@suveren/gateway 0.3.17 → 0.4.0
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/bin/suveren-gateway.js +419 -28
- package/content/integrations/calendar.json +20 -8
- package/content/integrations/crm.json +97 -23
- package/content/integrations/gmail.json +166 -29
- package/content/integrations/linkedin.json +15 -3
- package/content/integrations/mollie.json +2 -2
- package/dist/control-plane/index.mjs +333 -41
- package/dist/mcp-server/http.mjs +880 -210
- package/dist/ui/assets/index-BDQY7Z3H.js +105 -0
- package/dist/ui/assets/{index-DOt3SNnl.css → index-JHaCddDE.css} +1 -1
- package/dist/ui/index.html +2 -2
- package/node_modules/@hap/core/dist/index.d.mts +27 -0
- package/node_modules/@hap/core/dist/index.d.ts +27 -0
- package/node_modules/@hap/core/dist/index.js +13 -1
- package/node_modules/@hap/core/dist/index.mjs +13 -1
- package/node_modules/@hap/core/package.json +1 -1
- package/node_modules/@hap/core/src/gatekeeper.ts +47 -1
- package/node_modules/@hap/core/src/types.ts +27 -0
- package/node_modules/@hono/node-server/README.md +58 -25
- package/node_modules/@hono/node-server/dist/conninfo.cjs +22 -0
- package/node_modules/@hono/node-server/dist/{conninfo.d.ts → conninfo.d.cts} +4 -3
- package/node_modules/@hono/node-server/dist/conninfo.d.mts +4 -3
- package/node_modules/@hono/node-server/dist/conninfo.mjs +19 -16
- package/node_modules/@hono/node-server/dist/constants-BLSFu_RU.mjs +5 -0
- package/node_modules/@hono/node-server/dist/constants-BXAKTxRC.cjs +11 -0
- package/node_modules/@hono/node-server/dist/index.cjs +1173 -0
- package/node_modules/@hono/node-server/dist/index.d.cts +101 -0
- package/node_modules/@hono/node-server/dist/index.d.mts +101 -8
- package/node_modules/@hono/node-server/dist/index.mjs +1143 -637
- package/node_modules/@hono/node-server/dist/serve-static.cjs +151 -0
- package/node_modules/@hono/node-server/dist/serve-static.d.cts +18 -0
- package/node_modules/@hono/node-server/dist/serve-static.d.mts +14 -13
- package/node_modules/@hono/node-server/dist/serve-static.mjs +143 -145
- package/node_modules/@hono/node-server/dist/utils/response.cjs +8 -0
- package/node_modules/@hono/node-server/dist/utils/response.d.cts +4 -0
- package/node_modules/@hono/node-server/dist/utils/response.d.mts +3 -2
- package/node_modules/@hono/node-server/dist/utils/response.mjs +6 -9
- package/node_modules/@hono/node-server/dist/utils/stream.cjs +65 -0
- package/node_modules/@hono/node-server/dist/utils/stream.d.cts +6 -0
- package/node_modules/@hono/node-server/dist/utils/stream.d.mts +6 -0
- package/node_modules/@hono/node-server/dist/utils/stream.mjs +64 -0
- package/node_modules/@hono/node-server/package.json +65 -54
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/index.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/index.js +1 -12
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/index.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/stdio.d.ts +7 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/stdio.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/stdio.js +9 -3
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/stdio.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.js +5 -3
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/index.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/index.js +1 -12
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/index.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/sseKeepAlive.d.ts +5 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/sseKeepAlive.d.ts.map +1 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/sseKeepAlive.js +17 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/sseKeepAlive.js.map +1 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/stdio.d.ts +9 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/stdio.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/stdio.js +10 -4
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/stdio.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/webStandardStreamableHttp.d.ts +21 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/webStandardStreamableHttp.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/webStandardStreamableHttp.js +239 -41
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/webStandardStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/zod-compat.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/zod-compat.js +25 -6
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/zod-compat.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/mediaType.d.ts +32 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/mediaType.d.ts.map +1 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/mediaType.js +64 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/mediaType.js.map +1 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/stdio.d.ts +5 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/stdio.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/stdio.js +10 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/stdio.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.js +2 -13
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.d.ts +7 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.js +9 -3
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js +5 -3
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js +2 -13
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.d.ts +5 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.d.ts.map +1 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.js +13 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.js.map +1 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.d.ts +9 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js +10 -4
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.d.ts +21 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.js +239 -41
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js +25 -6
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.d.ts +32 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.d.ts.map +1 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.js +57 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.js.map +1 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.d.ts +5 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js +9 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/media-typer/README.md +15 -14
- package/node_modules/@modelcontextprotocol/sdk/node_modules/media-typer/index.js +0 -8
- package/node_modules/@modelcontextprotocol/sdk/node_modules/media-typer/package.json +16 -12
- package/node_modules/@modelcontextprotocol/sdk/package.json +4 -3
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/crypto.d.ts +1 -1
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/body-parser/HISTORY.md +7 -1
- package/node_modules/body-parser/lib/types/json.js +7 -3
- package/node_modules/body-parser/lib/types/raw.js +7 -3
- package/node_modules/body-parser/lib/types/text.js +7 -3
- package/node_modules/body-parser/lib/types/urlencoded.js +7 -3
- package/node_modules/body-parser/package.json +1 -1
- package/node_modules/express-rate-limit/dist/index.cjs +69 -5
- package/node_modules/express-rate-limit/dist/index.d.cts +16 -0
- package/node_modules/express-rate-limit/dist/index.d.mts +16 -0
- package/node_modules/express-rate-limit/dist/index.d.ts +16 -0
- package/node_modules/express-rate-limit/dist/index.mjs +55 -5
- package/node_modules/express-rate-limit/node_modules/debug/LICENSE +20 -0
- package/node_modules/express-rate-limit/node_modules/debug/README.md +481 -0
- package/node_modules/express-rate-limit/node_modules/debug/package.json +64 -0
- package/node_modules/express-rate-limit/node_modules/debug/src/browser.js +272 -0
- package/node_modules/express-rate-limit/node_modules/debug/src/common.js +292 -0
- package/node_modules/express-rate-limit/node_modules/debug/src/index.js +10 -0
- package/node_modules/express-rate-limit/node_modules/debug/src/node.js +263 -0
- package/node_modules/express-rate-limit/node_modules/ms/index.js +162 -0
- package/node_modules/express-rate-limit/node_modules/ms/license.md +21 -0
- package/node_modules/express-rate-limit/node_modules/ms/package.json +38 -0
- package/node_modules/express-rate-limit/node_modules/ms/readme.md +59 -0
- package/node_modules/express-rate-limit/package.json +12 -9
- package/node_modules/fast-uri/index.js +17 -0
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/security.test.js +62 -0
- package/node_modules/hono/dist/adapter/aws-lambda/handler.js +1 -4
- package/node_modules/hono/dist/adapter/lambda-edge/handler.js +12 -2
- package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +1 -4
- package/node_modules/hono/dist/cjs/adapter/lambda-edge/handler.js +12 -2
- package/node_modules/hono/dist/cjs/client/client.js +10 -1
- package/node_modules/hono/dist/cjs/client/utils.js +1 -1
- package/node_modules/hono/dist/cjs/helper/streaming/sse.js +5 -4
- package/node_modules/hono/dist/cjs/middleware/cache/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/compress/index.js +2 -1
- package/node_modules/hono/dist/cjs/middleware/etag/index.js +2 -1
- package/node_modules/hono/dist/cjs/middleware/method-override/index.js +5 -3
- package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +10 -4
- package/node_modules/hono/dist/cjs/request.js +8 -3
- package/node_modules/hono/dist/cjs/router/trie-router/node.js +9 -0
- package/node_modules/hono/dist/cjs/utils/accept.js +1 -1
- package/node_modules/hono/dist/cjs/utils/body.js +6 -0
- package/node_modules/hono/dist/cjs/utils/url.js +1 -1
- package/node_modules/hono/dist/client/client.js +10 -1
- package/node_modules/hono/dist/client/utils.js +1 -1
- package/node_modules/hono/dist/helper/streaming/sse.js +5 -4
- package/node_modules/hono/dist/middleware/cache/index.js +1 -1
- package/node_modules/hono/dist/middleware/compress/index.js +2 -1
- package/node_modules/hono/dist/middleware/etag/index.js +2 -1
- package/node_modules/hono/dist/middleware/method-override/index.js +5 -3
- package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +10 -4
- package/node_modules/hono/dist/request.js +8 -3
- package/node_modules/hono/dist/router/trie-router/node.js +9 -0
- package/node_modules/hono/dist/types/adapter/aws-lambda/types.d.ts +9 -0
- package/node_modules/hono/dist/types/adapter/lambda-edge/handler.d.ts +1 -1
- package/node_modules/hono/dist/types/helper/websocket/index.d.ts +1 -1
- package/node_modules/hono/dist/types/middleware/combine/index.d.ts +1 -1
- package/node_modules/hono/dist/types/middleware/language/language.d.ts +18 -0
- package/node_modules/hono/dist/types/utils/types.d.ts +1 -1
- package/node_modules/hono/dist/utils/accept.js +1 -1
- package/node_modules/hono/dist/utils/body.js +6 -0
- package/node_modules/hono/dist/utils/url.js +1 -1
- package/node_modules/hono/package.json +4 -4
- package/node_modules/ip-address/README.md +102 -96
- package/node_modules/ip-address/dist/common.d.ts +23 -0
- package/node_modules/ip-address/dist/common.js +27 -4
- package/node_modules/ip-address/dist/common.js.map +1 -1
- package/node_modules/ip-address/dist/ipv4.d.ts +8 -1
- package/node_modules/ip-address/dist/ipv4.js +21 -8
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/dist/ipv6.d.ts +59 -1
- package/node_modules/ip-address/dist/ipv6.js +149 -41
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/dist/v4/constants.js +5 -1
- package/node_modules/ip-address/dist/v4/constants.js.map +1 -1
- package/node_modules/ip-address/dist/v6/constants.js +3 -2
- package/node_modules/ip-address/dist/v6/constants.js.map +1 -1
- package/node_modules/ip-address/package.json +2 -2
- package/node_modules/jose/README.md +1 -4
- package/node_modules/jose/dist/types/jwks/remote.d.ts +3 -3
- package/node_modules/jose/dist/webapi/jwks/remote.js +1 -1
- package/node_modules/jose/dist/webapi/lib/key_to_jwk.js +4 -1
- package/node_modules/jose/package.json +1 -1
- package/package.json +2 -2
- package/profiles/customers/0.4.profile.json +7 -4
- package/profiles/customers/0.5.profile.json +131 -0
- package/profiles/customers/0.6.profile.json +153 -0
- package/profiles/email/0.4.profile.json +8 -4
- package/profiles/index.json +2 -0
- package/server.js +10 -0
- package/dist/ui/assets/index-CTmWS7W4.js +0 -105
- package/node_modules/@hono/node-server/dist/conninfo.js +0 -42
- package/node_modules/@hono/node-server/dist/globals.d.mts +0 -2
- package/node_modules/@hono/node-server/dist/globals.d.ts +0 -2
- package/node_modules/@hono/node-server/dist/globals.js +0 -29
- package/node_modules/@hono/node-server/dist/globals.mjs +0 -5
- package/node_modules/@hono/node-server/dist/index.d.ts +0 -8
- package/node_modules/@hono/node-server/dist/index.js +0 -702
- package/node_modules/@hono/node-server/dist/listener.d.mts +0 -13
- package/node_modules/@hono/node-server/dist/listener.d.ts +0 -13
- package/node_modules/@hono/node-server/dist/listener.js +0 -670
- package/node_modules/@hono/node-server/dist/listener.mjs +0 -635
- package/node_modules/@hono/node-server/dist/request.d.mts +0 -25
- package/node_modules/@hono/node-server/dist/request.d.ts +0 -25
- package/node_modules/@hono/node-server/dist/request.js +0 -238
- package/node_modules/@hono/node-server/dist/request.mjs +0 -206
- package/node_modules/@hono/node-server/dist/response.d.mts +0 -26
- package/node_modules/@hono/node-server/dist/response.d.ts +0 -26
- package/node_modules/@hono/node-server/dist/response.js +0 -112
- package/node_modules/@hono/node-server/dist/response.mjs +0 -85
- package/node_modules/@hono/node-server/dist/serve-static.d.ts +0 -17
- package/node_modules/@hono/node-server/dist/serve-static.js +0 -177
- package/node_modules/@hono/node-server/dist/server.d.mts +0 -10
- package/node_modules/@hono/node-server/dist/server.d.ts +0 -10
- package/node_modules/@hono/node-server/dist/server.js +0 -696
- package/node_modules/@hono/node-server/dist/server.mjs +0 -660
- package/node_modules/@hono/node-server/dist/types.d.mts +0 -44
- package/node_modules/@hono/node-server/dist/types.d.ts +0 -44
- package/node_modules/@hono/node-server/dist/types.js +0 -18
- package/node_modules/@hono/node-server/dist/types.mjs +0 -0
- package/node_modules/@hono/node-server/dist/utils/response/constants.d.mts +0 -3
- package/node_modules/@hono/node-server/dist/utils/response/constants.d.ts +0 -3
- package/node_modules/@hono/node-server/dist/utils/response/constants.js +0 -30
- package/node_modules/@hono/node-server/dist/utils/response/constants.mjs +0 -5
- package/node_modules/@hono/node-server/dist/utils/response.d.ts +0 -3
- package/node_modules/@hono/node-server/dist/utils/response.js +0 -37
- package/node_modules/@hono/node-server/dist/utils.d.mts +0 -9
- package/node_modules/@hono/node-server/dist/utils.d.ts +0 -9
- package/node_modules/@hono/node-server/dist/utils.js +0 -99
- package/node_modules/@hono/node-server/dist/utils.mjs +0 -71
- package/node_modules/@hono/node-server/dist/vercel.d.mts +0 -7
- package/node_modules/@hono/node-server/dist/vercel.d.ts +0 -7
- package/node_modules/@hono/node-server/dist/vercel.js +0 -677
- package/node_modules/@hono/node-server/dist/vercel.mjs +0 -640
package/bin/suveren-gateway.js
CHANGED
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
* which Node implements consistently across platforms.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { spawn } from 'node:child_process';
|
|
13
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
14
14
|
import { existsSync, mkdirSync, openSync, readFileSync, writeFileSync, unlinkSync, statSync } from 'node:fs';
|
|
15
15
|
import { homedir, platform } from 'node:os';
|
|
16
16
|
import { dirname, join, resolve } from 'node:path';
|
|
17
17
|
import { fileURLToPath } from 'node:url';
|
|
18
|
+
import { buildLaunchAgentPlist, buildMacLauncher, buildSystemdUnit, buildWindowsTaskXml } from '../lib/autostart-templates.mjs';
|
|
18
19
|
|
|
19
20
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
21
|
const PKG_ROOT = resolve(__dirname, '..');
|
|
@@ -39,24 +40,15 @@ try {
|
|
|
39
40
|
|
|
40
41
|
// ─── Subcommands ────────────────────────────────────────────────────────
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
case 'help':
|
|
52
|
-
case '--help':
|
|
53
|
-
case '-h':
|
|
54
|
-
printHelp(); break;
|
|
55
|
-
default:
|
|
56
|
-
console.error(`Unknown command: ${cmd}\n`);
|
|
57
|
-
printHelp();
|
|
58
|
-
process.exit(2);
|
|
59
|
-
}
|
|
43
|
+
/**
|
|
44
|
+
* Dispatch runs at the BOTTOM of this file, not here.
|
|
45
|
+
*
|
|
46
|
+
* Top-level `const` declarations are not hoisted, so dispatching from this
|
|
47
|
+
* point ran every subcommand before the constants below it were initialised.
|
|
48
|
+
* `service` referenced one and threw "Cannot access 'LAUNCH_AGENT_LABEL'
|
|
49
|
+
* before initialization" on every invocation — the feature had never worked on
|
|
50
|
+
* any platform, and nothing tested it. See main() at the end of the file.
|
|
51
|
+
*/
|
|
60
52
|
|
|
61
53
|
// ─── Implementations ────────────────────────────────────────────────────
|
|
62
54
|
|
|
@@ -115,15 +107,37 @@ async function stop() {
|
|
|
115
107
|
process.exit(0);
|
|
116
108
|
}
|
|
117
109
|
try {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
110
|
+
if (platform() === 'win32') {
|
|
111
|
+
// Windows has no POSIX signals: process.kill(pid, 'SIGTERM') is mapped to
|
|
112
|
+
// TerminateProcess, so (a) server.js's shutdown handler never runs and
|
|
113
|
+
// (b) only the parent dies — the CP + MCP children, and every downstream
|
|
114
|
+
// MCP integration they spawned, are orphaned and keep holding the ports
|
|
115
|
+
// and the data dir. `taskkill /T` walks the whole tree; /F is required
|
|
116
|
+
// because a detached process has no console to receive a close event.
|
|
117
|
+
// Graceful shutdown is not reachable here, which is exactly why the tree
|
|
118
|
+
// kill is: nothing else will reap the children.
|
|
119
|
+
const res = spawnSync('taskkill', ['/PID', String(pid), '/T', '/F'], {
|
|
120
|
+
stdio: 'ignore',
|
|
121
|
+
windowsHide: true,
|
|
122
|
+
});
|
|
123
|
+
// taskkill exits 128 when the process is already gone — that is a
|
|
124
|
+
// successful stop, not a failure.
|
|
125
|
+
if (res.status !== 0 && isPidAlive(pid)) {
|
|
126
|
+
throw new Error(`taskkill exited ${res.status ?? res.error?.message}`);
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
process.kill(pid, 'SIGTERM');
|
|
130
|
+
// Give it up to 5s to exit cleanly. server.js's SIGTERM handler
|
|
131
|
+
// propagates to the CP + MCP children, which shut their integrations
|
|
132
|
+
// down — so on POSIX the tree unwinds itself.
|
|
133
|
+
for (let i = 0; i < 50; i++) {
|
|
134
|
+
await sleep(100);
|
|
135
|
+
if (!isPidAlive(pid)) break;
|
|
136
|
+
}
|
|
137
|
+
if (isPidAlive(pid)) {
|
|
138
|
+
console.error(`Process ${pid} did not exit after SIGTERM — sending SIGKILL.`);
|
|
139
|
+
process.kill(pid, 'SIGKILL');
|
|
140
|
+
}
|
|
127
141
|
}
|
|
128
142
|
safeUnlink(PID_FILE);
|
|
129
143
|
console.log(`suveren-gateway stopped (pid ${pid}).`);
|
|
@@ -136,6 +150,26 @@ async function stop() {
|
|
|
136
150
|
async function status() {
|
|
137
151
|
const pid = readPid();
|
|
138
152
|
if (!pid) {
|
|
153
|
+
// No PID file does NOT mean not running: when the login service owns the
|
|
154
|
+
// gateway, launchd/systemd/Task Scheduler spawn server.js directly and
|
|
155
|
+
// nothing writes one. Ask the port before declaring it dead — otherwise
|
|
156
|
+
// status contradicts a gateway that is plainly serving requests.
|
|
157
|
+
try {
|
|
158
|
+
const res = await fetch(`http://localhost:${SUVEREN_PORT}/health`, {
|
|
159
|
+
signal: AbortSignal.timeout(3000),
|
|
160
|
+
});
|
|
161
|
+
if (res.ok) {
|
|
162
|
+
const body = await res.json();
|
|
163
|
+
console.log('suveren-gateway: running (managed by the login service)');
|
|
164
|
+
console.log(` UI: http://localhost:${SUVEREN_PORT}`);
|
|
165
|
+
console.log(` Vault: ${body.vaultUnlocked ? 'unlocked' : 'locked'}`);
|
|
166
|
+
console.log(` Version: ${body.version ?? 'unknown'} (running)`);
|
|
167
|
+
console.log(` Service: suveren-gateway service status`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
} catch {
|
|
171
|
+
/* nothing listening — genuinely not running */
|
|
172
|
+
}
|
|
139
173
|
console.log('suveren-gateway: not running (no PID file).');
|
|
140
174
|
process.exit(3);
|
|
141
175
|
}
|
|
@@ -197,6 +231,333 @@ async function logs(args) {
|
|
|
197
231
|
}
|
|
198
232
|
}
|
|
199
233
|
|
|
234
|
+
// ─── service: install autostart-on-login (survives reboot) ──────────────
|
|
235
|
+
//
|
|
236
|
+
// Keeps the gateway PROCESS always running (starts on login, restarts on
|
|
237
|
+
// crash). It boots LOCKED — you still enter your Suveren API key once per
|
|
238
|
+
// reboot; nothing is persisted. See doc/gateway-always-on.md.
|
|
239
|
+
// Implemented on all three: macOS LaunchAgent, Windows Task Scheduler (ONLOGON),
|
|
240
|
+
// Linux systemd user unit. All USER-level — no admin, no root, no stored
|
|
241
|
+
// password.
|
|
242
|
+
|
|
243
|
+
const LAUNCH_AGENT_LABEL = 'ai.suveren.gateway';
|
|
244
|
+
|
|
245
|
+
async function service(args) {
|
|
246
|
+
const sub = args[0] ?? 'help';
|
|
247
|
+
const os = platform();
|
|
248
|
+
|
|
249
|
+
if (sub === 'help' || sub === '--help' || sub === '-h') { printServiceHelp(); return; }
|
|
250
|
+
|
|
251
|
+
const impl = serviceImplFor(os);
|
|
252
|
+
if (!impl) {
|
|
253
|
+
console.error(`\`suveren-gateway service\` is not available on ${os}.`);
|
|
254
|
+
console.error(`Supported: macOS, Windows, Linux. Run in the background with:`);
|
|
255
|
+
console.error(` suveren-gateway start --detach`);
|
|
256
|
+
console.error(`(Note: --detach does NOT survive a reboot — the service command will.)`);
|
|
257
|
+
process.exit(2);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
switch (sub) {
|
|
261
|
+
case 'install': await impl.install(); break;
|
|
262
|
+
case 'uninstall': await impl.uninstall(); break;
|
|
263
|
+
case 'status': await impl.status(); break;
|
|
264
|
+
default:
|
|
265
|
+
console.error(`Unknown: service ${sub}\n`);
|
|
266
|
+
printServiceHelp();
|
|
267
|
+
process.exit(2);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function launchAgentPath() {
|
|
272
|
+
return join(homedir(), 'Library', 'LaunchAgents', `${LAUNCH_AGENT_LABEL}.plist`);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/** Where the named launcher lives. Its FILENAME is the Login Items entry. */
|
|
276
|
+
function macLauncherPath() {
|
|
277
|
+
return join(DATA_DIR, 'Suveren');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
async function serviceInstallMac() {
|
|
281
|
+
ensureDataDir();
|
|
282
|
+
const plistPath = launchAgentPath();
|
|
283
|
+
mkdirSync(dirname(plistPath), { recursive: true });
|
|
284
|
+
|
|
285
|
+
// Deliberately does NOT stop the running gateway.
|
|
286
|
+
//
|
|
287
|
+
// Autostart is about FUTURE logins. Seizing the current instance forced a
|
|
288
|
+
// restart, the restart re-locked the vault, and the user was thrown back to
|
|
289
|
+
// the login screen with no idea whether it had worked. Register it and leave
|
|
290
|
+
// the running gateway alone; launchd picks the agent up at the next login,
|
|
291
|
+
// which is exactly when it is wanted.
|
|
292
|
+
|
|
293
|
+
// A launcher named `Suveren` so System Settings → Login Items shows that,
|
|
294
|
+
// rather than "node".
|
|
295
|
+
const launcherPath = macLauncherPath();
|
|
296
|
+
writeFileSync(launcherPath, buildMacLauncher({
|
|
297
|
+
nodePath: process.execPath,
|
|
298
|
+
serverEntry: SERVER_ENTRY,
|
|
299
|
+
}), { encoding: 'utf8', mode: 0o755 });
|
|
300
|
+
|
|
301
|
+
const plist = buildLaunchAgentPlist({
|
|
302
|
+
launcherPath,
|
|
303
|
+
label: LAUNCH_AGENT_LABEL,
|
|
304
|
+
logFile: LOG_FILE,
|
|
305
|
+
dataDir: process.env.SUVEREN_DATA_DIR ?? '',
|
|
306
|
+
// Captured now, while we are running from the user's shell. launchd would
|
|
307
|
+
// otherwise hand the gateway /usr/bin:/bin:/usr/sbin:/sbin, which has no
|
|
308
|
+
// npx and none of the integration shims — the gateway starts and then
|
|
309
|
+
// every integration silently fails to launch.
|
|
310
|
+
path: process.env.PATH ?? '',
|
|
311
|
+
});
|
|
312
|
+
writeFileSync(plistPath, plist, { encoding: 'utf8', mode: 0o644 });
|
|
313
|
+
|
|
314
|
+
const uid = process.getuid();
|
|
315
|
+
// Clear any prior "disabled" mark from a previous uninstall, so the agent is
|
|
316
|
+
// eligible again — but do NOT bootstrap it now: that would start a second
|
|
317
|
+
// gateway alongside the running one and fight over the port.
|
|
318
|
+
runQuiet('launchctl', ['enable', `gui/${uid}/${LAUNCH_AGENT_LABEL}`]);
|
|
319
|
+
|
|
320
|
+
console.log(`✓ Suveren gateway installed as a login service.`);
|
|
321
|
+
console.log(``);
|
|
322
|
+
console.log(` It starts automatically from your NEXT login, and restarts if it crashes.`);
|
|
323
|
+
console.log(` Your current gateway keeps running — nothing was interrupted.`);
|
|
324
|
+
console.log(` After a reboot it comes up LOCKED — open http://localhost:${SUVEREN_PORT} and`);
|
|
325
|
+
console.log(` enter your Suveren API key once to unlock it (your key is never stored).`);
|
|
326
|
+
console.log(``);
|
|
327
|
+
console.log(` Plist: ${plistPath}`);
|
|
328
|
+
console.log(` Status: suveren-gateway service status`);
|
|
329
|
+
console.log(` Remove: suveren-gateway service uninstall`);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
async function serviceUninstallMac() {
|
|
333
|
+
const plistPath = launchAgentPath();
|
|
334
|
+
const uid = process.getuid();
|
|
335
|
+
|
|
336
|
+
// Deliberately NOT `launchctl bootout`: that unloads AND kills the job, so
|
|
337
|
+
// turning autostart off would destroy the running gateway — and from the UI
|
|
338
|
+
// that is catastrophic, because the page doing the asking dies with it and
|
|
339
|
+
// there is nothing left to start it again. Removing the plist is enough to
|
|
340
|
+
// stop it coming back at login; `disable` stops launchd resurrecting it via
|
|
341
|
+
// KeepAlive in the meantime. The instance you have keeps serving.
|
|
342
|
+
runQuiet('launchctl', ['disable', `gui/${uid}/${LAUNCH_AGENT_LABEL}`]);
|
|
343
|
+
if (existsSync(plistPath)) safeUnlink(plistPath);
|
|
344
|
+
if (existsSync(macLauncherPath())) safeUnlink(macLauncherPath());
|
|
345
|
+
console.log(`✓ Login service removed. The gateway will no longer start on login.`);
|
|
346
|
+
console.log(' The running gateway keeps serving — only autostart is off, so it');
|
|
347
|
+
console.log(' will not come back by itself after a restart.');
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
async function serviceStatusMac() {
|
|
351
|
+
const plistPath = launchAgentPath();
|
|
352
|
+
const installed = existsSync(plistPath);
|
|
353
|
+
console.log(`Login service: ${installed ? 'installed' : 'not installed'}`);
|
|
354
|
+
if (installed) console.log(` Plist: ${plistPath}`);
|
|
355
|
+
const uid = process.getuid();
|
|
356
|
+
const p = runQuiet('launchctl', ['print', `gui/${uid}/${LAUNCH_AGENT_LABEL}`]);
|
|
357
|
+
if (p.status === 0) {
|
|
358
|
+
const state = /state = (\w+)/.exec(p.stdout || '');
|
|
359
|
+
console.log(` launchd: loaded${state ? ` (${state[1]})` : ''}`);
|
|
360
|
+
} else if (installed) {
|
|
361
|
+
console.log(` launchd: not loaded (run \`suveren-gateway service install\` to (re)load)`);
|
|
362
|
+
}
|
|
363
|
+
console.log('');
|
|
364
|
+
await status(); // process/health/vault line
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// ─── Windows: Task Scheduler (ONLOGON) ──────────────────────────────────
|
|
368
|
+
|
|
369
|
+
const WIN_TASK_NAME = 'Suveren';
|
|
370
|
+
|
|
371
|
+
async function serviceInstallWindows() {
|
|
372
|
+
ensureDataDir();
|
|
373
|
+
|
|
374
|
+
// Deliberately does NOT stop the running gateway — see the macOS note.
|
|
375
|
+
// Registering is enough; Task Scheduler starts it at the next logon.
|
|
376
|
+
|
|
377
|
+
// schtasks reads the XML from a file and requires UTF-16 LE with a BOM —
|
|
378
|
+
// it rejects UTF-8 with an unhelpful "The task XML is malformed".
|
|
379
|
+
const xml = buildWindowsTaskXml({
|
|
380
|
+
nodePath: process.execPath,
|
|
381
|
+
serverEntry: SERVER_ENTRY,
|
|
382
|
+
author: 'Suveren',
|
|
383
|
+
dataDir: process.env.SUVEREN_DATA_DIR ?? '',
|
|
384
|
+
});
|
|
385
|
+
const xmlPath = join(DATA_DIR, 'suveren-task.xml');
|
|
386
|
+
writeFileSync(xmlPath, '\ufeff' + xml, { encoding: 'utf16le' });
|
|
387
|
+
|
|
388
|
+
// /F overwrites an existing task, so install is idempotent.
|
|
389
|
+
const r = runQuiet('schtasks', ['/Create', '/TN', WIN_TASK_NAME, '/XML', xmlPath, '/F']);
|
|
390
|
+
safeUnlink(xmlPath);
|
|
391
|
+
|
|
392
|
+
if (r.status !== 0) {
|
|
393
|
+
console.error('Could not register the scheduled task.');
|
|
394
|
+
console.error(r.stderr || r.stdout || '');
|
|
395
|
+
process.exit(1);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
console.log('✓ Suveren gateway installed as a login task.');
|
|
399
|
+
console.log('');
|
|
400
|
+
console.log(' It starts automatically from your NEXT logon, and restarts if it crashes.');
|
|
401
|
+
console.log(' Your current gateway keeps running — nothing was interrupted.');
|
|
402
|
+
console.log(` After a reboot it comes up LOCKED — open http://localhost:${SUVEREN_PORT} and`);
|
|
403
|
+
console.log(' enter your Suveren API key once to unlock it (your key is never stored).');
|
|
404
|
+
console.log('');
|
|
405
|
+
console.log(` Task: ${WIN_TASK_NAME} (Task Scheduler, current user)`);
|
|
406
|
+
console.log(' Status: suveren-gateway service status');
|
|
407
|
+
console.log(' Remove: suveren-gateway service uninstall');
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
async function serviceUninstallWindows() {
|
|
411
|
+
const r = runQuiet('schtasks', ['/Delete', '/TN', WIN_TASK_NAME, '/F']);
|
|
412
|
+
if (r.status !== 0 && !/cannot find/i.test(r.stderr + r.stdout)) {
|
|
413
|
+
console.error('Could not remove the scheduled task.');
|
|
414
|
+
console.error(r.stderr || r.stdout || '');
|
|
415
|
+
process.exit(1);
|
|
416
|
+
}
|
|
417
|
+
console.log('✓ Login task removed. The gateway will no longer start on login.');
|
|
418
|
+
console.log(' (A currently-running instance keeps running until you `suveren-gateway stop`.)');
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
async function serviceStatusWindows() {
|
|
422
|
+
const r = runQuiet('schtasks', ['/Query', '/TN', WIN_TASK_NAME, '/FO', 'LIST']);
|
|
423
|
+
const installed = r.status === 0;
|
|
424
|
+
console.log(`Login service: ${installed ? 'installed' : 'not installed'}`);
|
|
425
|
+
if (installed) {
|
|
426
|
+
console.log(` Task: ${WIN_TASK_NAME}`);
|
|
427
|
+
const state = /Status:\s*(\S+)/.exec(r.stdout || '');
|
|
428
|
+
if (state) console.log(` State: ${state[1]}`);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// ─── Linux: systemd user unit ───────────────────────────────────────────
|
|
433
|
+
|
|
434
|
+
const SYSTEMD_UNIT = 'suveren-gateway.service';
|
|
435
|
+
|
|
436
|
+
function systemdUnitPath() {
|
|
437
|
+
const base = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');
|
|
438
|
+
return join(base, 'systemd', 'user', SYSTEMD_UNIT);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function hasSystemd() {
|
|
442
|
+
return runQuiet('systemctl', ['--user', '--version']).status === 0;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
async function serviceInstallLinux() {
|
|
446
|
+
ensureDataDir();
|
|
447
|
+
|
|
448
|
+
if (!hasSystemd()) {
|
|
449
|
+
console.error('systemd --user is not available on this system.');
|
|
450
|
+
console.error('Run it in the background instead: suveren-gateway start --detach');
|
|
451
|
+
process.exit(1);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Deliberately does NOT stop the running gateway — see the macOS note.
|
|
455
|
+
const unitPath = systemdUnitPath();
|
|
456
|
+
mkdirSync(dirname(unitPath), { recursive: true });
|
|
457
|
+
writeFileSync(unitPath, buildSystemdUnit({
|
|
458
|
+
nodePath: process.execPath,
|
|
459
|
+
serverEntry: SERVER_ENTRY,
|
|
460
|
+
logFile: LOG_FILE,
|
|
461
|
+
dataDir: process.env.SUVEREN_DATA_DIR ?? '',
|
|
462
|
+
// See the macOS note: a systemd user unit inherits no usable PATH either.
|
|
463
|
+
path: process.env.PATH ?? '',
|
|
464
|
+
}), { encoding: 'utf8', mode: 0o644 });
|
|
465
|
+
|
|
466
|
+
runQuiet('systemctl', ['--user', 'daemon-reload']);
|
|
467
|
+
// `enable` WITHOUT --now: registered for the next login, running instance
|
|
468
|
+
// untouched. --now would start a second gateway and fight over the port.
|
|
469
|
+
const en = runQuiet('systemctl', ['--user', 'enable', SYSTEMD_UNIT]);
|
|
470
|
+
if (en.status !== 0) {
|
|
471
|
+
console.error('Wrote the unit file but systemd could not enable it.');
|
|
472
|
+
console.error(en.stderr || en.stdout || '');
|
|
473
|
+
console.error(`Unit: ${unitPath}`);
|
|
474
|
+
process.exit(1);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
console.log('✓ Suveren gateway installed as a user service.');
|
|
478
|
+
console.log('');
|
|
479
|
+
console.log(' It starts automatically from your NEXT login, and restarts if it crashes.');
|
|
480
|
+
console.log(' Your current gateway keeps running — nothing was interrupted.');
|
|
481
|
+
console.log(` After a reboot it comes up LOCKED — open http://localhost:${SUVEREN_PORT} and`);
|
|
482
|
+
console.log(' enter your Suveren API key once to unlock it (your key is never stored).');
|
|
483
|
+
console.log('');
|
|
484
|
+
console.log(` Unit: ${unitPath}`);
|
|
485
|
+
console.log(' Status: suveren-gateway service status');
|
|
486
|
+
console.log(' Remove: suveren-gateway service uninstall');
|
|
487
|
+
console.log('');
|
|
488
|
+
console.log(' A user service starts at LOGIN. To have it run from boot without');
|
|
489
|
+
console.log(' logging in, enable lingering once:');
|
|
490
|
+
console.log(` loginctl enable-linger ${process.env.USER ?? '$USER'}`);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
async function serviceUninstallLinux() {
|
|
494
|
+
const unitPath = systemdUnitPath();
|
|
495
|
+
// `disable` WITHOUT --now: stop it starting at login, but leave the running
|
|
496
|
+
// instance alone. --now would stop it, and from the UI that kills the page
|
|
497
|
+
// making the request with nothing left to restart it.
|
|
498
|
+
runQuiet('systemctl', ['--user', 'disable', SYSTEMD_UNIT]);
|
|
499
|
+
if (existsSync(unitPath)) safeUnlink(unitPath);
|
|
500
|
+
runQuiet('systemctl', ['--user', 'daemon-reload']);
|
|
501
|
+
console.log('✓ User service removed. The gateway will no longer start on login.');
|
|
502
|
+
console.log(' The running gateway keeps serving — only autostart is off, so it');
|
|
503
|
+
console.log(' will not come back by itself after a restart.');
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
async function serviceStatusLinux() {
|
|
507
|
+
const unitPath = systemdUnitPath();
|
|
508
|
+
const installed = existsSync(unitPath);
|
|
509
|
+
console.log(`Login service: ${installed ? 'installed' : 'not installed'}`);
|
|
510
|
+
if (installed) console.log(` Unit: ${unitPath}`);
|
|
511
|
+
const active = runQuiet('systemctl', ['--user', 'is-active', SYSTEMD_UNIT]);
|
|
512
|
+
const enabled = runQuiet('systemctl', ['--user', 'is-enabled', SYSTEMD_UNIT]);
|
|
513
|
+
if (installed) {
|
|
514
|
+
console.log(` systemd: ${(active.stdout || 'unknown').trim()} / ${(enabled.stdout || 'unknown').trim()}`);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Per-platform autostart; null ⇒ unsupported platform.
|
|
520
|
+
*
|
|
521
|
+
* A function, not a const object: the CLI dispatches at the top of this file,
|
|
522
|
+
* which runs BEFORE a top-level const is initialised (temporal dead zone), so
|
|
523
|
+
* an object here threw "Cannot access before initialization" on every
|
|
524
|
+
* `service` invocation. Function declarations are hoisted.
|
|
525
|
+
*/
|
|
526
|
+
function serviceImplFor(os) {
|
|
527
|
+
switch (os) {
|
|
528
|
+
case 'darwin': return { install: serviceInstallMac, uninstall: serviceUninstallMac, status: serviceStatusMac };
|
|
529
|
+
case 'win32': return { install: serviceInstallWindows, uninstall: serviceUninstallWindows, status: serviceStatusWindows };
|
|
530
|
+
case 'linux': return { install: serviceInstallLinux, uninstall: serviceUninstallLinux, status: serviceStatusLinux };
|
|
531
|
+
default: return null;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/** Run a command capturing output, never throwing. */
|
|
536
|
+
function runQuiet(bin, args) {
|
|
537
|
+
const r = spawnSync(bin, args, { encoding: 'utf8' });
|
|
538
|
+
return { status: r.status ?? 1, stdout: r.stdout ?? '', stderr: r.stderr ?? '' };
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
function printServiceHelp() {
|
|
542
|
+
console.log(`suveren-gateway service — run the gateway as a login service (survives reboot)
|
|
543
|
+
|
|
544
|
+
Usage:
|
|
545
|
+
suveren-gateway service install Start on login + restart on crash
|
|
546
|
+
suveren-gateway service uninstall Remove the login service
|
|
547
|
+
suveren-gateway service status Show whether it's installed + running
|
|
548
|
+
|
|
549
|
+
Supported on macOS (LaunchAgent), Windows (Task Scheduler) and Linux (systemd
|
|
550
|
+
user unit). All are USER-level — no admin rights, no root, no stored password.
|
|
551
|
+
|
|
552
|
+
The gateway boots LOCKED after a reboot: you enter your Suveren API key once to
|
|
553
|
+
unlock it, and the key is never stored. Autostart keeps the PROCESS alive; it
|
|
554
|
+
cannot unlock your credentials for you.
|
|
555
|
+
|
|
556
|
+
Linux: a user service starts at LOGIN. To run it from boot without logging in,
|
|
557
|
+
enable lingering once: loginctl enable-linger $USER
|
|
558
|
+
`);
|
|
559
|
+
}
|
|
560
|
+
|
|
200
561
|
// ─── Helpers ────────────────────────────────────────────────────────────
|
|
201
562
|
|
|
202
563
|
function ensureDataDir() {
|
|
@@ -250,6 +611,8 @@ Usage:
|
|
|
250
611
|
suveren-gateway restart Stop, then start --detach
|
|
251
612
|
suveren-gateway status Show running state + health
|
|
252
613
|
suveren-gateway logs [--tail] Print or tail ~/.suveren/gateway.log
|
|
614
|
+
suveren-gateway service <cmd> Run as a login service that survives reboot
|
|
615
|
+
(install | uninstall | status; macOS today)
|
|
253
616
|
suveren-gateway help Print this help
|
|
254
617
|
|
|
255
618
|
Environment:
|
|
@@ -258,3 +621,31 @@ Environment:
|
|
|
258
621
|
SUVEREN_DATA_DIR Data directory (default ~/.suveren)
|
|
259
622
|
`);
|
|
260
623
|
}
|
|
624
|
+
|
|
625
|
+
// ─── Entry point ────────────────────────────────────────────────────────
|
|
626
|
+
//
|
|
627
|
+
// Called last so every declaration above is initialised first.
|
|
628
|
+
|
|
629
|
+
async function main() {
|
|
630
|
+
const argv = process.argv.slice(2);
|
|
631
|
+
const cmd = argv[0] ?? 'help';
|
|
632
|
+
|
|
633
|
+
switch (cmd) {
|
|
634
|
+
case 'start': await start(argv.slice(1)); break;
|
|
635
|
+
case 'stop': await stop(); break;
|
|
636
|
+
case 'status': await status(); break;
|
|
637
|
+
case 'restart': await restart(); break;
|
|
638
|
+
case 'logs': await logs(argv.slice(1)); break;
|
|
639
|
+
case 'service': await service(argv.slice(1)); break;
|
|
640
|
+
case 'help':
|
|
641
|
+
case '--help':
|
|
642
|
+
case '-h':
|
|
643
|
+
printHelp(); break;
|
|
644
|
+
default:
|
|
645
|
+
console.error(`Unknown command: ${cmd}\n`);
|
|
646
|
+
printHelp();
|
|
647
|
+
process.exit(2);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
await main();
|
|
@@ -56,10 +56,22 @@
|
|
|
56
56
|
"staticExecution": { "duration": 0, "lookahead": 0 }
|
|
57
57
|
},
|
|
58
58
|
"overrides": {
|
|
59
|
-
"list_calendars": {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
"list_calendars": {
|
|
60
|
+
"category": "read",
|
|
61
|
+
"read": { "resourceBound": "allowed_calendars", "resultResourcePath": "id" }
|
|
62
|
+
},
|
|
63
|
+
"list_events": {
|
|
64
|
+
"category": "read",
|
|
65
|
+
"read": { "resourceBound": "allowed_calendars", "resourceArg": "calendarId", "resourceDefault": "primary" }
|
|
66
|
+
},
|
|
67
|
+
"get_event": {
|
|
68
|
+
"category": "read",
|
|
69
|
+
"read": { "resourceBound": "allowed_calendars", "resourceArg": "calendarId", "resourceDefault": "primary" }
|
|
70
|
+
},
|
|
71
|
+
"free_busy": {
|
|
72
|
+
"category": "read",
|
|
73
|
+
"read": { "resourceBound": "allowed_calendars", "resourceArrayArg": "calendarIds", "resourceDefault": "primary" }
|
|
74
|
+
},
|
|
63
75
|
"create_event": {
|
|
64
76
|
"executionMapping": {
|
|
65
77
|
"duration_minutes": "duration",
|
|
@@ -70,7 +82,7 @@
|
|
|
70
82
|
],
|
|
71
83
|
"calendarId": "allowed_calendars"
|
|
72
84
|
},
|
|
73
|
-
"staticExecution": { "action_type": "
|
|
85
|
+
"staticExecution": { "action_type": "booking" }
|
|
74
86
|
},
|
|
75
87
|
"update_event": {
|
|
76
88
|
"executionMapping": {
|
|
@@ -80,7 +92,7 @@
|
|
|
80
92
|
],
|
|
81
93
|
"calendarId": "allowed_calendars"
|
|
82
94
|
},
|
|
83
|
-
"staticExecution": { "action_type": "
|
|
95
|
+
"staticExecution": { "action_type": "booking", "duration": 0, "lookahead": 0 }
|
|
84
96
|
},
|
|
85
97
|
"delete_event": {
|
|
86
98
|
"executionMapping": {
|
|
@@ -97,8 +109,8 @@
|
|
|
97
109
|
"risk": "low",
|
|
98
110
|
"mode": "automatic",
|
|
99
111
|
"bounds": { "booking_daily_max": "0", "booking_duration_max": "0", "lookahead_days_max": "0" },
|
|
100
|
-
"context": { "allowed_calendars": "", "allowed_attendees": "", "allowed_domains": "" },
|
|
101
|
-
"intent": "Allow the agent to
|
|
112
|
+
"context": { "allowed_calendars": "primary", "allowed_attendees": "", "allowed_domains": "" },
|
|
113
|
+
"intent": "Allow the agent to read the primary calendar (only) to help with scheduling suggestions. No create or modify. To read other calendars, add them to allowed_calendars.",
|
|
102
114
|
"ttl": 2592000,
|
|
103
115
|
"tags": ["read-only", "30 days"]
|
|
104
116
|
},
|