runbot-next 0.1.0 → 0.1.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/README.md CHANGED
@@ -1,45 +1,67 @@
1
1
  # runbot-next
2
2
 
3
- Bun CLI and reusable function definitions for reading public Odoo Runbot pages.
3
+ Fast local console for public Odoo Runbot pages.
4
4
 
5
- The core functions live in `src/runbot/tools.ts`. Each tool has:
5
+ Runbot Next gives you a focused UI for branches, batches, builds, logs, and test failures without asking the browser to scrape Runbot directly. The local server fetches Runbot HTML, parses it, and serves the app plus API from one port.
6
6
 
7
- - `name`
8
- - `summary`
9
- - `description`
10
- - Zod `inputSchema`
11
- - async `handler`
7
+ ![Runbot Next app screenshot](docs/assets/runbot-next-app.png)
12
8
 
13
- That single definition list is used by the CLI and can also be adapted for MCP or oRPC via `src/adapters`.
9
+ ## Run
14
10
 
15
- ## Usage
11
+ ```sh
12
+ npx runbot-next
13
+ ```
16
14
 
17
- Run the web app locally from the published package:
15
+ or:
18
16
 
19
17
  ```sh
20
- npx runbot-next
21
18
  bunx runbot-next
22
19
  ```
23
20
 
24
- Use `PORT` to choose a port:
21
+ The server starts on `http://127.0.0.1:3000`. If the port is busy, it tries the next available port, up to 100 ports.
22
+
23
+ Use `PORT` to choose the starting port:
25
24
 
26
25
  ```sh
27
26
  PORT=5173 npx runbot-next
28
- PORT=5173 bunx runbot-next
29
27
  ```
30
28
 
31
- Develop or use the CLI from the repo:
29
+ ## Features
30
+
31
+ - Browse Runbot projects, branches, and batches.
32
+ - Open build slots, commits, logs, and run links quickly.
33
+ - Parse visible test failures from Runbot logs.
34
+ - Record proxied Runbot traffic while debugging.
35
+ - Runs locally through `npx` or `bunx`.
36
+
37
+ ## Develop
32
38
 
33
39
  ```sh
34
40
  bun install
41
+ bun run dev
42
+ PORT=3001 bun run serve
43
+ ```
44
+
45
+ For production-package checks:
46
+
47
+ ```sh
48
+ bun run build
49
+ bun run build:server
50
+ npm pack --dry-run
51
+ ```
52
+
53
+ ## CLI
54
+
55
+ The reusable tool definitions live in `src/runbot/tools.ts`.
56
+
57
+ ```sh
35
58
  bun run src/cli.ts projects
36
59
  bun run src/cli.ts batches /runbot/rd-1 --search master
37
60
  bun run src/cli.ts batch 2526059 --json
38
61
  bun run src/cli.ts build 110606813
39
62
  bun run src/cli.ts tests --batch 2413720 --slot "Enterprise Tests" --unparsed
40
- bun run src/cli.ts link 110606813 log run
41
63
  ```
42
64
 
43
- ## Notes
65
+ ## Note
44
66
 
45
- Runbot's public pages are server-rendered HTML. The tool parses public links and text from those pages instead of relying on a JSON API.
67
+ Runbot public pages are server-rendered HTML. This app intentionally uses a local server because Runbot does not expose permissive browser CORS headers for direct client-side scraping.
@@ -5136,7 +5136,8 @@ class TrafficRecorder {
5136
5136
  }
5137
5137
 
5138
5138
  // src/server-node.ts
5139
- var port = Number(process.env.PORT ?? 3000);
5139
+ var initialPort = Number(process.env.PORT ?? 3000);
5140
+ var maxPortAttempts = 100;
5140
5141
  var host = process.env.HOST ?? "127.0.0.1";
5141
5142
  var procedures = toOrpcProcedures();
5142
5143
  var traffic = new TrafficRecorder;
@@ -5188,10 +5189,10 @@ function sendStatic(response, pathname) {
5188
5189
  });
5189
5190
  createReadStream(resolved).pipe(response);
5190
5191
  }
5191
- createServer(async (request, response) => {
5192
+ async function handleRequest(request, response) {
5192
5193
  if (request.method === "OPTIONS")
5193
5194
  return sendJson(response, {});
5194
- const url = new URL(request.url ?? "/", `http://${request.headers.host ?? `${host}:${port}`}`);
5195
+ const url = new URL(request.url ?? "/", `http://${request.headers.host ?? `${host}:${initialPort}`}`);
5195
5196
  if (url.pathname === "/orpc/tools") {
5196
5197
  return sendJson(response, Object.keys(procedures).map((name) => ({ name })));
5197
5198
  }
@@ -5218,6 +5219,23 @@ createServer(async (request, response) => {
5218
5219
  }
5219
5220
  }
5220
5221
  return sendStatic(response, url.pathname);
5221
- }).listen(port, host, () => {
5222
- console.log(`Runbot Next listening on http://${host}:${port}`);
5223
- });
5222
+ }
5223
+ function listen(port, attemptsLeft = maxPortAttempts) {
5224
+ const server = createServer(handleRequest);
5225
+ server.once("error", (error) => {
5226
+ if (error.code === "EADDRINUSE" && attemptsLeft > 0) {
5227
+ server.close();
5228
+ listen(port + 1, attemptsLeft - 1);
5229
+ return;
5230
+ }
5231
+ if (error.code === "EADDRINUSE") {
5232
+ console.error(`No available port found from ${initialPort} to ${initialPort + maxPortAttempts}.`);
5233
+ process.exit(1);
5234
+ }
5235
+ throw error;
5236
+ });
5237
+ server.listen(port, host, () => {
5238
+ console.log(`Runbot Next listening on http://${host}:${port}`);
5239
+ });
5240
+ }
5241
+ listen(initialPort);
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runbot-next",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "bin": {
@@ -9,7 +9,8 @@
9
9
  "files": [
10
10
  "dist",
11
11
  "dist-server",
12
- "README.md"
12
+ "README.md",
13
+ "docs/assets/runbot-next-app.png"
13
14
  ],
14
15
  "scripts": {
15
16
  "dev": "vite --host 127.0.0.1",