@helyx/cli 1.6.0 → 1.6.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.6.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Remove unused internal development, status reporting, OAuth, private control,
|
|
8
|
+
advanced Cloud Connect and Auto Moderation tuning examples from the self-host
|
|
9
|
+
environment template and portable documentation. The environment builder also
|
|
10
|
+
omits these examples from older templates while preserving existing active
|
|
11
|
+
custom settings. Keep Discord intent settings, basic Cloud Connect and data
|
|
12
|
+
encryption configuration; runtime defaults and scanning behavior are unchanged.
|
|
13
|
+
|
|
3
14
|
## 1.6.0
|
|
4
15
|
|
|
5
16
|
### Minor Changes
|
|
@@ -22,6 +22,8 @@ type HostedOnlyBotEnvironment = "HELYX_PRIVACY_ENABLED" | "HELYX_PRIVACY_EXECUTO
|
|
|
22
22
|
type EnvironmentExample = Record<Exclude<keyof BotEnvironmentInput, HostedOnlyBotEnvironment>, {
|
|
23
23
|
value: string;
|
|
24
24
|
optional: boolean;
|
|
25
|
+
} | {
|
|
26
|
+
omit: true;
|
|
25
27
|
}>;
|
|
26
28
|
export declare const selfHostEnvironmentContract: EnvironmentExample;
|
|
27
29
|
export {};
|
|
@@ -180,6 +180,12 @@ function validateEnvironmentTemplate(template, databaseEngine) {
|
|
|
180
180
|
.split("\n")
|
|
181
181
|
.map((line) => line.trim()));
|
|
182
182
|
for (const [key, definition] of Object.entries(selfHostEnvironmentContract)) {
|
|
183
|
+
if ("omit" in definition) {
|
|
184
|
+
const setting = new RegExp(`^(?:#\\s*)?${key}\\s*=`, "u");
|
|
185
|
+
if ([...lines].some((line) => setting.test(line)))
|
|
186
|
+
throw new Error(`Self-host environment template contains an omitted setting: ${key}`);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
183
189
|
const value = key === "DATABASE_ENGINE"
|
|
184
190
|
? databaseEngine
|
|
185
191
|
: key === "DATABASE_URL" && databaseEngine === "mysql"
|
|
@@ -333,25 +339,15 @@ export const selfHostEnvironmentContract = {
|
|
|
333
339
|
DISCORD_TOKEN: { value: "replace-me", optional: false },
|
|
334
340
|
DISCORD_CLIENT_ID: { value: "12345678901234567", optional: false },
|
|
335
341
|
HELYX_MESSAGE_CONTENT_ENABLED: { value: "false", optional: false },
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
},
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
optional: true,
|
|
346
|
-
},
|
|
347
|
-
DISCORD_INTERNAL_GUILD_ID: {
|
|
348
|
-
value: "12345678901234567",
|
|
349
|
-
optional: true,
|
|
350
|
-
},
|
|
351
|
-
APPROVED_ROLES: {
|
|
352
|
-
value: "12345678901234567,12345678901234568",
|
|
353
|
-
optional: true,
|
|
354
|
-
},
|
|
342
|
+
// Advanced self-host options use runtime defaults; internal/hosted settings
|
|
343
|
+
// are deliberately absent from the customer example.
|
|
344
|
+
HELYX_AUTOMOD_EMBEDDED_WORKERS: { omit: true },
|
|
345
|
+
HELYX_AUTOMOD_EMBEDDED_QUEUE_ITEMS: { omit: true },
|
|
346
|
+
HELYX_AUTOMOD_EMBEDDED_QUEUE_BYTES: { omit: true },
|
|
347
|
+
HELYX_AUTOMOD_EMBEDDED_QUEUE_ITEMS_PER_GUILD: { omit: true },
|
|
348
|
+
HELYX_AUTOMOD_EMBEDDED_REFRESH_SECONDS: { omit: true },
|
|
349
|
+
DISCORD_INTERNAL_GUILD_ID: { omit: true },
|
|
350
|
+
APPROVED_ROLES: { omit: true },
|
|
355
351
|
HELYX_MODULE_PACKAGES: {
|
|
356
352
|
value: "",
|
|
357
353
|
optional: true,
|
|
@@ -364,16 +360,10 @@ export const selfHostEnvironmentContract = {
|
|
|
364
360
|
value: "https://app.helyx.gg",
|
|
365
361
|
optional: true,
|
|
366
362
|
},
|
|
367
|
-
HELYX_BOT_CONTROL_SECRET: {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
},
|
|
371
|
-
HELYX_BOT_CONTROL_PORT: { value: "3001", optional: true },
|
|
372
|
-
HELYX_GUILD_RECONCILIATION_INTERVAL_SECONDS: {
|
|
373
|
-
value: "900",
|
|
374
|
-
optional: true,
|
|
375
|
-
},
|
|
376
|
-
HELYX_HOSTED_MODERATION_ENABLED: { value: "false", optional: false },
|
|
363
|
+
HELYX_BOT_CONTROL_SECRET: { omit: true },
|
|
364
|
+
HELYX_BOT_CONTROL_PORT: { omit: true },
|
|
365
|
+
HELYX_GUILD_RECONCILIATION_INTERVAL_SECONDS: { omit: true },
|
|
366
|
+
HELYX_HOSTED_MODERATION_ENABLED: { omit: true },
|
|
377
367
|
HELYX_GUILD_COMMAND_WRITES_ENABLED: { value: "false", optional: false },
|
|
378
368
|
HELYX_GUILD_COMMAND_WRITE_SCOPE: { value: "allowlist", optional: false },
|
|
379
369
|
HELYX_GUILD_COMMAND_RELEASE_ID: { value: "", optional: true },
|
|
@@ -381,31 +371,16 @@ export const selfHostEnvironmentContract = {
|
|
|
381
371
|
HELYX_GUILD_COMMAND_WRITE_GUILD_IDS: { value: "", optional: true },
|
|
382
372
|
HELYX_GUILD_MEMBERS_ENABLED: { value: "false", optional: false },
|
|
383
373
|
HELYX_CLOUD_CONNECT_ENABLED: { value: "true", optional: false },
|
|
384
|
-
HELYX_CLOUD_ENROLMENT_TOKEN: {
|
|
385
|
-
|
|
386
|
-
optional: true,
|
|
387
|
-
},
|
|
388
|
-
HELYX_CLOUD_ENROLMENT_FILE: {
|
|
389
|
-
value: "./helyx.cloud-enrolment.json",
|
|
390
|
-
optional: true,
|
|
391
|
-
},
|
|
374
|
+
HELYX_CLOUD_ENROLMENT_TOKEN: { omit: true },
|
|
375
|
+
HELYX_CLOUD_ENROLMENT_FILE: { omit: true },
|
|
392
376
|
HELYX_DATA_ENCRYPTION_KEY: {
|
|
393
377
|
value: "replace-with-a-base64-encoded-32-byte-key",
|
|
394
378
|
optional: true,
|
|
395
379
|
},
|
|
396
|
-
HELYX_CLOUD_API_URL: {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
},
|
|
400
|
-
HELYX_OAUTH_ENABLED: { value: "false", optional: false },
|
|
401
|
-
HELYX_OAUTH_INTERNAL_SECRET: {
|
|
402
|
-
value: "replace-with-a-base64-encoded-32-byte-key",
|
|
403
|
-
optional: true,
|
|
404
|
-
},
|
|
405
|
-
HELYX_CLOUD_ENDPOINT: {
|
|
406
|
-
value: "wss://connect.helyx.gg/v1/connect",
|
|
407
|
-
optional: true,
|
|
408
|
-
},
|
|
380
|
+
HELYX_CLOUD_API_URL: { omit: true },
|
|
381
|
+
HELYX_OAUTH_ENABLED: { omit: true },
|
|
382
|
+
HELYX_OAUTH_INTERNAL_SECRET: { omit: true },
|
|
383
|
+
HELYX_CLOUD_ENDPOINT: { omit: true },
|
|
409
384
|
HELYX_OWNER_USER_IDS: {
|
|
410
385
|
value: "12345678901234567",
|
|
411
386
|
optional: true,
|
|
@@ -438,35 +413,14 @@ export const selfHostEnvironmentContract = {
|
|
|
438
413
|
value: "4",
|
|
439
414
|
optional: true,
|
|
440
415
|
},
|
|
441
|
-
HELYX_CLOUD_AUDIT_RETENTION_DAYS: {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
},
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
},
|
|
449
|
-
HELYX_STATUS_ENABLED: { value: "false", optional: false },
|
|
450
|
-
HELYX_STATUS_URL: {
|
|
451
|
-
value: "https://status.helyx.gg",
|
|
452
|
-
optional: true,
|
|
453
|
-
},
|
|
454
|
-
HELYX_STATUS_HEARTBEAT_SECRET: {
|
|
455
|
-
value: "replace-with-a-base64-encoded-32-byte-key",
|
|
456
|
-
optional: true,
|
|
457
|
-
},
|
|
458
|
-
HELYX_STATUS_HEARTBEAT_INTERVAL_SECONDS: {
|
|
459
|
-
value: "60",
|
|
460
|
-
optional: true,
|
|
461
|
-
},
|
|
462
|
-
CF_ACCESS_CLIENT_ID: {
|
|
463
|
-
value: "replace-with-access-client-id",
|
|
464
|
-
optional: true,
|
|
465
|
-
},
|
|
466
|
-
CF_ACCESS_CLIENT_SECRET: {
|
|
467
|
-
value: "replace-with-access-client-secret",
|
|
468
|
-
optional: true,
|
|
469
|
-
},
|
|
416
|
+
HELYX_CLOUD_AUDIT_RETENTION_DAYS: { omit: true },
|
|
417
|
+
HELYX_CLOUD_CREDENTIAL_AUDIT_RETENTION_DAYS: { omit: true },
|
|
418
|
+
HELYX_STATUS_ENABLED: { omit: true },
|
|
419
|
+
HELYX_STATUS_URL: { omit: true },
|
|
420
|
+
HELYX_STATUS_HEARTBEAT_SECRET: { omit: true },
|
|
421
|
+
HELYX_STATUS_HEARTBEAT_INTERVAL_SECONDS: { omit: true },
|
|
422
|
+
CF_ACCESS_CLIENT_ID: { omit: true },
|
|
423
|
+
CF_ACCESS_CLIENT_SECRET: { omit: true },
|
|
470
424
|
LOG_LEVEL: { value: "info", optional: false },
|
|
471
425
|
NODE_ENV: { value: "production", optional: false },
|
|
472
426
|
};
|
package/package.json
CHANGED
package/self-host-catalogue.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"catalogueVersion":
|
|
3
|
+
"catalogueVersion": 87,
|
|
4
4
|
"core": {
|
|
5
5
|
"package": "@helyx/bot",
|
|
6
|
-
"version": "1.5.
|
|
6
|
+
"version": "1.5.4",
|
|
7
7
|
"availability": "published"
|
|
8
8
|
},
|
|
9
9
|
"generator": {
|
|
10
10
|
"package": "@helyx/cli",
|
|
11
|
-
"version": "1.6.
|
|
11
|
+
"version": "1.6.1",
|
|
12
12
|
"command": "helyx",
|
|
13
13
|
"availability": "published"
|
|
14
14
|
},
|
|
@@ -9,16 +9,6 @@ DISCORD_CLIENT_ID=12345678901234567
|
|
|
9
9
|
# Explicit privileged gateway opt-in. Keep false unless a reviewed loaded module
|
|
10
10
|
# requires message content and it is enabled in the Discord developer portal.
|
|
11
11
|
HELYX_MESSAGE_CONTENT_ENABLED=false
|
|
12
|
-
# Enhanced Auto Moderation stays inside this bot process. One worker is the
|
|
13
|
-
# recommended default (range 1-4); increase only after measuring CPU and memory.
|
|
14
|
-
# Hosted scanning uses the separate Helyx Ecko service, not these settings.
|
|
15
|
-
HELYX_AUTOMOD_EMBEDDED_WORKERS=1
|
|
16
|
-
# Optional conservative queue overrides (hard ceilings: 5000 items, 64 MiB,
|
|
17
|
-
# 100 items per server). Defaults are used when these remain commented.
|
|
18
|
-
# HELYX_AUTOMOD_EMBEDDED_QUEUE_ITEMS=5000
|
|
19
|
-
# HELYX_AUTOMOD_EMBEDDED_QUEUE_BYTES=67108864
|
|
20
|
-
# HELYX_AUTOMOD_EMBEDDED_QUEUE_ITEMS_PER_GUILD=100
|
|
21
|
-
# HELYX_AUTOMOD_EMBEDDED_REFRESH_SECONDS=300
|
|
22
12
|
# Enable for loaded member workflows such as Welcome, Access Control or Levels,
|
|
23
13
|
# with Server Members Intent also enabled in the Discord developer portal.
|
|
24
14
|
HELYX_GUILD_MEMBERS_ENABLED=false
|
|
@@ -51,10 +41,6 @@ HELYX_CLOUD_CONNECT_ENABLED=true
|
|
|
51
41
|
# trace, debug, info, warn, error, fatal or silent
|
|
52
42
|
LOG_LEVEL=info
|
|
53
43
|
|
|
54
|
-
# Guild-scoped development commands only
|
|
55
|
-
# DISCORD_INTERNAL_GUILD_ID=12345678901234567
|
|
56
|
-
# APPROVED_ROLES=12345678901234567,12345678901234568
|
|
57
|
-
|
|
58
44
|
# SHARDING: OFF BY DEFAULT
|
|
59
45
|
|
|
60
46
|
# `off` is the compatible self-host default. Keep shard-only values commented
|
|
@@ -80,12 +66,6 @@ HELYX_SHARD_MODE=off
|
|
|
80
66
|
# Additional reviewed module packages
|
|
81
67
|
# HELYX_MODULE_PACKAGES=
|
|
82
68
|
|
|
83
|
-
# Private dashboard control endpoint — configure both together
|
|
84
|
-
# HELYX_BOT_CONTROL_SECRET=replace-with-a-base64-encoded-32-byte-key
|
|
85
|
-
# HELYX_BOT_CONTROL_PORT=3001
|
|
86
|
-
# HELYX_GUILD_RECONCILIATION_INTERVAL_SECONDS=900
|
|
87
|
-
HELYX_HOSTED_MODERATION_ENABLED=false
|
|
88
|
-
|
|
89
69
|
# Guild command writes remain off until explicitly enabled for known guild IDs.
|
|
90
70
|
# For enabled-module server commands, set writes=true, retain allowlist scope,
|
|
91
71
|
# add comma-separated Discord server IDs below, and use global mode platform-only.
|
|
@@ -96,14 +76,6 @@ HELYX_GUILD_COMMAND_WRITE_SCOPE=allowlist
|
|
|
96
76
|
HELYX_GLOBAL_COMMAND_MODE=legacy
|
|
97
77
|
# HELYX_GUILD_COMMAND_WRITE_GUILD_IDS=
|
|
98
78
|
|
|
99
|
-
# Alternative Cloud Connect enrolment — the Discord command is preferred
|
|
100
|
-
# HELYX_CLOUD_ENROLMENT_TOKEN=replace-with-a-short-lived-enrolment-code
|
|
101
|
-
# HELYX_CLOUD_ENROLMENT_FILE=./helyx.cloud-enrolment.json
|
|
102
|
-
|
|
103
|
-
# Hosted OAuth bridge. Keep disabled unless the API and bot share this secret.
|
|
104
|
-
HELYX_OAUTH_ENABLED=false
|
|
105
|
-
# HELYX_OAUTH_INTERNAL_SECRET=replace-with-a-base64-encoded-32-byte-key
|
|
106
|
-
|
|
107
79
|
# DANGER ZONE — HELYX-MANAGED VALUES, DO NOT EDIT
|
|
108
80
|
|
|
109
81
|
# Generated module selection
|
|
@@ -113,22 +85,5 @@ HELYX_MODULE_CATALOGUE_PATH=./helyx.modules.json
|
|
|
113
85
|
# and Invite Tracking; retain it unchanged across restarts and deployments.
|
|
114
86
|
# HELYX_DATA_ENCRYPTION_KEY=replace-with-a-base64-encoded-32-byte-key
|
|
115
87
|
|
|
116
|
-
# Official Cloud Connect endpoints
|
|
117
|
-
# HELYX_CLOUD_API_URL=https://api.helyx.gg
|
|
118
|
-
# HELYX_CLOUD_ENDPOINT=wss://connect.helyx.gg/v1/connect
|
|
119
|
-
|
|
120
|
-
# Security audit retention
|
|
121
|
-
# HELYX_CLOUD_AUDIT_RETENTION_DAYS=90
|
|
122
|
-
# HELYX_CLOUD_CREDENTIAL_AUDIT_RETENTION_DAYS=365
|
|
123
|
-
|
|
124
|
-
# Optional public status reporting. Keep disabled unless this installation has
|
|
125
|
-
# its own approved Helyx status credentials.
|
|
126
|
-
HELYX_STATUS_ENABLED=false
|
|
127
|
-
# HELYX_STATUS_URL=https://status.helyx.gg
|
|
128
|
-
# HELYX_STATUS_HEARTBEAT_SECRET=replace-with-a-base64-encoded-32-byte-key
|
|
129
|
-
# HELYX_STATUS_HEARTBEAT_INTERVAL_SECONDS=60
|
|
130
|
-
# CF_ACCESS_CLIENT_ID=replace-with-access-client-id
|
|
131
|
-
# CF_ACCESS_CLIENT_SECRET=replace-with-access-client-secret
|
|
132
|
-
|
|
133
88
|
# Runtime mode
|
|
134
89
|
NODE_ENV=production
|
|
@@ -208,23 +208,19 @@ const environmentGroups = [
|
|
|
208
208
|
],
|
|
209
209
|
["DATA ENCRYPTION - KEEP THIS KEY", /^HELYX_DATA_ENCRYPTION_KEY$/u],
|
|
210
210
|
["LOGGING", /^LOG_LEVEL$/u],
|
|
211
|
-
["AUTO MODERATION", /^HELYX_AUTOMOD_/u],
|
|
212
211
|
["SHARDING - ADVANCED", /^HELYX_SHARD_/u],
|
|
213
212
|
["MODULE SELECTION", /^HELYX_MODULE_/u],
|
|
214
|
-
[
|
|
215
|
-
"PRIVATE CONTROL - ADVANCED",
|
|
216
|
-
/^HELYX_BOT_CONTROL_|^HELYX_HOSTED_MODERATION_ENABLED$|^HELYX_GUILD_RECONCILIATION_INTERVAL_SECONDS$/u,
|
|
217
|
-
],
|
|
218
|
-
["CLOUD CONNECT - ADVANCED", /^HELYX_CLOUD_/u],
|
|
219
|
-
["OAUTH - ADVANCED", /^HELYX_OAUTH_/u],
|
|
220
|
-
["STATUS REPORTING - OPTIONAL", /^HELYX_STATUS_|^CF_ACCESS_/u],
|
|
221
|
-
[
|
|
222
|
-
"INTERNAL DEVELOPMENT - OPTIONAL",
|
|
223
|
-
/^(?:DISCORD_INTERNAL_GUILD_ID|APPROVED_ROLES)$/u,
|
|
224
|
-
],
|
|
225
213
|
["CUSTOM SETTINGS", /./u],
|
|
226
214
|
];
|
|
215
|
+
const omittedExampleSetting =
|
|
216
|
+
/^(?:HELYX_AUTOMOD_|HELYX_BOT_CONTROL_|HELYX_HOSTED_MODERATION_ENABLED$|HELYX_GUILD_RECONCILIATION_INTERVAL_SECONDS$|HELYX_CLOUD_(?!CONNECT_ENABLED$)|HELYX_OAUTH_|HELYX_STATUS_|CF_ACCESS_|DISCORD_INTERNAL_GUILD_ID$|APPROVED_ROLES$)/u;
|
|
227
217
|
const oldHeadings = new Set([
|
|
218
|
+
"AUTO MODERATION",
|
|
219
|
+
"PRIVATE CONTROL - ADVANCED",
|
|
220
|
+
"CLOUD CONNECT - ADVANCED",
|
|
221
|
+
"OAUTH - ADVANCED",
|
|
222
|
+
"STATUS REPORTING - OPTIONAL",
|
|
223
|
+
"INTERNAL DEVELOPMENT - OPTIONAL",
|
|
228
224
|
"REQUIRED — EDIT THESE VALUES",
|
|
229
225
|
"Discord",
|
|
230
226
|
"Database",
|
|
@@ -237,7 +233,7 @@ const oldHeadings = new Set([
|
|
|
237
233
|
"Keep this file private. Lines starting with # are comments.",
|
|
238
234
|
]);
|
|
239
235
|
|
|
240
|
-
export function formatEnvironment(content) {
|
|
236
|
+
export function formatEnvironment(content, { template = false } = {}) {
|
|
241
237
|
const newline = content.includes("\r\n") ? "\r\n" : "\n";
|
|
242
238
|
const groups = environmentGroups.map(() => []);
|
|
243
239
|
let pending = [];
|
|
@@ -265,6 +261,10 @@ export function formatEnvironment(content) {
|
|
|
265
261
|
continue;
|
|
266
262
|
const key =
|
|
267
263
|
record.key ?? text.match(/^\s*#\s*([A-Za-z_][A-Za-z0-9_]*)\s*=/u)?.[1];
|
|
264
|
+
if (key && omittedExampleSetting.test(key) && (template || !record.key)) {
|
|
265
|
+
pending = [];
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
268
|
if (!key) {
|
|
269
269
|
if (!text.trim() && pending.length && previousGroup !== undefined) {
|
|
270
270
|
append(previousGroup, pending);
|
|
@@ -295,6 +295,9 @@ export function formatEnvironment(content) {
|
|
|
295
295
|
].join("\n\n\n") + "\n";
|
|
296
296
|
const formatted = output.replace(/\n/gu, newline);
|
|
297
297
|
const before = parseEnv(content);
|
|
298
|
+
if (template)
|
|
299
|
+
for (const key of Object.keys(before))
|
|
300
|
+
if (omittedExampleSetting.test(key)) delete before[key];
|
|
298
301
|
const after = parseEnv(formatted);
|
|
299
302
|
if (
|
|
300
303
|
Object.keys(before).length !== Object.keys(after).length ||
|
|
@@ -420,7 +423,10 @@ export async function runWizard({
|
|
|
420
423
|
"Choose a downloaded Helyx starter folder containing package.json and .env.example.",
|
|
421
424
|
);
|
|
422
425
|
const original = await optionalRead(join(directory, ".env"));
|
|
423
|
-
const template =
|
|
426
|
+
const template = formatEnvironment(
|
|
427
|
+
await readFile(join(directory, ".env.example"), "utf8"),
|
|
428
|
+
{ template: true },
|
|
429
|
+
);
|
|
424
430
|
const existing = parseEnv(original ?? "");
|
|
425
431
|
const defaults = parseEnv(template);
|
|
426
432
|
const values = { ...defaults, ...existing };
|