@mgsoftwarebv/mg-dashboard-mcp 7.0.6 → 7.0.7

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/dist/index.js CHANGED
@@ -20,6 +20,7 @@ import { sql } from 'drizzle-orm';
20
20
  import { once } from 'events';
21
21
  import { lookup } from 'dns/promises';
22
22
  import { connect } from 'tls';
23
+ import { pgTable, timestamp, jsonb, uuid, boolean, text, pgEnum, integer, uniqueIndex, index, bigint } from 'drizzle-orm/pg-core';
23
24
  import { tasks } from '@trigger.dev/sdk/v3';
24
25
  import { HeadObjectCommand, S3Client, ListObjectsV2Command, DeleteObjectsCommand, DeleteObjectCommand, CreateMultipartUploadCommand, UploadPartCommand, CompleteMultipartUploadCommand, AbortMultipartUploadCommand, PutObjectCommand, GetObjectCommand, CopyObjectCommand } from '@aws-sdk/client-s3';
25
26
 
@@ -943,9 +944,9 @@ async function fetchAndFormatRun(conn, proxy, sshExec2, instance, runId) {
943
944
  return { content: [{ type: "text", text: `Invalid API response:
944
945
  ${rawJson.substring(0, 500)}` }] };
945
946
  }
946
- let text = formatRunDetail(run);
947
- if (logs) text += "\n\n--- Logs ---\n" + logs;
948
- return { content: [{ type: "text", text }] };
947
+ let text6 = formatRunDetail(run);
948
+ if (logs) text6 += "\n\n--- Logs ---\n" + logs;
949
+ return { content: [{ type: "text", text: text6 }] };
949
950
  }
950
951
  async function waitForCompletion(conn, proxy, sshExec2, instance, runId, waitSeconds) {
951
952
  const pollInterval = 3e3;
@@ -967,10 +968,10 @@ async function waitForCompletion(conn, proxy, sshExec2, instance, runId, waitSec
967
968
  continue;
968
969
  }
969
970
  if (TERMINAL_STATUSES.has(run.status)) {
970
- let text = formatRunDetail(run);
971
+ let text6 = formatRunDetail(run);
971
972
  const logs = await fetchRunLogs(runId, conn, proxy, sshExec2);
972
- if (logs) text += "\n\n--- Logs ---\n" + logs;
973
- return { content: [{ type: "text", text }] };
973
+ if (logs) text6 += "\n\n--- Logs ---\n" + logs;
974
+ return { content: [{ type: "text", text: text6 }] };
974
975
  }
975
976
  }
976
977
  return {
@@ -3657,10 +3658,10 @@ var ZodObject = class _ZodObject extends ZodType {
3657
3658
  // }) as any;
3658
3659
  // return merged;
3659
3660
  // }
3660
- catchall(index) {
3661
+ catchall(index4) {
3661
3662
  return new _ZodObject({
3662
3663
  ...this._def,
3663
- catchall: index
3664
+ catchall: index4
3664
3665
  });
3665
3666
  }
3666
3667
  pick(mask) {
@@ -3978,9 +3979,9 @@ function mergeValues(a, b) {
3978
3979
  return { valid: false };
3979
3980
  }
3980
3981
  const newArray = [];
3981
- for (let index = 0; index < a.length; index++) {
3982
- const itemA = a[index];
3983
- const itemB = b[index];
3982
+ for (let index4 = 0; index4 < a.length; index4++) {
3983
+ const itemA = a[index4];
3984
+ const itemB = b[index4];
3984
3985
  const sharedValue = mergeValues(itemA, itemB);
3985
3986
  if (!sharedValue.valid) {
3986
3987
  return { valid: false };
@@ -4186,10 +4187,10 @@ var ZodMap = class extends ZodType {
4186
4187
  }
4187
4188
  const keyType = this._def.keyType;
4188
4189
  const valueType = this._def.valueType;
4189
- const pairs = [...ctx.data.entries()].map(([key, value], index) => {
4190
+ const pairs = [...ctx.data.entries()].map(([key, value], index4) => {
4190
4191
  return {
4191
- key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, "key"])),
4192
- value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"]))
4192
+ key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index4, "key"])),
4193
+ value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index4, "value"]))
4193
4194
  };
4194
4195
  });
4195
4196
  if (ctx.common.async) {
@@ -5103,6 +5104,618 @@ external_exports.array(LitespeedVhostMappingSchema);
5103
5104
  function normalizeVhostDomain(value) {
5104
5105
  return value.trim().replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/\.+$/, "").toLowerCase();
5105
5106
  }
5107
+ var users = pgTable("user", {
5108
+ id: uuid("id").primaryKey().defaultRandom(),
5109
+ email: text("email").notNull().unique(),
5110
+ fullName: text("full_name"),
5111
+ avatarUrl: text("avatar_url"),
5112
+ emailVerified: boolean("email_verified").notNull().default(false),
5113
+ roleId: uuid("role_id"),
5114
+ permissions: jsonb("permissions"),
5115
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5116
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5117
+ });
5118
+ pgTable("session", {
5119
+ id: uuid("id").primaryKey().defaultRandom(),
5120
+ userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
5121
+ token: text("token").notNull().unique(),
5122
+ expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
5123
+ ipAddress: text("ip_address"),
5124
+ userAgent: text("user_agent"),
5125
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5126
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5127
+ });
5128
+ pgTable("account", {
5129
+ id: uuid("id").primaryKey().defaultRandom(),
5130
+ userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
5131
+ providerId: text("provider_id").notNull(),
5132
+ accountId: text("account_id").notNull(),
5133
+ password: text("password"),
5134
+ accessToken: text("access_token"),
5135
+ refreshToken: text("refresh_token"),
5136
+ accessTokenExpiresAt: timestamp("access_token_expires_at", {
5137
+ withTimezone: true
5138
+ }),
5139
+ refreshTokenExpiresAt: timestamp("refresh_token_expires_at", {
5140
+ withTimezone: true
5141
+ }),
5142
+ scope: text("scope"),
5143
+ idToken: text("id_token"),
5144
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5145
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5146
+ });
5147
+ pgTable("verification", {
5148
+ id: uuid("id").primaryKey().defaultRandom(),
5149
+ identifier: text("identifier").notNull(),
5150
+ value: text("value").notNull(),
5151
+ expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
5152
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5153
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5154
+ });
5155
+ pgTable("two_factor", {
5156
+ id: uuid("id").primaryKey().defaultRandom(),
5157
+ userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
5158
+ secret: text("secret").notNull(),
5159
+ backupCodes: text("backup_codes")
5160
+ });
5161
+ var managedServerOs = pgEnum("managed_server_os", [
5162
+ "linux",
5163
+ "windows",
5164
+ "unknown"
5165
+ ]);
5166
+ var serverAgentStatus = pgEnum("server_agent_status", [
5167
+ "not_installed",
5168
+ "installing",
5169
+ "online",
5170
+ "degraded",
5171
+ "offline",
5172
+ "error"
5173
+ ]);
5174
+ var resourceKind = pgEnum("resource_kind", [
5175
+ "wordpress",
5176
+ "prestashop",
5177
+ "postgres_cluster",
5178
+ "postgres_database",
5179
+ "mysql_database",
5180
+ "mariadb_database",
5181
+ "boiler_project",
5182
+ "boiler_web_project",
5183
+ "static_site",
5184
+ "docker_app",
5185
+ "domain",
5186
+ "backup_policy",
5187
+ "server_service"
5188
+ ]);
5189
+ var resourceStatus = pgEnum("resource_status", [
5190
+ "unknown",
5191
+ "healthy",
5192
+ "degraded",
5193
+ "failed",
5194
+ "missing",
5195
+ "provisioning",
5196
+ "disabled"
5197
+ ]);
5198
+ var resourceOwnership = pgEnum("resource_ownership", [
5199
+ "managed",
5200
+ "discovered",
5201
+ "external"
5202
+ ]);
5203
+ var operationStatus = pgEnum("operation_status", [
5204
+ "queued",
5205
+ "running",
5206
+ "succeeded",
5207
+ "failed",
5208
+ "cancelled"
5209
+ ]);
5210
+ var alertSeverity = pgEnum("alert_severity", [
5211
+ "info",
5212
+ "warning",
5213
+ "critical"
5214
+ ]);
5215
+ var managedServer = pgTable(
5216
+ "managed_server",
5217
+ {
5218
+ id: uuid("id").primaryKey().defaultRandom(),
5219
+ name: text("name").notNull(),
5220
+ hostname: text("hostname").notNull(),
5221
+ port: integer("port").notNull().default(22),
5222
+ username: text("username").notNull(),
5223
+ authMethod: text("auth_method").notNull().default("ssh_key"),
5224
+ os: managedServerOs("os").notNull().default("unknown"),
5225
+ provider: text("provider"),
5226
+ region: text("region"),
5227
+ tags: jsonb("tags").$type().notNull().default([]),
5228
+ agentStatus: serverAgentStatus("agent_status").notNull().default("not_installed"),
5229
+ agentVersion: text("agent_version"),
5230
+ lastSeenAt: timestamp("last_seen_at", { withTimezone: true }),
5231
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5232
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5233
+ },
5234
+ (table) => [
5235
+ uniqueIndex("managed_server_hostname_port_uidx").on(
5236
+ table.hostname,
5237
+ table.port
5238
+ ),
5239
+ index("managed_server_agent_status_idx").on(table.agentStatus)
5240
+ ]
5241
+ );
5242
+ pgTable("server_credential", {
5243
+ serverId: uuid("server_id").primaryKey().references(() => managedServer.id, { onDelete: "cascade" }),
5244
+ passwordEncrypted: text("password_encrypted"),
5245
+ sshKeyEncrypted: text("ssh_key_encrypted"),
5246
+ sshKeyPassphraseEncrypted: text("ssh_key_passphrase_encrypted"),
5247
+ dbRootPasswordEncrypted: text("db_root_password_encrypted"),
5248
+ monitoringApiKeyEncrypted: text("monitoring_api_key_encrypted"),
5249
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5250
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5251
+ });
5252
+ pgTable(
5253
+ "server_connection_log",
5254
+ {
5255
+ id: uuid("id").primaryKey().defaultRandom(),
5256
+ serverId: uuid("server_id").notNull().references(() => managedServer.id, { onDelete: "cascade" }),
5257
+ userId: uuid("user_id").notNull(),
5258
+ connectedAt: timestamp("connected_at", { withTimezone: true }).notNull().defaultNow(),
5259
+ disconnectedAt: timestamp("disconnected_at", { withTimezone: true }),
5260
+ durationSeconds: integer("duration_seconds"),
5261
+ status: text("status").notNull(),
5262
+ errorMessage: text("error_message"),
5263
+ clientIp: text("client_ip"),
5264
+ terminalCols: integer("terminal_cols"),
5265
+ terminalRows: integer("terminal_rows"),
5266
+ outputSizeBytes: bigint("output_size_bytes", { mode: "number" }).notNull().default(0),
5267
+ inputSizeBytes: bigint("input_size_bytes", { mode: "number" }).notNull().default(0),
5268
+ commandCount: integer("command_count").notNull().default(0),
5269
+ connectionType: text("connection_type").notNull().default("terminal"),
5270
+ action: text("action"),
5271
+ rawOutput: text("raw_output"),
5272
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
5273
+ },
5274
+ (table) => [
5275
+ index("server_connection_log_server_idx").on(table.serverId),
5276
+ index("server_connection_log_user_idx").on(table.userId),
5277
+ index("server_connection_log_connected_idx").on(table.connectedAt),
5278
+ index("server_connection_log_status_idx").on(table.status)
5279
+ ]
5280
+ );
5281
+ pgTable(
5282
+ "mcp_audit_log",
5283
+ {
5284
+ id: uuid("id").primaryKey().defaultRandom(),
5285
+ apiKeyId: uuid("api_key_id"),
5286
+ userId: uuid("user_id"),
5287
+ toolName: text("tool_name"),
5288
+ arguments: jsonb("arguments"),
5289
+ ipAddress: text("ip_address"),
5290
+ serverId: uuid("server_id"),
5291
+ resultStatus: text("result_status").notNull().default("success"),
5292
+ errorMessage: text("error_message"),
5293
+ durationMs: integer("duration_ms"),
5294
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
5295
+ },
5296
+ (table) => [
5297
+ index("mcp_audit_log_created_at_idx").on(table.createdAt),
5298
+ index("mcp_audit_log_user_idx").on(table.userId),
5299
+ index("mcp_audit_log_tool_name_idx").on(table.toolName),
5300
+ index("mcp_audit_log_server_idx").on(table.serverId),
5301
+ index("mcp_audit_log_api_key_idx").on(table.apiKeyId),
5302
+ index("mcp_audit_log_result_status_idx").on(table.resultStatus)
5303
+ ]
5304
+ );
5305
+ var resource = pgTable(
5306
+ "resource",
5307
+ {
5308
+ id: uuid("id").primaryKey().defaultRandom(),
5309
+ serverId: uuid("server_id").notNull().references(() => managedServer.id, { onDelete: "cascade" }),
5310
+ parentResourceId: uuid("parent_resource_id"),
5311
+ kind: resourceKind("kind").notNull(),
5312
+ slug: text("slug").notNull(),
5313
+ displayName: text("display_name").notNull(),
5314
+ spec: jsonb("spec").$type().notNull().default({}),
5315
+ state: jsonb("state").$type().notNull().default({}),
5316
+ status: resourceStatus("status").notNull().default("unknown"),
5317
+ ownership: resourceOwnership("ownership").notNull().default("managed"),
5318
+ lastDetectedAt: timestamp("last_detected_at", { withTimezone: true }),
5319
+ lastEventId: uuid("last_event_id"),
5320
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5321
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5322
+ },
5323
+ (table) => [
5324
+ uniqueIndex("resource_server_kind_slug_uidx").on(
5325
+ table.serverId,
5326
+ table.kind,
5327
+ table.slug
5328
+ ),
5329
+ index("resource_server_idx").on(table.serverId),
5330
+ index("resource_parent_idx").on(table.parentResourceId),
5331
+ index("resource_kind_status_idx").on(table.kind, table.status)
5332
+ ]
5333
+ );
5334
+ pgTable(
5335
+ "resource_event",
5336
+ {
5337
+ id: uuid("id").primaryKey().defaultRandom(),
5338
+ resourceId: uuid("resource_id").notNull().references(() => resource.id, { onDelete: "cascade" }),
5339
+ kind: text("kind").notNull(),
5340
+ before: jsonb("before").$type(),
5341
+ after: jsonb("after").$type(),
5342
+ actorUserId: text("actor_user_id"),
5343
+ operationId: uuid("operation_id"),
5344
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
5345
+ },
5346
+ (table) => [
5347
+ index("resource_event_resource_created_idx").on(
5348
+ table.resourceId,
5349
+ table.createdAt
5350
+ ),
5351
+ index("resource_event_operation_idx").on(table.operationId)
5352
+ ]
5353
+ );
5354
+ var operation = pgTable(
5355
+ "operation",
5356
+ {
5357
+ id: uuid("id").primaryKey().defaultRandom(),
5358
+ kind: text("kind").notNull(),
5359
+ resourceId: uuid("resource_id").references(() => resource.id, {
5360
+ onDelete: "set null"
5361
+ }),
5362
+ serverId: uuid("server_id").references(() => managedServer.id, {
5363
+ onDelete: "set null"
5364
+ }),
5365
+ status: operationStatus("status").notNull().default("queued"),
5366
+ steps: jsonb("steps").$type().notNull().default([]),
5367
+ idempotencyKey: text("idempotency_key").notNull(),
5368
+ triggerRunId: text("trigger_run_id"),
5369
+ logsR2Key: text("logs_r2_key"),
5370
+ logs: text("logs"),
5371
+ startedBy: text("started_by"),
5372
+ startedAt: timestamp("started_at", { withTimezone: true }),
5373
+ endedAt: timestamp("ended_at", { withTimezone: true }),
5374
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5375
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5376
+ },
5377
+ (table) => [
5378
+ uniqueIndex("operation_idempotency_uidx").on(table.idempotencyKey),
5379
+ index("operation_resource_idx").on(table.resourceId),
5380
+ index("operation_server_idx").on(table.serverId),
5381
+ index("operation_status_created_idx").on(table.status, table.createdAt)
5382
+ ]
5383
+ );
5384
+ pgTable(
5385
+ "agent_installation",
5386
+ {
5387
+ id: uuid("id").primaryKey().defaultRandom(),
5388
+ serverId: uuid("server_id").notNull().references(() => managedServer.id, { onDelete: "cascade" }),
5389
+ agentId: text("agent_id"),
5390
+ version: text("version").notNull(),
5391
+ installPath: text("install_path").notNull().default("/usr/local/bin/mg-agent"),
5392
+ configHash: text("config_hash").notNull(),
5393
+ status: serverAgentStatus("status").notNull().default("installing"),
5394
+ lastHeartbeatAt: timestamp("last_heartbeat_at", { withTimezone: true }),
5395
+ lastError: text("last_error"),
5396
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5397
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5398
+ },
5399
+ (table) => [
5400
+ uniqueIndex("agent_installation_server_uidx").on(table.serverId),
5401
+ index("agent_installation_status_idx").on(table.status)
5402
+ ]
5403
+ );
5404
+ pgTable(
5405
+ "monitoring_sample",
5406
+ {
5407
+ id: uuid("id").primaryKey().defaultRandom(),
5408
+ serverId: uuid("server_id").notNull().references(() => managedServer.id, { onDelete: "cascade" }),
5409
+ resourceId: uuid("resource_id").references(() => resource.id, {
5410
+ onDelete: "cascade"
5411
+ }),
5412
+ metric: text("metric").notNull(),
5413
+ value: integer("value").notNull(),
5414
+ unit: text("unit").notNull(),
5415
+ tags: jsonb("tags").$type().notNull().default({}),
5416
+ sampledAt: timestamp("sampled_at", { withTimezone: true }).notNull().defaultNow()
5417
+ },
5418
+ (table) => [
5419
+ index("monitoring_sample_server_metric_time_idx").on(
5420
+ table.serverId,
5421
+ table.metric,
5422
+ table.sampledAt
5423
+ ),
5424
+ // Descending on sampled_at so "latest metric per (server, metric)" lookups
5425
+ // (DISTINCT ON ... ORDER BY sampled_at DESC) are served by an index-only
5426
+ // scan instead of a full-table sort. The migration also adds
5427
+ // INCLUDE (value, unit) to make it covering for the overview snapshot query
5428
+ // (Drizzle 0.44 can't express INCLUDE here). See migration 20260529210000.
5429
+ index("monitoring_sample_server_metric_time_desc_idx").on(
5430
+ table.serverId,
5431
+ table.metric,
5432
+ table.sampledAt.desc()
5433
+ ),
5434
+ index("monitoring_sample_resource_metric_time_idx").on(
5435
+ table.resourceId,
5436
+ table.metric,
5437
+ table.sampledAt
5438
+ )
5439
+ ]
5440
+ );
5441
+ var appLogSource = pgTable(
5442
+ "app_log_source",
5443
+ {
5444
+ id: uuid("id").primaryKey().defaultRandom(),
5445
+ serverId: uuid("server_id").notNull().references(() => managedServer.id, { onDelete: "cascade" }),
5446
+ resourceId: uuid("resource_id").references(() => resource.id, {
5447
+ onDelete: "set null"
5448
+ }),
5449
+ sourceType: text("source_type").notNull(),
5450
+ sourceKey: text("source_key").notNull(),
5451
+ displayName: text("display_name").notNull(),
5452
+ path: text("path").notNull(),
5453
+ enabled: boolean("enabled").notNull().default(true),
5454
+ mutedUntil: timestamp("muted_until", { withTimezone: true }),
5455
+ metadata: jsonb("metadata").$type().notNull().default({}),
5456
+ lastSeenAt: timestamp("last_seen_at", { withTimezone: true }).notNull().defaultNow(),
5457
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5458
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5459
+ },
5460
+ (table) => [
5461
+ uniqueIndex("app_log_source_server_type_key_uidx").on(
5462
+ table.serverId,
5463
+ table.sourceType,
5464
+ table.sourceKey
5465
+ ),
5466
+ index("app_log_source_server_idx").on(table.serverId),
5467
+ index("app_log_source_resource_idx").on(table.resourceId),
5468
+ index("app_log_source_type_seen_idx").on(
5469
+ table.sourceType,
5470
+ table.lastSeenAt
5471
+ )
5472
+ ]
5473
+ );
5474
+ pgTable(
5475
+ "app_error_event",
5476
+ {
5477
+ id: uuid("id").primaryKey().defaultRandom(),
5478
+ serverId: uuid("server_id").notNull().references(() => managedServer.id, { onDelete: "cascade" }),
5479
+ resourceId: uuid("resource_id").references(() => resource.id, {
5480
+ onDelete: "set null"
5481
+ }),
5482
+ logSourceId: uuid("log_source_id").references(() => appLogSource.id, {
5483
+ onDelete: "set null"
5484
+ }),
5485
+ fingerprint: text("fingerprint").notNull(),
5486
+ severity: text("severity").notNull().default("critical"),
5487
+ category: text("category").notNull(),
5488
+ sourceType: text("source_type").notNull(),
5489
+ sourcePath: text("source_path").notNull(),
5490
+ sampleMessage: text("sample_message").notNull(),
5491
+ sampleLines: jsonb("sample_lines").$type().notNull().default([]),
5492
+ signals: jsonb("signals").$type().notNull().default({}),
5493
+ occurrences: integer("occurrences").notNull().default(1),
5494
+ firstSeenAt: timestamp("first_seen_at", { withTimezone: true }).notNull().defaultNow(),
5495
+ lastSeenAt: timestamp("last_seen_at", { withTimezone: true }).notNull().defaultNow(),
5496
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
5497
+ },
5498
+ (table) => [
5499
+ index("app_error_event_fingerprint_created_idx").on(
5500
+ table.fingerprint,
5501
+ table.createdAt
5502
+ ),
5503
+ index("app_error_event_server_created_idx").on(
5504
+ table.serverId,
5505
+ table.createdAt
5506
+ ),
5507
+ index("app_error_event_resource_created_idx").on(
5508
+ table.resourceId,
5509
+ table.createdAt
5510
+ ),
5511
+ index("app_error_event_severity_created_idx").on(
5512
+ table.severity,
5513
+ table.createdAt
5514
+ )
5515
+ ]
5516
+ );
5517
+ pgTable(
5518
+ "app_error_alert",
5519
+ {
5520
+ id: uuid("id").primaryKey().defaultRandom(),
5521
+ fingerprint: text("fingerprint").notNull(),
5522
+ serverId: uuid("server_id").notNull().references(() => managedServer.id, { onDelete: "cascade" }),
5523
+ resourceId: uuid("resource_id").references(() => resource.id, {
5524
+ onDelete: "set null"
5525
+ }),
5526
+ logSourceId: uuid("log_source_id").references(() => appLogSource.id, {
5527
+ onDelete: "set null"
5528
+ }),
5529
+ severity: text("severity").notNull().default("critical"),
5530
+ status: text("status").notNull().default("open"),
5531
+ category: text("category").notNull(),
5532
+ title: text("title").notNull(),
5533
+ lastError: text("last_error").notNull(),
5534
+ sampleLines: jsonb("sample_lines").$type().notNull().default([]),
5535
+ signals: jsonb("signals").$type().notNull().default({}),
5536
+ failureCount: integer("failure_count").notNull().default(1),
5537
+ firstSeenAt: timestamp("first_seen_at", { withTimezone: true }).notNull().defaultNow(),
5538
+ lastSeenAt: timestamp("last_seen_at", { withTimezone: true }).notNull().defaultNow(),
5539
+ lastAlertAt: timestamp("last_alert_at", { withTimezone: true }),
5540
+ resolvedAt: timestamp("resolved_at", { withTimezone: true }),
5541
+ mutedUntil: timestamp("muted_until", { withTimezone: true }),
5542
+ cursorPrompt: text("cursor_prompt"),
5543
+ telegramChatId: text("telegram_chat_id"),
5544
+ telegramMessageId: bigint("telegram_message_id", { mode: "number" }),
5545
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5546
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5547
+ },
5548
+ (table) => [
5549
+ uniqueIndex("app_error_alert_fingerprint_uidx").on(table.fingerprint),
5550
+ index("app_error_alert_status_seen_idx").on(
5551
+ table.status,
5552
+ table.lastSeenAt
5553
+ ),
5554
+ index("app_error_alert_server_seen_idx").on(
5555
+ table.serverId,
5556
+ table.lastSeenAt
5557
+ ),
5558
+ index("app_error_alert_resource_seen_idx").on(
5559
+ table.resourceId,
5560
+ table.lastSeenAt
5561
+ ),
5562
+ index("app_error_alert_alerted_idx").on(table.lastAlertAt)
5563
+ ]
5564
+ );
5565
+ pgTable(
5566
+ "alert_rule",
5567
+ {
5568
+ id: uuid("id").primaryKey().defaultRandom(),
5569
+ serverId: uuid("server_id").references(() => managedServer.id, {
5570
+ onDelete: "cascade"
5571
+ }),
5572
+ resourceId: uuid("resource_id").references(() => resource.id, {
5573
+ onDelete: "cascade"
5574
+ }),
5575
+ metric: text("metric").notNull(),
5576
+ expression: text("expression").notNull(),
5577
+ severity: alertSeverity("severity").notNull().default("warning"),
5578
+ cooldownSeconds: integer("cooldown_seconds").notNull().default(900),
5579
+ enabled: boolean("enabled").notNull().default(true),
5580
+ routes: jsonb("routes").$type().notNull().default({}),
5581
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5582
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5583
+ },
5584
+ (table) => [
5585
+ index("alert_rule_server_idx").on(table.serverId),
5586
+ index("alert_rule_resource_idx").on(table.resourceId),
5587
+ index("alert_rule_enabled_severity_idx").on(table.enabled, table.severity)
5588
+ ]
5589
+ );
5590
+ pgTable(
5591
+ "deployment_project_server",
5592
+ {
5593
+ id: uuid("id").primaryKey().defaultRandom(),
5594
+ releaseProfileStageId: uuid("release_profile_stage_id").notNull(),
5595
+ sshServerId: uuid("ssh_server_id").notNull(),
5596
+ deployPath: text("deploy_path").notNull(),
5597
+ deployPathNormalized: text("deploy_path_normalized"),
5598
+ pm2PortBase: integer("pm2_port_base").notNull(),
5599
+ postgresHost: text("postgres_host"),
5600
+ postgresPort: integer("postgres_port"),
5601
+ buildFilters: text("build_filters"),
5602
+ envSymlinkDirs: jsonb("env_symlink_dirs"),
5603
+ litespeedVhosts: jsonb("litespeed_vhosts"),
5604
+ litespeedVhostsCheckedAt: timestamp("litespeed_vhosts_checked_at", {
5605
+ withTimezone: true
5606
+ }),
5607
+ litespeedVhostsCheckOk: boolean("litespeed_vhosts_check_ok"),
5608
+ ecosystemConfig: text("ecosystem_config").notNull().default("ecosystem.config.cjs"),
5609
+ usePipelineDeploy: boolean("use_pipeline_deploy").notNull().default(true),
5610
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5611
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5612
+ },
5613
+ (table) => [
5614
+ uniqueIndex("deployment_project_server_stage_server_uidx").on(
5615
+ table.releaseProfileStageId,
5616
+ table.sshServerId
5617
+ ),
5618
+ uniqueIndex("deployment_project_server_server_path_uidx").on(
5619
+ table.sshServerId,
5620
+ table.deployPathNormalized
5621
+ ),
5622
+ uniqueIndex("deployment_project_server_server_port_uidx").on(
5623
+ table.sshServerId,
5624
+ table.pm2PortBase
5625
+ )
5626
+ ]
5627
+ );
5628
+ var dnsMigrationStatus = pgEnum("dns_migration_status", [
5629
+ "pending",
5630
+ "scanned",
5631
+ "imported",
5632
+ "verified"
5633
+ ]);
5634
+ var dnsMigration = pgTable(
5635
+ "dns_migration",
5636
+ {
5637
+ id: uuid("id").primaryKey().defaultRandom(),
5638
+ domain: text("domain").notNull(),
5639
+ sourceProvider: text("source_provider").notNull().default("hostnet"),
5640
+ status: dnsMigrationStatus("status").notNull().default("pending"),
5641
+ scannedRecords: jsonb("scanned_records").$type().notNull().default([]),
5642
+ sourceNameservers: jsonb("source_nameservers").$type().notNull().default([]),
5643
+ currentNameservers: jsonb("current_nameservers").$type().notNull().default([]),
5644
+ importResult: jsonb("import_result").$type(),
5645
+ emailChecklist: jsonb("email_checklist").$type().notNull().default({}),
5646
+ directadminHost: text("directadmin_host"),
5647
+ directadminUsername: text("directadmin_username"),
5648
+ directadminPasswordEncrypted: text("directadmin_password_encrypted"),
5649
+ syncServerId: uuid("sync_server_id").references(() => managedServer.id, {
5650
+ onDelete: "set null"
5651
+ }),
5652
+ syncOperationId: uuid("sync_operation_id").references(() => operation.id, {
5653
+ onDelete: "set null"
5654
+ }),
5655
+ mailRecordsImportedAt: timestamp("mail_records_imported_at", {
5656
+ withTimezone: true
5657
+ }),
5658
+ notes: text("notes"),
5659
+ lastError: text("last_error"),
5660
+ lastScannedAt: timestamp("last_scanned_at", { withTimezone: true }),
5661
+ importedAt: timestamp("imported_at", { withTimezone: true }),
5662
+ verifiedAt: timestamp("verified_at", { withTimezone: true }),
5663
+ createdBy: text("created_by"),
5664
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5665
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5666
+ },
5667
+ (table) => [
5668
+ index("dns_migration_domain_idx").on(table.domain),
5669
+ index("dns_migration_status_created_idx").on(
5670
+ table.status,
5671
+ table.createdAt
5672
+ )
5673
+ ]
5674
+ );
5675
+ var dnsMigrationMailboxStatus = pgEnum(
5676
+ "dns_migration_mailbox_status",
5677
+ ["pending", "provisioned", "syncing", "synced", "delta_synced", "failed"]
5678
+ );
5679
+ pgTable(
5680
+ "dns_migration_mailbox",
5681
+ {
5682
+ id: uuid("id").primaryKey().defaultRandom(),
5683
+ migrationId: uuid("migration_id").notNull().references(() => dnsMigration.id, { onDelete: "cascade" }),
5684
+ address: text("address").notNull(),
5685
+ sourcePasswordEncrypted: text("source_password_encrypted"),
5686
+ destPasswordEncrypted: text("dest_password_encrypted"),
5687
+ status: dnsMigrationMailboxStatus("status").notNull().default("pending"),
5688
+ syncStats: jsonb("sync_stats").$type(),
5689
+ lastError: text("last_error"),
5690
+ provisionedAt: timestamp("provisioned_at", { withTimezone: true }),
5691
+ lastSyncedAt: timestamp("last_synced_at", { withTimezone: true }),
5692
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5693
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5694
+ },
5695
+ (table) => [
5696
+ uniqueIndex("dns_migration_mailbox_migration_address_uidx").on(
5697
+ table.migrationId,
5698
+ table.address
5699
+ ),
5700
+ index("dns_migration_mailbox_migration_idx").on(table.migrationId)
5701
+ ]
5702
+ );
5703
+ pgTable(
5704
+ "github_token",
5705
+ {
5706
+ id: uuid("id").primaryKey().defaultRandom(),
5707
+ label: text("label").notNull(),
5708
+ owner: text("owner"),
5709
+ notes: text("notes"),
5710
+ tokenEncrypted: text("token_encrypted").notNull(),
5711
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5712
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5713
+ },
5714
+ (table) => [
5715
+ index("github_token_label_idx").on(table.label),
5716
+ index("github_token_owner_idx").on(table.owner)
5717
+ ]
5718
+ );
5106
5719
  async function triggerPipeline(payload) {
5107
5720
  return tasks.trigger(
5108
5721
  "execute-pipeline",
@@ -5667,10 +6280,10 @@ function inferDeployMethod(folderName, hasNextConfig, hasDockerfile, hasPm2Ecosy
5667
6280
  function toLabel(folderName) {
5668
6281
  return folderName.charAt(0).toUpperCase() + folderName.slice(1);
5669
6282
  }
5670
- async function scanRepoForApps(repoFullName, githubToken, ref = "main") {
6283
+ async function scanRepoForApps(repoFullName, githubToken2, ref = "main") {
5671
6284
  const headers = {
5672
6285
  Accept: "application/vnd.github.v3+json",
5673
- Authorization: `Bearer ${githubToken}`,
6286
+ Authorization: `Bearer ${githubToken2}`,
5674
6287
  "Content-Type": "application/json"
5675
6288
  };
5676
6289
  async function fetchContents(path) {
@@ -5816,10 +6429,10 @@ function toStageApps(apps) {
5816
6429
  enabled: a.enabled
5817
6430
  }));
5818
6431
  }
5819
- async function ensureGitHubBranchExists(repoFullName, branchName, fromBranch, githubToken) {
6432
+ async function ensureGitHubBranchExists(repoFullName, branchName, fromBranch, githubToken2) {
5820
6433
  const headers = {
5821
6434
  Accept: "application/vnd.github.v3+json",
5822
- Authorization: `Bearer ${githubToken}`,
6435
+ Authorization: `Bearer ${githubToken2}`,
5823
6436
  "Content-Type": "application/json"
5824
6437
  };
5825
6438
  const checkRes = await fetch(
@@ -6822,7 +7435,7 @@ function getEncryptionKey() {
6822
7435
  throw new Error("ENCRYPTION_KEY must be a 64-character hex string");
6823
7436
  return buf;
6824
7437
  }
6825
- function encrypt(text) {
7438
+ function encrypt(text6) {
6826
7439
  const key = getEncryptionKey();
6827
7440
  const iv = randomBytes(ENC_IV_LENGTH);
6828
7441
  const cipher = createCipheriv(
@@ -6830,7 +7443,7 @@ function encrypt(text) {
6830
7443
  new Uint8Array(key),
6831
7444
  new Uint8Array(iv)
6832
7445
  );
6833
- let encrypted = cipher.update(text, "utf8", "hex");
7446
+ let encrypted = cipher.update(text6, "utf8", "hex");
6834
7447
  encrypted += cipher.final("hex");
6835
7448
  const authTag = cipher.getAuthTag();
6836
7449
  return Buffer.concat([
@@ -7550,10 +8163,10 @@ async function r2GetObjectRange(bucket, key, range) {
7550
8163
  const body = result.Body;
7551
8164
  if (!body?.transformToString)
7552
8165
  throw new Error("R2 returned no readable body");
7553
- const text = await body.transformToString();
8166
+ const text6 = await body.transformToString();
7554
8167
  const header = `# range: bytes ${range.offset}-${end} of ${size} (${effectiveLen} bytes)`;
7555
8168
  return `${header}
7556
- ${text}`;
8169
+ ${text6}`;
7557
8170
  } catch (e) {
7558
8171
  throw r2WrapError(bucket, key, e);
7559
8172
  }
@@ -7916,15 +8529,15 @@ async function sftpRead(opts, filePath, proxy, options) {
7916
8529
  clearTimeout(timer);
7917
8530
  cleanup?.();
7918
8531
  cleanup = void 0;
7919
- const text = Buffer.concat(
8532
+ const text6 = Buffer.concat(
7920
8533
  chunks.map((ch) => new Uint8Array(ch))
7921
8534
  ).toString("utf-8");
7922
8535
  if (!isWholeFileRequest) {
7923
8536
  const header = `# range: bytes ${offset}-${offset + effectiveLen - 1} of ${total} (${effectiveLen} bytes)`;
7924
8537
  resolve(`${header}
7925
- ${text}`);
8538
+ ${text6}`);
7926
8539
  } else {
7927
- resolve(text);
8540
+ resolve(text6);
7928
8541
  }
7929
8542
  });
7930
8543
  rs.on("error", (e) => {
@@ -8054,11 +8667,11 @@ function getKnownContainers(serverId, maxAgeMs = 5 * 6e4) {
8054
8667
  if (Date.now() - e.capturedAt > maxAgeMs) return void 0;
8055
8668
  return e.names;
8056
8669
  }
8057
- function truncateForLLM(text, maxBytes) {
8058
- const totalBytes = Buffer.byteLength(text, "utf8");
8670
+ function truncateForLLM(text6, maxBytes) {
8671
+ const totalBytes = Buffer.byteLength(text6, "utf8");
8059
8672
  if (totalBytes <= maxBytes)
8060
- return { text, truncated: false, totalBytes, shownBytes: totalBytes };
8061
- const buf = Buffer.from(text, "utf8");
8673
+ return { text: text6, truncated: false, totalBytes, shownBytes: totalBytes };
8674
+ const buf = Buffer.from(text6, "utf8");
8062
8675
  let cut = maxBytes;
8063
8676
  while (cut > 0 && (buf[cut] & 192) === 128) cut--;
8064
8677
  const head = buf.subarray(0, cut).toString("utf8");
@@ -8088,10 +8701,10 @@ function isTransientSshError(stderr, exitCode) {
8088
8701
  function postprocessResult(result, meta) {
8089
8702
  if (!result.content?.length) return result;
8090
8703
  const block = result.content[0];
8091
- let text = String(block.text ?? "");
8092
- const trunc = truncateForLLM(text, RESPONSE_MAX_BYTES);
8704
+ let text6 = String(block.text ?? "");
8705
+ const trunc = truncateForLLM(text6, RESPONSE_MAX_BYTES);
8093
8706
  if (trunc.truncated) {
8094
- text = trunc.text + "\n\n... " + buildTruncationHint(
8707
+ text6 = trunc.text + "\n\n... " + buildTruncationHint(
8095
8708
  meta.toolName,
8096
8709
  meta.args,
8097
8710
  trunc.totalBytes,
@@ -8105,11 +8718,11 @@ function postprocessResult(result, meta) {
8105
8718
  const parts = [`took ${tookStr}`, sizeStr];
8106
8719
  if (meta.serverIdLabel) parts.push(`server: ${meta.serverIdLabel}`);
8107
8720
  if (meta.cached) parts.push("cached");
8108
- text = `${text}
8721
+ text6 = `${text6}
8109
8722
 
8110
8723
  [${parts.join(", ")}]`;
8111
8724
  }
8112
- return { ...result, content: [{ ...block, text }] };
8725
+ return { ...result, content: [{ ...block, text: text6 }] };
8113
8726
  }
8114
8727
  function buildPipelineScript(commands, shell, marker, stopOnError) {
8115
8728
  if (shell === "powershell") {
@@ -11164,8 +11777,8 @@ ${sample.join("\n")}${files.length > 5 ? `
11164
11777
  };
11165
11778
  const filtered = sortRows(applyFilter(only.rows));
11166
11779
  if (format === "json") {
11167
- const text2 = filtered.map((c) => JSON.stringify(c)).join("\n") || "(no containers)";
11168
- return { content: [{ type: "text", text: text2 }] };
11780
+ const text7 = filtered.map((c) => JSON.stringify(c)).join("\n") || "(no containers)";
11781
+ return { content: [{ type: "text", text: text7 }] };
11169
11782
  }
11170
11783
  if (groupByProject) {
11171
11784
  const groups = /* @__PURE__ */ new Map();
@@ -11192,8 +11805,8 @@ ${sample.join("\n")}${files.length > 5 ? `
11192
11805
  }
11193
11806
  const header = `${"NAMES".padEnd(36)} ${"IMAGE".padEnd(40)} ${"STATUS".padEnd(24)} ${"HEALTH".padEnd(10)} ${"PORTS".padEnd(40)} PROJECT`;
11194
11807
  const body = filtered.map((r) => `${fmtRow(r)} ${r.Project || ""}`);
11195
- const text = filtered.length === 0 ? "(no containers match)" : [header, ...body].join("\n");
11196
- return { content: [{ type: "text", text }] };
11808
+ const text6 = filtered.length === 0 ? "(no containers match)" : [header, ...body].join("\n");
11809
+ return { content: [{ type: "text", text: text6 }] };
11197
11810
  }
11198
11811
  if (format === "json") {
11199
11812
  const lines = [];
@@ -12766,7 +13379,7 @@ ${lines.join("\n\n")}`
12766
13379
  // ----- Domains (mijn.host) -----
12767
13380
  case "domain-list": {
12768
13381
  const res = await mijnhostFetch(
12769
- "/domains"
13382
+ "/domains/"
12770
13383
  );
12771
13384
  const domains = res.data.domains;
12772
13385
  if (!domains.length) {