@naisys/hub 3.0.0-beta.35 → 3.0.0-beta.36

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
@@ -4,48 +4,56 @@
4
4
 
5
5
  The hub is the central server and source of truth for a NAISYS cluster. Runners and supervisors connect over WebSocket + REST; the hub owns persistence (mail, context logs, cost, variables) so runners are ephemeral and can be restarted or moved between machines without losing state.
6
6
 
7
- Run standalone with `npx naisys_hub`, or in-process with `npx naisys --integrated-hub`.
7
+ ## Running
8
+
9
+ Most installations run the hub in-process with the supervisor UI and ERP — see the [main README](../../README.md). To run the hub alone:
10
+
11
+ ```bash
12
+ npm install @naisys/hub
13
+ npx naisys-hub
14
+ ```
15
+
16
+ Hosts then connect with `npx naisys --hub=https://<server>/hub`. If the hub isn't already public, expose it with a reverse proxy or [ngrok](https://ngrok.com/).
17
+
18
+ > **Note:** Remote auto-update from the supervisor UI only works when the hub runs attached to a `naisys` runner (the integrated stack). Running `naisys-hub` solo skips the runner that performs the update.
19
+
20
+ ## Configuration
21
+
22
+ Standalone hub reads configuration from `.env`:
23
+
24
+ - `NAISYS_FOLDER` - persistent data folder for the hub database, logs, and access key
25
+ - `SERVER_PORT` - HTTP port; defaults to `3300`
8
26
 
9
27
  ## Features
10
28
 
11
29
  ### Core
12
30
 
13
- - WebSocket + REST server with persistence
14
- - `hub-protocol` shared-types package between hub and clients for compile-time safety
15
- - Heartbeat service tracks online runners/supervisors and agent status
16
- - Run-session tracking per run with keep-alive and authoritative online/offline state
31
+ - WebSocket + REST server with `hub-protocol` shared types between hub and clients
32
+ - Heartbeat service for online runners/supervisors and agent status
33
+ - Run-session tracking with keep-alive and authoritative online/offline state
17
34
  - Per-app host filter (naisys-host vs supervisor-host)
18
35
 
19
36
  ### Persistence ([doc 001](../../docs/001-database-design.md))
20
37
 
21
- The hub owns all shared data, so runners stay ephemeral:
22
-
23
- - Mail
24
- - Context log and attachments ([doc 011](../../docs/011-mail-attachments.md))
25
- - Cost tracking
26
- - Variables
38
+ The hub owns mail, context logs and [attachments](../../docs/011-mail-attachments.md), cost history, and variables, so runners stay ephemeral and replaceable.
27
39
 
28
- ### Multi-machine
40
+ ### Multi-machine ([doc 005](../../docs/005-multi-machine-redux.md))
29
41
 
30
- - Hub is the single source of truth ([doc 005](../../docs/005-multi-machine-redux.md)); runners are ephemeral
31
- - Duplicate host-connection prevention; a new connection supersedes a dead one
42
+ - Hub is the single source of truth; runners are ephemeral
43
+ - Duplicate host-connection prevention a new connection supersedes a dead one
32
44
 
33
45
  ### Security ([doc 010](../../docs/010-hub-security.md))
34
46
 
35
- - `Authorization: Bearer` header auth
36
- - Rotatable hub access key
37
- - Hardened spawning: no shell interpretation, timeouts on `execFileSync` to prevent hangs
38
- - Public attachment IDs; API key read from headers, not query params
39
- - Hub socket served at `/hub` path for reverse-proxy friendliness (TLS terminated at the proxy)
47
+ - `Authorization: Bearer` header auth with a rotatable access key
48
+ - Hardened spawning: no shell interpretation, timeouts on `execFileSync`
49
+ - API keys read from headers, not query params
50
+ - Hub socket served at `/hub` for reverse-proxy friendliness (TLS terminated at the proxy)
40
51
 
41
- ### Packaging and deployment
52
+ ### Deployment
42
53
 
43
- - Reverse-proxy-friendly path strategy `<app>/api/...`
44
- - Unified port strategy ([doc 009](../../docs/009-port-strategy.md))
45
- - npm-published bin entry points: `naisys`, `naisys_hub`, `naisys_supervisor`, `naisys_erp`
46
- - Ngrok support (skip-browser-warning header + setup guide)
47
- - PWA manifest, favicons, Apple/Android icons
48
- - Shrinkwrap lockfile to prevent third-party upgrades from breaking the app
54
+ - Reverse-proxy-friendly path strategy (`<app>/api/...`) and unified port strategy ([doc 009](../../docs/009-port-strategy.md))
55
+ - npm bin entry points: `naisys`, `naisys-hub`, `naisys-supervisor`, `naisys-erp`
56
+ - Ngrok-friendly (skip-browser-warning header)
49
57
 
50
58
  ## License
51
59
 
package/dist/naisysHub.js CHANGED
@@ -104,6 +104,28 @@ export const startHub = async (startupType, startSupervisor, plugins, startupAge
104
104
  if (startupType === "hosted") {
105
105
  logService.disableConsole();
106
106
  }
107
+ // Hosted mode: parent process owns signal handling
108
+ if (startupType === "standalone") {
109
+ let shuttingDown = false;
110
+ const handleShutdown = async (signal) => {
111
+ if (shuttingDown) {
112
+ console.log("[Hub] Force exit");
113
+ process.exit(1);
114
+ }
115
+ shuttingDown = true;
116
+ logService.log(`[Hub] Shutting down (${signal})...`);
117
+ try {
118
+ await io.close();
119
+ await fastify.close();
120
+ }
121
+ catch (err) {
122
+ console.error("[Hub] Error during shutdown:", err);
123
+ }
124
+ process.exit(0);
125
+ };
126
+ process.on("SIGTERM", () => void handleShutdown("SIGTERM"));
127
+ process.on("SIGINT", () => void handleShutdown("SIGINT"));
128
+ }
107
129
  return { serverPort };
108
130
  }
109
131
  catch (err) {
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@naisys/hub",
3
- "version": "3.0.0-beta.35",
3
+ "version": "3.0.0-beta.36",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@naisys/hub",
9
- "version": "3.0.0-beta.35",
9
+ "version": "3.0.0-beta.36",
10
10
  "dependencies": {
11
- "@naisys/common": "3.0.0-beta.35",
12
- "@naisys/common-node": "3.0.0-beta.35",
13
- "@naisys/hub-database": "3.0.0-beta.35",
14
- "@naisys/hub-protocol": "3.0.0-beta.35",
11
+ "@naisys/common": "3.0.0-beta.36",
12
+ "@naisys/common-node": "3.0.0-beta.36",
13
+ "@naisys/hub-database": "3.0.0-beta.36",
14
+ "@naisys/hub-protocol": "3.0.0-beta.36",
15
15
  "commander": "^14.0.3",
16
16
  "dotenv": "^17.3.1",
17
17
  "fastify": "^5.8.2",
@@ -24,7 +24,7 @@
24
24
  "node": ">=22.0.0"
25
25
  },
26
26
  "peerDependencies": {
27
- "@naisys/supervisor": "3.0.0-beta.35"
27
+ "@naisys/supervisor": "3.0.0-beta.36"
28
28
  },
29
29
  "peerDependenciesMeta": {
30
30
  "@naisys/supervisor": {
@@ -189,32 +189,32 @@
189
189
  "license": "MIT"
190
190
  },
191
191
  "node_modules/@naisys/common": {
192
- "version": "3.0.0-beta.35",
193
- "resolved": "https://registry.npmjs.org/@naisys/common/-/common-3.0.0-beta.35.tgz",
194
- "integrity": "sha512-8SvMZ/D8Ll+ZbnlhovI22Z3sTOhb3im3NLJda9VkBFDJQdfDqacV72YnHmNaG/39VthEzTSn0yrSirJ0O6cgHA==",
192
+ "version": "3.0.0-beta.36",
193
+ "resolved": "https://registry.npmjs.org/@naisys/common/-/common-3.0.0-beta.36.tgz",
194
+ "integrity": "sha512-a5EYqKvnL1Uy1pdslLZVMQERbo3ZtnMvhKa5B4GQJ/ziwM5zgMfbUFUEDniJRnta4dtIU5GxgzxBxmin+gMbhw==",
195
195
  "dependencies": {
196
196
  "semver": "^7.7.4",
197
197
  "zod": "^4.3.6"
198
198
  }
199
199
  },
200
200
  "node_modules/@naisys/common-node": {
201
- "version": "3.0.0-beta.35",
202
- "resolved": "https://registry.npmjs.org/@naisys/common-node/-/common-node-3.0.0-beta.35.tgz",
203
- "integrity": "sha512-IpGH9HepjRATQ0AdQby5sd98keBH3TKcXRhRZpUH13j/vRLlbhZOZgzkqQz/55jrRbbSI84EVGZPxly1dUn/XQ==",
201
+ "version": "3.0.0-beta.36",
202
+ "resolved": "https://registry.npmjs.org/@naisys/common-node/-/common-node-3.0.0-beta.36.tgz",
203
+ "integrity": "sha512-pgzHJuh6OH6wiNU4PRV8sSNaBqWCYateD7+tWHnwvDwVOzwce8ttLNtsK+NQzwQqp+vjPAMpfJ9yMqoOttXgbA==",
204
204
  "dependencies": {
205
- "@naisys/common": "3.0.0-beta.35",
205
+ "@naisys/common": "3.0.0-beta.36",
206
206
  "better-sqlite3": "^12.6.2",
207
207
  "js-yaml": "^4.1.1",
208
208
  "pino": "^10.3.1"
209
209
  }
210
210
  },
211
211
  "node_modules/@naisys/hub-database": {
212
- "version": "3.0.0-beta.35",
213
- "resolved": "https://registry.npmjs.org/@naisys/hub-database/-/hub-database-3.0.0-beta.35.tgz",
214
- "integrity": "sha512-AE1wNMm/kMG/FL8VM8OWJiklA08DHi4iFf6HmZIshvK+br/Llt5h8yh3rSAn5gpYuGcstDjmDKsYm+v79QqtUw==",
212
+ "version": "3.0.0-beta.36",
213
+ "resolved": "https://registry.npmjs.org/@naisys/hub-database/-/hub-database-3.0.0-beta.36.tgz",
214
+ "integrity": "sha512-FiJJCaOARun5jbTwX2VwXgEy5xDqlMi7X1ZSpxSn0jMv3dzniupCYYAYyO4muwXdFLNO2vMnhUdmhK/m2k7ouw==",
215
215
  "dependencies": {
216
- "@naisys/common": "3.0.0-beta.35",
217
- "@naisys/common-node": "3.0.0-beta.35",
216
+ "@naisys/common": "3.0.0-beta.36",
217
+ "@naisys/common-node": "3.0.0-beta.36",
218
218
  "@prisma/adapter-better-sqlite3": "^7.5.0",
219
219
  "@prisma/client": "^7.5.0",
220
220
  "better-sqlite3": "^12.6.2",
@@ -222,11 +222,11 @@
222
222
  }
223
223
  },
224
224
  "node_modules/@naisys/hub-protocol": {
225
- "version": "3.0.0-beta.35",
226
- "resolved": "https://registry.npmjs.org/@naisys/hub-protocol/-/hub-protocol-3.0.0-beta.35.tgz",
227
- "integrity": "sha512-cX03B8AsRB6Ln/Lm1z0iLiMRO0IKyrxmkpB0915lZ8mctACfgkSBLxYttxOKwV8Gwn7Jj5molPIYSVN6Wntc2Q==",
225
+ "version": "3.0.0-beta.36",
226
+ "resolved": "https://registry.npmjs.org/@naisys/hub-protocol/-/hub-protocol-3.0.0-beta.36.tgz",
227
+ "integrity": "sha512-JCxS982SjYUws3vg3O5XgoeoC0Pllhm7qLdqXTJpZY9v+SA5VGvu5/xvOURspNuIbpRayQkUx7cakTmQUQFKrw==",
228
228
  "dependencies": {
229
- "@naisys/common": "3.0.0-beta.35",
229
+ "@naisys/common": "3.0.0-beta.36",
230
230
  "zod": "^4.3.6"
231
231
  }
232
232
  },
@@ -640,9 +640,9 @@
640
640
  }
641
641
  },
642
642
  "node_modules/ajv": {
643
- "version": "8.18.0",
644
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
645
- "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
643
+ "version": "8.20.0",
644
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
645
+ "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
646
646
  "license": "MIT",
647
647
  "dependencies": {
648
648
  "fast-deep-equal": "^3.1.3",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naisys/hub",
3
- "version": "3.0.0-beta.35",
3
+ "version": "3.0.0-beta.36",
4
4
  "description": "NAISYS Hub - Adds persistence and multi-instance coordination to NAISYS",
5
5
  "type": "module",
6
6
  "main": "dist/naisysHub.js",
@@ -31,7 +31,7 @@
31
31
  "!dist/**/*.d.ts.map"
32
32
  ],
33
33
  "peerDependencies": {
34
- "@naisys/supervisor": "3.0.0-beta.35"
34
+ "@naisys/supervisor": "3.0.0-beta.36"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "@naisys/supervisor": {
@@ -39,10 +39,10 @@
39
39
  }
40
40
  },
41
41
  "dependencies": {
42
- "@naisys/common": "3.0.0-beta.35",
43
- "@naisys/common-node": "3.0.0-beta.35",
44
- "@naisys/hub-database": "3.0.0-beta.35",
45
- "@naisys/hub-protocol": "3.0.0-beta.35",
42
+ "@naisys/common": "3.0.0-beta.36",
43
+ "@naisys/common-node": "3.0.0-beta.36",
44
+ "@naisys/hub-database": "3.0.0-beta.36",
45
+ "@naisys/hub-protocol": "3.0.0-beta.36",
46
46
  "commander": "^14.0.3",
47
47
  "dotenv": "^17.3.1",
48
48
  "fastify": "^5.8.2",