my-durable 0.0.2 → 0.0.3

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
@@ -8,6 +8,22 @@
8
8
 
9
9
  📺 Watch this video to get the full breakdown of this codebase: **[Pi Durable PROACTIVE Agents](https://youtu.be/DNDYYHsypZg)**
10
10
 
11
+ ## Quick start (`md`)
12
+
13
+ ```sh
14
+ npm install -g my-durable
15
+
16
+ md hub # web UI + device tunnel server → http://127.0.0.1:4781
17
+ md device # device daemon (pairs to a hub, serves this machine)
18
+ md tui # terminal admin client
19
+ md --help # commands, flags and environment variables
20
+ ```
21
+
22
+ `md hub` is the only component that other machines talk to, so it is also the one
23
+ to put behind a TLS proxy or tunnel (it refuses anything that did not arrive over
24
+ HTTPS). Pair a device by opening the hub, pressing **Pair a device**, and entering
25
+ the code — or open the pairing link directly on the machine being added.
26
+
11
27
  <p align="center">
12
28
  <img src="images/01_durable_agent_network.svg" alt="Three clients (web UI, dpi-tui, curl) reach durable agents on four devices; the clients disconnect and every device keeps checkpointing its run to SQLite" width="850">
13
29
  </p>
package/bin/md.mjs ADDED
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+ // `md` — one command for the Durable Pi stack.
3
+ // md hub [--port N] [--host H] [--public-host H] web UI + device tunnel server
4
+ // md device device-side daemon
5
+ // md tui terminal admin client
6
+ // Every subcommand runs the TypeScript entry through tsx, so no build step is needed.
7
+ import { access } from "node:fs/promises";
8
+ import { fileURLToPath } from "node:url";
9
+
10
+ /** Subcommand → TypeScript entry, relative to this file. */
11
+ const COMMANDS = {
12
+ hub: "../apps/dpi-playground/apps/dpi-playground-hub/src/main.ts",
13
+ device: "../apps/dpi-backend/src/main.ts",
14
+ tui: "../apps/dpi-tui/src/main.ts",
15
+ };
16
+
17
+ const HELP = `md — Durable Pi
18
+
19
+ Usage:
20
+ md hub [--port 4781] [--host 127.0.0.1] [--public-host <host>]
21
+ Web UI + device tunnel server (devices dial this).
22
+ md device
23
+ Device-side daemon (pairs to a hub, serves one machine's agents).
24
+ md tui
25
+ Terminal admin client.
26
+ md help | md --help | md -h
27
+ md version | md --version | md -v
28
+
29
+ Environment (hub): DPI_HOME, DPI_HUB_PORT, DPI_HUB_HOST, DPI_HUB_PUBLIC_HOST,
30
+ DPI_HUB_ORIGIN, DPI_HUB_REQUIRE_TLS
31
+ Environment (device): DPI_HUB_URL, DPI_HOME
32
+ `;
33
+
34
+ /**
35
+ * tsx is a dependency of the published package, but a bare repository checkout has it only
36
+ * inside the per-app node_modules. Try the normal resolution first, then the known local
37
+ * copies, so `md` works in both places without a root install.
38
+ */
39
+ async function loadTsx() {
40
+ try {
41
+ return await import("tsx/esm/api");
42
+ } catch (error) {
43
+ if (error?.code !== "ERR_MODULE_NOT_FOUND") throw error;
44
+ }
45
+ const candidates = [
46
+ "../apps/dpi-playground/node_modules/tsx/dist/esm/api/index.mjs",
47
+ "../apps/dpi-backend/node_modules/tsx/dist/esm/api/index.mjs",
48
+ "../apps/dpi-sdk/node_modules/tsx/dist/esm/api/index.mjs",
49
+ "../apps/dpi-tui/node_modules/tsx/dist/esm/api/index.mjs",
50
+ ];
51
+ for (const relative of candidates) {
52
+ const url = new URL(relative, import.meta.url);
53
+ try {
54
+ await access(fileURLToPath(url));
55
+ return await import(url.href);
56
+ } catch {
57
+ // try the next one
58
+ }
59
+ }
60
+ throw new Error(
61
+ "md: cannot find tsx. Install the package (npm install -g my-durable) or run npm install in an app directory.",
62
+ );
63
+ }
64
+
65
+ const [first, ...rest] = process.argv.slice(2);
66
+
67
+ if (!first || first === "help" || first === "--help" || first === "-h") {
68
+ process.stdout.write(HELP);
69
+ process.exit(0);
70
+ }
71
+
72
+ if (first === "version" || first === "--version" || first === "-v") {
73
+ const { readFileSync } = await import("node:fs");
74
+ const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
75
+ process.stdout.write(`md (my-durable) ${pkg.version}\n`);
76
+ process.exit(0);
77
+ }
78
+
79
+ if (!Object.hasOwn(COMMANDS, first)) {
80
+ process.stderr.write(`md: unknown command '${first}'\n\n${HELP}`);
81
+ process.exit(2);
82
+ }
83
+
84
+ // The entries parse process.argv.slice(2) themselves: hand them their own args.
85
+ process.argv = [process.argv[0], process.argv[1], ...rest];
86
+ const { register } = await loadTsx();
87
+ register();
88
+ await import(COMMANDS[first]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "my-durable",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Durable Pi — the durable agent network: hub web UI, device backend daemon, TUI admin and the shared SDK, packaged as one runnable monorepo install",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -15,9 +15,7 @@
15
15
  "node": ">=22.0.0"
16
16
  },
17
17
  "bin": {
18
- "my-durable-hub": "bin/hub.mjs",
19
- "my-durable-device": "bin/device.mjs",
20
- "my-durable-tui": "bin/tui.mjs"
18
+ "md": "bin/md.mjs"
21
19
  },
22
20
  "scripts": {
23
21
  "hub": "tsx apps/dpi-playground/apps/dpi-playground-hub/src/main.ts",
package/bin/device.mjs DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
- // Run the device daemon TypeScript entry through tsx so `my-durable-device` works without a build step.
3
- import { register } from "tsx/esm/api";
4
- register();
5
- await import("../apps/dpi-backend/src/main.ts");
package/bin/hub.mjs DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
- // Run the hub TypeScript entry through tsx so `my-durable-hub` works without a build step.
3
- import { register } from "tsx/esm/api";
4
- register();
5
- await import("../apps/dpi-playground/apps/dpi-playground-hub/src/main.ts");
package/bin/tui.mjs DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
- // Run the TUI TypeScript entry through tsx so `my-durable-tui` works without a build step.
3
- import { register } from "tsx/esm/api";
4
- register();
5
- await import("../apps/dpi-tui/src/main.ts");