@mgsoftwarebv/mg-dashboard-mcp 7.4.3 → 7.4.5

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.
Files changed (2) hide show
  1. package/dist/index.js +432 -190
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -20,7 +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, check, bigint } from 'drizzle-orm/pg-core';
23
+ import { pgTable, timestamp, jsonb, uuid, boolean, text, pgEnum, integer, uniqueIndex, index, check, bigint, foreignKey } from 'drizzle-orm/pg-core';
24
24
  import { HeadObjectCommand, ListObjectsV2Command, DeleteObjectsCommand, S3Client, DeleteObjectCommand, CreateMultipartUploadCommand, UploadPartCommand, CompleteMultipartUploadCommand, AbortMultipartUploadCommand, PutObjectCommand, GetObjectCommand, CopyObjectCommand } from '@aws-sdk/client-s3';
25
25
 
26
26
  var __defProp = Object.defineProperty;
@@ -703,10 +703,10 @@ var TRIGGER_TOOL_MODULE_MAP = {
703
703
  "trigger-env": "settings"
704
704
  };
705
705
  async function discoverInstance(projectSlug, conn, proxy, sshExec2) {
706
- const sql26 = `SELECT re.\\"apiKey\\" || '~~' || p.\\"externalRef\\" FROM \\"RuntimeEnvironment\\" re JOIN \\"Project\\" p ON re.\\"projectId\\" = p.id WHERE p.slug='${projectSlug}' AND re.slug='prod' LIMIT 1`;
706
+ const sql27 = `SELECT re.\\"apiKey\\" || '~~' || p.\\"externalRef\\" FROM \\"RuntimeEnvironment\\" re JOIN \\"Project\\" p ON re.\\"projectId\\" = p.id WHERE p.slug='${projectSlug}' AND re.slug='prod' LIMIT 1`;
707
707
  const cmd = [
708
708
  `PORT=$(docker port "${WA_CONTAINER}" 3000/tcp 2>/dev/null | head -1 | sed 's/.*://')`,
709
- `ROW=$(docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql26}" 2>/dev/null | tr -d '[:space:]')`,
709
+ `ROW=$(docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql27}" 2>/dev/null | tr -d '[:space:]')`,
710
710
  'echo "$PORT|$ROW"'
711
711
  ].join(" && ");
712
712
  const result = await sshExec2(conn, cmd, proxy);
@@ -728,8 +728,8 @@ async function discoverInstance(projectSlug, conn, proxy, sshExec2) {
728
728
  return { port, apiKey: apiKey2, projectRef: projectRef || "" };
729
729
  }
730
730
  async function fetchRunLogs(runId, conn, proxy, sshExec2) {
731
- const sql26 = `SELECT level, message, \\"isError\\", \\"createdAt\\" FROM \\"TaskEvent\\" WHERE \\"runId\\" = '${runId}' AND level IN ('INFO','WARN','ERROR','DEBUG','LOG','TRACE') ORDER BY \\"startTime\\" ASC LIMIT 200`;
732
- const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql26}" 2>/dev/null`;
731
+ const sql27 = `SELECT level, message, \\"isError\\", \\"createdAt\\" FROM \\"TaskEvent\\" WHERE \\"runId\\" = '${runId}' AND level IN ('INFO','WARN','ERROR','DEBUG','LOG','TRACE') ORDER BY \\"startTime\\" ASC LIMIT 200`;
732
+ const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql27}" 2>/dev/null`;
733
733
  const result = await sshExec2(conn, cmd, proxy);
734
734
  const output = result.stdout.trim();
735
735
  if (!output) return "";
@@ -811,8 +811,8 @@ async function handleTriggerTool(name, args2, deps) {
811
811
  switch (name) {
812
812
  // -----------------------------------------------------------------
813
813
  case "trigger-list": {
814
- const sql26 = 'SELECT slug, name FROM \\"Project\\" ORDER BY name';
815
- const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql26}" 2>/dev/null`;
814
+ const sql27 = 'SELECT slug, name FROM \\"Project\\" ORDER BY name';
815
+ const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql27}" 2>/dev/null`;
816
816
  const result = await sshExec2(conn, cmd, proxy);
817
817
  const output = result.stdout.trim();
818
818
  if (!output) {
@@ -990,9 +990,9 @@ ${raw2.substring(0, 500)}` }] };
990
990
  return { content: [{ type: "text", text: `No environment variables for ${project}/${env}.` }] };
991
991
  }
992
992
  const lines = vars.map((v) => `${v.isSecret ? "[secret]" : " "} ${v.name}`).sort();
993
- const text9 = `Env vars for ${project}/${env} (${vars.length}) \u2014 values hidden, use action="get" with a key:
993
+ const text11 = `Env vars for ${project}/${env} (${vars.length}) \u2014 values hidden, use action="get" with a key:
994
994
  ` + "-".repeat(50) + "\n" + lines.join("\n");
995
- return { content: [{ type: "text", text: text9 }] };
995
+ return { content: [{ type: "text", text: text11 }] };
996
996
  }
997
997
  if (action === "get") {
998
998
  const key2 = String(args2.key ?? "");
@@ -1079,9 +1079,9 @@ async function fetchAndFormatRun(conn, proxy, sshExec2, instance, runId) {
1079
1079
  return { content: [{ type: "text", text: `Invalid API response:
1080
1080
  ${rawJson.substring(0, 500)}` }] };
1081
1081
  }
1082
- let text9 = formatRunDetail(run);
1083
- if (logs) text9 += "\n\n--- Logs ---\n" + logs;
1084
- return { content: [{ type: "text", text: text9 }] };
1082
+ let text11 = formatRunDetail(run);
1083
+ if (logs) text11 += "\n\n--- Logs ---\n" + logs;
1084
+ return { content: [{ type: "text", text: text11 }] };
1085
1085
  }
1086
1086
  async function waitForCompletion(conn, proxy, sshExec2, instance, runId, waitSeconds) {
1087
1087
  const pollInterval = 3e3;
@@ -1103,10 +1103,10 @@ async function waitForCompletion(conn, proxy, sshExec2, instance, runId, waitSec
1103
1103
  continue;
1104
1104
  }
1105
1105
  if (TERMINAL_STATUSES.has(run.status)) {
1106
- let text9 = formatRunDetail(run);
1106
+ let text11 = formatRunDetail(run);
1107
1107
  const logs = await fetchRunLogs(runId, conn, proxy, sshExec2);
1108
- if (logs) text9 += "\n\n--- Logs ---\n" + logs;
1109
- return { content: [{ type: "text", text: text9 }] };
1108
+ if (logs) text11 += "\n\n--- Logs ---\n" + logs;
1109
+ return { content: [{ type: "text", text: text11 }] };
1110
1110
  }
1111
1111
  }
1112
1112
  return {
@@ -1968,7 +1968,7 @@ var ZodType = class {
1968
1968
  const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));
1969
1969
  return handleResult(ctx, result);
1970
1970
  }
1971
- refine(check2, message) {
1971
+ refine(check3, message) {
1972
1972
  const getIssueProperties = (val) => {
1973
1973
  if (typeof message === "string" || typeof message === "undefined") {
1974
1974
  return { message };
@@ -1979,7 +1979,7 @@ var ZodType = class {
1979
1979
  }
1980
1980
  };
1981
1981
  return this._refinement((val, ctx) => {
1982
- const result = check2(val);
1982
+ const result = check3(val);
1983
1983
  const setError = () => ctx.addIssue({
1984
1984
  code: ZodIssueCode.custom,
1985
1985
  ...getIssueProperties(val)
@@ -2002,9 +2002,9 @@ var ZodType = class {
2002
2002
  }
2003
2003
  });
2004
2004
  }
2005
- refinement(check2, refinementData) {
2005
+ refinement(check3, refinementData) {
2006
2006
  return this._refinement((val, ctx) => {
2007
- if (!check2(val)) {
2007
+ if (!check3(val)) {
2008
2008
  ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData);
2009
2009
  return false;
2010
2010
  } else {
@@ -2224,70 +2224,70 @@ var ZodString = class _ZodString extends ZodType {
2224
2224
  }
2225
2225
  const status = new ParseStatus();
2226
2226
  let ctx = void 0;
2227
- for (const check2 of this._def.checks) {
2228
- if (check2.kind === "min") {
2229
- if (input.data.length < check2.value) {
2227
+ for (const check3 of this._def.checks) {
2228
+ if (check3.kind === "min") {
2229
+ if (input.data.length < check3.value) {
2230
2230
  ctx = this._getOrReturnCtx(input, ctx);
2231
2231
  addIssueToContext(ctx, {
2232
2232
  code: ZodIssueCode.too_small,
2233
- minimum: check2.value,
2233
+ minimum: check3.value,
2234
2234
  type: "string",
2235
2235
  inclusive: true,
2236
2236
  exact: false,
2237
- message: check2.message
2237
+ message: check3.message
2238
2238
  });
2239
2239
  status.dirty();
2240
2240
  }
2241
- } else if (check2.kind === "max") {
2242
- if (input.data.length > check2.value) {
2241
+ } else if (check3.kind === "max") {
2242
+ if (input.data.length > check3.value) {
2243
2243
  ctx = this._getOrReturnCtx(input, ctx);
2244
2244
  addIssueToContext(ctx, {
2245
2245
  code: ZodIssueCode.too_big,
2246
- maximum: check2.value,
2246
+ maximum: check3.value,
2247
2247
  type: "string",
2248
2248
  inclusive: true,
2249
2249
  exact: false,
2250
- message: check2.message
2250
+ message: check3.message
2251
2251
  });
2252
2252
  status.dirty();
2253
2253
  }
2254
- } else if (check2.kind === "length") {
2255
- const tooBig = input.data.length > check2.value;
2256
- const tooSmall = input.data.length < check2.value;
2254
+ } else if (check3.kind === "length") {
2255
+ const tooBig = input.data.length > check3.value;
2256
+ const tooSmall = input.data.length < check3.value;
2257
2257
  if (tooBig || tooSmall) {
2258
2258
  ctx = this._getOrReturnCtx(input, ctx);
2259
2259
  if (tooBig) {
2260
2260
  addIssueToContext(ctx, {
2261
2261
  code: ZodIssueCode.too_big,
2262
- maximum: check2.value,
2262
+ maximum: check3.value,
2263
2263
  type: "string",
2264
2264
  inclusive: true,
2265
2265
  exact: true,
2266
- message: check2.message
2266
+ message: check3.message
2267
2267
  });
2268
2268
  } else if (tooSmall) {
2269
2269
  addIssueToContext(ctx, {
2270
2270
  code: ZodIssueCode.too_small,
2271
- minimum: check2.value,
2271
+ minimum: check3.value,
2272
2272
  type: "string",
2273
2273
  inclusive: true,
2274
2274
  exact: true,
2275
- message: check2.message
2275
+ message: check3.message
2276
2276
  });
2277
2277
  }
2278
2278
  status.dirty();
2279
2279
  }
2280
- } else if (check2.kind === "email") {
2280
+ } else if (check3.kind === "email") {
2281
2281
  if (!emailRegex.test(input.data)) {
2282
2282
  ctx = this._getOrReturnCtx(input, ctx);
2283
2283
  addIssueToContext(ctx, {
2284
2284
  validation: "email",
2285
2285
  code: ZodIssueCode.invalid_string,
2286
- message: check2.message
2286
+ message: check3.message
2287
2287
  });
2288
2288
  status.dirty();
2289
2289
  }
2290
- } else if (check2.kind === "emoji") {
2290
+ } else if (check3.kind === "emoji") {
2291
2291
  if (!emojiRegex) {
2292
2292
  emojiRegex = new RegExp(_emojiRegex, "u");
2293
2293
  }
@@ -2296,61 +2296,61 @@ var ZodString = class _ZodString extends ZodType {
2296
2296
  addIssueToContext(ctx, {
2297
2297
  validation: "emoji",
2298
2298
  code: ZodIssueCode.invalid_string,
2299
- message: check2.message
2299
+ message: check3.message
2300
2300
  });
2301
2301
  status.dirty();
2302
2302
  }
2303
- } else if (check2.kind === "uuid") {
2303
+ } else if (check3.kind === "uuid") {
2304
2304
  if (!uuidRegex.test(input.data)) {
2305
2305
  ctx = this._getOrReturnCtx(input, ctx);
2306
2306
  addIssueToContext(ctx, {
2307
2307
  validation: "uuid",
2308
2308
  code: ZodIssueCode.invalid_string,
2309
- message: check2.message
2309
+ message: check3.message
2310
2310
  });
2311
2311
  status.dirty();
2312
2312
  }
2313
- } else if (check2.kind === "nanoid") {
2313
+ } else if (check3.kind === "nanoid") {
2314
2314
  if (!nanoidRegex.test(input.data)) {
2315
2315
  ctx = this._getOrReturnCtx(input, ctx);
2316
2316
  addIssueToContext(ctx, {
2317
2317
  validation: "nanoid",
2318
2318
  code: ZodIssueCode.invalid_string,
2319
- message: check2.message
2319
+ message: check3.message
2320
2320
  });
2321
2321
  status.dirty();
2322
2322
  }
2323
- } else if (check2.kind === "cuid") {
2323
+ } else if (check3.kind === "cuid") {
2324
2324
  if (!cuidRegex.test(input.data)) {
2325
2325
  ctx = this._getOrReturnCtx(input, ctx);
2326
2326
  addIssueToContext(ctx, {
2327
2327
  validation: "cuid",
2328
2328
  code: ZodIssueCode.invalid_string,
2329
- message: check2.message
2329
+ message: check3.message
2330
2330
  });
2331
2331
  status.dirty();
2332
2332
  }
2333
- } else if (check2.kind === "cuid2") {
2333
+ } else if (check3.kind === "cuid2") {
2334
2334
  if (!cuid2Regex.test(input.data)) {
2335
2335
  ctx = this._getOrReturnCtx(input, ctx);
2336
2336
  addIssueToContext(ctx, {
2337
2337
  validation: "cuid2",
2338
2338
  code: ZodIssueCode.invalid_string,
2339
- message: check2.message
2339
+ message: check3.message
2340
2340
  });
2341
2341
  status.dirty();
2342
2342
  }
2343
- } else if (check2.kind === "ulid") {
2343
+ } else if (check3.kind === "ulid") {
2344
2344
  if (!ulidRegex.test(input.data)) {
2345
2345
  ctx = this._getOrReturnCtx(input, ctx);
2346
2346
  addIssueToContext(ctx, {
2347
2347
  validation: "ulid",
2348
2348
  code: ZodIssueCode.invalid_string,
2349
- message: check2.message
2349
+ message: check3.message
2350
2350
  });
2351
2351
  status.dirty();
2352
2352
  }
2353
- } else if (check2.kind === "url") {
2353
+ } else if (check3.kind === "url") {
2354
2354
  try {
2355
2355
  new URL(input.data);
2356
2356
  } catch {
@@ -2358,153 +2358,153 @@ var ZodString = class _ZodString extends ZodType {
2358
2358
  addIssueToContext(ctx, {
2359
2359
  validation: "url",
2360
2360
  code: ZodIssueCode.invalid_string,
2361
- message: check2.message
2361
+ message: check3.message
2362
2362
  });
2363
2363
  status.dirty();
2364
2364
  }
2365
- } else if (check2.kind === "regex") {
2366
- check2.regex.lastIndex = 0;
2367
- const testResult = check2.regex.test(input.data);
2365
+ } else if (check3.kind === "regex") {
2366
+ check3.regex.lastIndex = 0;
2367
+ const testResult = check3.regex.test(input.data);
2368
2368
  if (!testResult) {
2369
2369
  ctx = this._getOrReturnCtx(input, ctx);
2370
2370
  addIssueToContext(ctx, {
2371
2371
  validation: "regex",
2372
2372
  code: ZodIssueCode.invalid_string,
2373
- message: check2.message
2373
+ message: check3.message
2374
2374
  });
2375
2375
  status.dirty();
2376
2376
  }
2377
- } else if (check2.kind === "trim") {
2377
+ } else if (check3.kind === "trim") {
2378
2378
  input.data = input.data.trim();
2379
- } else if (check2.kind === "includes") {
2380
- if (!input.data.includes(check2.value, check2.position)) {
2379
+ } else if (check3.kind === "includes") {
2380
+ if (!input.data.includes(check3.value, check3.position)) {
2381
2381
  ctx = this._getOrReturnCtx(input, ctx);
2382
2382
  addIssueToContext(ctx, {
2383
2383
  code: ZodIssueCode.invalid_string,
2384
- validation: { includes: check2.value, position: check2.position },
2385
- message: check2.message
2384
+ validation: { includes: check3.value, position: check3.position },
2385
+ message: check3.message
2386
2386
  });
2387
2387
  status.dirty();
2388
2388
  }
2389
- } else if (check2.kind === "toLowerCase") {
2389
+ } else if (check3.kind === "toLowerCase") {
2390
2390
  input.data = input.data.toLowerCase();
2391
- } else if (check2.kind === "toUpperCase") {
2391
+ } else if (check3.kind === "toUpperCase") {
2392
2392
  input.data = input.data.toUpperCase();
2393
- } else if (check2.kind === "startsWith") {
2394
- if (!input.data.startsWith(check2.value)) {
2393
+ } else if (check3.kind === "startsWith") {
2394
+ if (!input.data.startsWith(check3.value)) {
2395
2395
  ctx = this._getOrReturnCtx(input, ctx);
2396
2396
  addIssueToContext(ctx, {
2397
2397
  code: ZodIssueCode.invalid_string,
2398
- validation: { startsWith: check2.value },
2399
- message: check2.message
2398
+ validation: { startsWith: check3.value },
2399
+ message: check3.message
2400
2400
  });
2401
2401
  status.dirty();
2402
2402
  }
2403
- } else if (check2.kind === "endsWith") {
2404
- if (!input.data.endsWith(check2.value)) {
2403
+ } else if (check3.kind === "endsWith") {
2404
+ if (!input.data.endsWith(check3.value)) {
2405
2405
  ctx = this._getOrReturnCtx(input, ctx);
2406
2406
  addIssueToContext(ctx, {
2407
2407
  code: ZodIssueCode.invalid_string,
2408
- validation: { endsWith: check2.value },
2409
- message: check2.message
2408
+ validation: { endsWith: check3.value },
2409
+ message: check3.message
2410
2410
  });
2411
2411
  status.dirty();
2412
2412
  }
2413
- } else if (check2.kind === "datetime") {
2414
- const regex = datetimeRegex(check2);
2413
+ } else if (check3.kind === "datetime") {
2414
+ const regex = datetimeRegex(check3);
2415
2415
  if (!regex.test(input.data)) {
2416
2416
  ctx = this._getOrReturnCtx(input, ctx);
2417
2417
  addIssueToContext(ctx, {
2418
2418
  code: ZodIssueCode.invalid_string,
2419
2419
  validation: "datetime",
2420
- message: check2.message
2420
+ message: check3.message
2421
2421
  });
2422
2422
  status.dirty();
2423
2423
  }
2424
- } else if (check2.kind === "date") {
2424
+ } else if (check3.kind === "date") {
2425
2425
  const regex = dateRegex;
2426
2426
  if (!regex.test(input.data)) {
2427
2427
  ctx = this._getOrReturnCtx(input, ctx);
2428
2428
  addIssueToContext(ctx, {
2429
2429
  code: ZodIssueCode.invalid_string,
2430
2430
  validation: "date",
2431
- message: check2.message
2431
+ message: check3.message
2432
2432
  });
2433
2433
  status.dirty();
2434
2434
  }
2435
- } else if (check2.kind === "time") {
2436
- const regex = timeRegex(check2);
2435
+ } else if (check3.kind === "time") {
2436
+ const regex = timeRegex(check3);
2437
2437
  if (!regex.test(input.data)) {
2438
2438
  ctx = this._getOrReturnCtx(input, ctx);
2439
2439
  addIssueToContext(ctx, {
2440
2440
  code: ZodIssueCode.invalid_string,
2441
2441
  validation: "time",
2442
- message: check2.message
2442
+ message: check3.message
2443
2443
  });
2444
2444
  status.dirty();
2445
2445
  }
2446
- } else if (check2.kind === "duration") {
2446
+ } else if (check3.kind === "duration") {
2447
2447
  if (!durationRegex.test(input.data)) {
2448
2448
  ctx = this._getOrReturnCtx(input, ctx);
2449
2449
  addIssueToContext(ctx, {
2450
2450
  validation: "duration",
2451
2451
  code: ZodIssueCode.invalid_string,
2452
- message: check2.message
2452
+ message: check3.message
2453
2453
  });
2454
2454
  status.dirty();
2455
2455
  }
2456
- } else if (check2.kind === "ip") {
2457
- if (!isValidIP(input.data, check2.version)) {
2456
+ } else if (check3.kind === "ip") {
2457
+ if (!isValidIP(input.data, check3.version)) {
2458
2458
  ctx = this._getOrReturnCtx(input, ctx);
2459
2459
  addIssueToContext(ctx, {
2460
2460
  validation: "ip",
2461
2461
  code: ZodIssueCode.invalid_string,
2462
- message: check2.message
2462
+ message: check3.message
2463
2463
  });
2464
2464
  status.dirty();
2465
2465
  }
2466
- } else if (check2.kind === "jwt") {
2467
- if (!isValidJWT(input.data, check2.alg)) {
2466
+ } else if (check3.kind === "jwt") {
2467
+ if (!isValidJWT(input.data, check3.alg)) {
2468
2468
  ctx = this._getOrReturnCtx(input, ctx);
2469
2469
  addIssueToContext(ctx, {
2470
2470
  validation: "jwt",
2471
2471
  code: ZodIssueCode.invalid_string,
2472
- message: check2.message
2472
+ message: check3.message
2473
2473
  });
2474
2474
  status.dirty();
2475
2475
  }
2476
- } else if (check2.kind === "cidr") {
2477
- if (!isValidCidr(input.data, check2.version)) {
2476
+ } else if (check3.kind === "cidr") {
2477
+ if (!isValidCidr(input.data, check3.version)) {
2478
2478
  ctx = this._getOrReturnCtx(input, ctx);
2479
2479
  addIssueToContext(ctx, {
2480
2480
  validation: "cidr",
2481
2481
  code: ZodIssueCode.invalid_string,
2482
- message: check2.message
2482
+ message: check3.message
2483
2483
  });
2484
2484
  status.dirty();
2485
2485
  }
2486
- } else if (check2.kind === "base64") {
2486
+ } else if (check3.kind === "base64") {
2487
2487
  if (!base64Regex.test(input.data)) {
2488
2488
  ctx = this._getOrReturnCtx(input, ctx);
2489
2489
  addIssueToContext(ctx, {
2490
2490
  validation: "base64",
2491
2491
  code: ZodIssueCode.invalid_string,
2492
- message: check2.message
2492
+ message: check3.message
2493
2493
  });
2494
2494
  status.dirty();
2495
2495
  }
2496
- } else if (check2.kind === "base64url") {
2496
+ } else if (check3.kind === "base64url") {
2497
2497
  if (!base64urlRegex.test(input.data)) {
2498
2498
  ctx = this._getOrReturnCtx(input, ctx);
2499
2499
  addIssueToContext(ctx, {
2500
2500
  validation: "base64url",
2501
2501
  code: ZodIssueCode.invalid_string,
2502
- message: check2.message
2502
+ message: check3.message
2503
2503
  });
2504
2504
  status.dirty();
2505
2505
  }
2506
2506
  } else {
2507
- util.assertNever(check2);
2507
+ util.assertNever(check3);
2508
2508
  }
2509
2509
  }
2510
2510
  return { status: status.value, value: input.data };
@@ -2516,10 +2516,10 @@ var ZodString = class _ZodString extends ZodType {
2516
2516
  ...errorUtil.errToObj(message)
2517
2517
  });
2518
2518
  }
2519
- _addCheck(check2) {
2519
+ _addCheck(check3) {
2520
2520
  return new _ZodString({
2521
2521
  ...this._def,
2522
- checks: [...this._def.checks, check2]
2522
+ checks: [...this._def.checks, check3]
2523
2523
  });
2524
2524
  }
2525
2525
  email(message) {
@@ -2784,67 +2784,67 @@ var ZodNumber = class _ZodNumber extends ZodType {
2784
2784
  }
2785
2785
  let ctx = void 0;
2786
2786
  const status = new ParseStatus();
2787
- for (const check2 of this._def.checks) {
2788
- if (check2.kind === "int") {
2787
+ for (const check3 of this._def.checks) {
2788
+ if (check3.kind === "int") {
2789
2789
  if (!util.isInteger(input.data)) {
2790
2790
  ctx = this._getOrReturnCtx(input, ctx);
2791
2791
  addIssueToContext(ctx, {
2792
2792
  code: ZodIssueCode.invalid_type,
2793
2793
  expected: "integer",
2794
2794
  received: "float",
2795
- message: check2.message
2795
+ message: check3.message
2796
2796
  });
2797
2797
  status.dirty();
2798
2798
  }
2799
- } else if (check2.kind === "min") {
2800
- const tooSmall = check2.inclusive ? input.data < check2.value : input.data <= check2.value;
2799
+ } else if (check3.kind === "min") {
2800
+ const tooSmall = check3.inclusive ? input.data < check3.value : input.data <= check3.value;
2801
2801
  if (tooSmall) {
2802
2802
  ctx = this._getOrReturnCtx(input, ctx);
2803
2803
  addIssueToContext(ctx, {
2804
2804
  code: ZodIssueCode.too_small,
2805
- minimum: check2.value,
2805
+ minimum: check3.value,
2806
2806
  type: "number",
2807
- inclusive: check2.inclusive,
2807
+ inclusive: check3.inclusive,
2808
2808
  exact: false,
2809
- message: check2.message
2809
+ message: check3.message
2810
2810
  });
2811
2811
  status.dirty();
2812
2812
  }
2813
- } else if (check2.kind === "max") {
2814
- const tooBig = check2.inclusive ? input.data > check2.value : input.data >= check2.value;
2813
+ } else if (check3.kind === "max") {
2814
+ const tooBig = check3.inclusive ? input.data > check3.value : input.data >= check3.value;
2815
2815
  if (tooBig) {
2816
2816
  ctx = this._getOrReturnCtx(input, ctx);
2817
2817
  addIssueToContext(ctx, {
2818
2818
  code: ZodIssueCode.too_big,
2819
- maximum: check2.value,
2819
+ maximum: check3.value,
2820
2820
  type: "number",
2821
- inclusive: check2.inclusive,
2821
+ inclusive: check3.inclusive,
2822
2822
  exact: false,
2823
- message: check2.message
2823
+ message: check3.message
2824
2824
  });
2825
2825
  status.dirty();
2826
2826
  }
2827
- } else if (check2.kind === "multipleOf") {
2828
- if (floatSafeRemainder(input.data, check2.value) !== 0) {
2827
+ } else if (check3.kind === "multipleOf") {
2828
+ if (floatSafeRemainder(input.data, check3.value) !== 0) {
2829
2829
  ctx = this._getOrReturnCtx(input, ctx);
2830
2830
  addIssueToContext(ctx, {
2831
2831
  code: ZodIssueCode.not_multiple_of,
2832
- multipleOf: check2.value,
2833
- message: check2.message
2832
+ multipleOf: check3.value,
2833
+ message: check3.message
2834
2834
  });
2835
2835
  status.dirty();
2836
2836
  }
2837
- } else if (check2.kind === "finite") {
2837
+ } else if (check3.kind === "finite") {
2838
2838
  if (!Number.isFinite(input.data)) {
2839
2839
  ctx = this._getOrReturnCtx(input, ctx);
2840
2840
  addIssueToContext(ctx, {
2841
2841
  code: ZodIssueCode.not_finite,
2842
- message: check2.message
2842
+ message: check3.message
2843
2843
  });
2844
2844
  status.dirty();
2845
2845
  }
2846
2846
  } else {
2847
- util.assertNever(check2);
2847
+ util.assertNever(check3);
2848
2848
  }
2849
2849
  }
2850
2850
  return { status: status.value, value: input.data };
@@ -2875,10 +2875,10 @@ var ZodNumber = class _ZodNumber extends ZodType {
2875
2875
  ]
2876
2876
  });
2877
2877
  }
2878
- _addCheck(check2) {
2878
+ _addCheck(check3) {
2879
2879
  return new _ZodNumber({
2880
2880
  ...this._def,
2881
- checks: [...this._def.checks, check2]
2881
+ checks: [...this._def.checks, check3]
2882
2882
  });
2883
2883
  }
2884
2884
  int(message) {
@@ -3013,45 +3013,45 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
3013
3013
  }
3014
3014
  let ctx = void 0;
3015
3015
  const status = new ParseStatus();
3016
- for (const check2 of this._def.checks) {
3017
- if (check2.kind === "min") {
3018
- const tooSmall = check2.inclusive ? input.data < check2.value : input.data <= check2.value;
3016
+ for (const check3 of this._def.checks) {
3017
+ if (check3.kind === "min") {
3018
+ const tooSmall = check3.inclusive ? input.data < check3.value : input.data <= check3.value;
3019
3019
  if (tooSmall) {
3020
3020
  ctx = this._getOrReturnCtx(input, ctx);
3021
3021
  addIssueToContext(ctx, {
3022
3022
  code: ZodIssueCode.too_small,
3023
3023
  type: "bigint",
3024
- minimum: check2.value,
3025
- inclusive: check2.inclusive,
3026
- message: check2.message
3024
+ minimum: check3.value,
3025
+ inclusive: check3.inclusive,
3026
+ message: check3.message
3027
3027
  });
3028
3028
  status.dirty();
3029
3029
  }
3030
- } else if (check2.kind === "max") {
3031
- const tooBig = check2.inclusive ? input.data > check2.value : input.data >= check2.value;
3030
+ } else if (check3.kind === "max") {
3031
+ const tooBig = check3.inclusive ? input.data > check3.value : input.data >= check3.value;
3032
3032
  if (tooBig) {
3033
3033
  ctx = this._getOrReturnCtx(input, ctx);
3034
3034
  addIssueToContext(ctx, {
3035
3035
  code: ZodIssueCode.too_big,
3036
3036
  type: "bigint",
3037
- maximum: check2.value,
3038
- inclusive: check2.inclusive,
3039
- message: check2.message
3037
+ maximum: check3.value,
3038
+ inclusive: check3.inclusive,
3039
+ message: check3.message
3040
3040
  });
3041
3041
  status.dirty();
3042
3042
  }
3043
- } else if (check2.kind === "multipleOf") {
3044
- if (input.data % check2.value !== BigInt(0)) {
3043
+ } else if (check3.kind === "multipleOf") {
3044
+ if (input.data % check3.value !== BigInt(0)) {
3045
3045
  ctx = this._getOrReturnCtx(input, ctx);
3046
3046
  addIssueToContext(ctx, {
3047
3047
  code: ZodIssueCode.not_multiple_of,
3048
- multipleOf: check2.value,
3049
- message: check2.message
3048
+ multipleOf: check3.value,
3049
+ message: check3.message
3050
3050
  });
3051
3051
  status.dirty();
3052
3052
  }
3053
3053
  } else {
3054
- util.assertNever(check2);
3054
+ util.assertNever(check3);
3055
3055
  }
3056
3056
  }
3057
3057
  return { status: status.value, value: input.data };
@@ -3091,10 +3091,10 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
3091
3091
  ]
3092
3092
  });
3093
3093
  }
3094
- _addCheck(check2) {
3094
+ _addCheck(check3) {
3095
3095
  return new _ZodBigInt({
3096
3096
  ...this._def,
3097
- checks: [...this._def.checks, check2]
3097
+ checks: [...this._def.checks, check3]
3098
3098
  });
3099
3099
  }
3100
3100
  positive(message) {
@@ -3214,35 +3214,35 @@ var ZodDate = class _ZodDate extends ZodType {
3214
3214
  }
3215
3215
  const status = new ParseStatus();
3216
3216
  let ctx = void 0;
3217
- for (const check2 of this._def.checks) {
3218
- if (check2.kind === "min") {
3219
- if (input.data.getTime() < check2.value) {
3217
+ for (const check3 of this._def.checks) {
3218
+ if (check3.kind === "min") {
3219
+ if (input.data.getTime() < check3.value) {
3220
3220
  ctx = this._getOrReturnCtx(input, ctx);
3221
3221
  addIssueToContext(ctx, {
3222
3222
  code: ZodIssueCode.too_small,
3223
- message: check2.message,
3223
+ message: check3.message,
3224
3224
  inclusive: true,
3225
3225
  exact: false,
3226
- minimum: check2.value,
3226
+ minimum: check3.value,
3227
3227
  type: "date"
3228
3228
  });
3229
3229
  status.dirty();
3230
3230
  }
3231
- } else if (check2.kind === "max") {
3232
- if (input.data.getTime() > check2.value) {
3231
+ } else if (check3.kind === "max") {
3232
+ if (input.data.getTime() > check3.value) {
3233
3233
  ctx = this._getOrReturnCtx(input, ctx);
3234
3234
  addIssueToContext(ctx, {
3235
3235
  code: ZodIssueCode.too_big,
3236
- message: check2.message,
3236
+ message: check3.message,
3237
3237
  inclusive: true,
3238
3238
  exact: false,
3239
- maximum: check2.value,
3239
+ maximum: check3.value,
3240
3240
  type: "date"
3241
3241
  });
3242
3242
  status.dirty();
3243
3243
  }
3244
3244
  } else {
3245
- util.assertNever(check2);
3245
+ util.assertNever(check3);
3246
3246
  }
3247
3247
  }
3248
3248
  return {
@@ -3250,10 +3250,10 @@ var ZodDate = class _ZodDate extends ZodType {
3250
3250
  value: new Date(input.data.getTime())
3251
3251
  };
3252
3252
  }
3253
- _addCheck(check2) {
3253
+ _addCheck(check3) {
3254
3254
  return new _ZodDate({
3255
3255
  ...this._def,
3256
- checks: [...this._def.checks, check2]
3256
+ checks: [...this._def.checks, check3]
3257
3257
  });
3258
3258
  }
3259
3259
  min(minDate, message) {
@@ -3793,10 +3793,10 @@ var ZodObject = class _ZodObject extends ZodType {
3793
3793
  // }) as any;
3794
3794
  // return merged;
3795
3795
  // }
3796
- catchall(index7) {
3796
+ catchall(index8) {
3797
3797
  return new _ZodObject({
3798
3798
  ...this._def,
3799
- catchall: index7
3799
+ catchall: index8
3800
3800
  });
3801
3801
  }
3802
3802
  pick(mask) {
@@ -4114,9 +4114,9 @@ function mergeValues(a, b) {
4114
4114
  return { valid: false };
4115
4115
  }
4116
4116
  const newArray = [];
4117
- for (let index7 = 0; index7 < a.length; index7++) {
4118
- const itemA = a[index7];
4119
- const itemB = b[index7];
4117
+ for (let index8 = 0; index8 < a.length; index8++) {
4118
+ const itemA = a[index8];
4119
+ const itemB = b[index8];
4120
4120
  const sharedValue = mergeValues(itemA, itemB);
4121
4121
  if (!sharedValue.valid) {
4122
4122
  return { valid: false };
@@ -4322,10 +4322,10 @@ var ZodMap = class extends ZodType {
4322
4322
  }
4323
4323
  const keyType = this._def.keyType;
4324
4324
  const valueType = this._def.valueType;
4325
- const pairs = [...ctx.data.entries()].map(([key, value], index7) => {
4325
+ const pairs = [...ctx.data.entries()].map(([key, value], index8) => {
4326
4326
  return {
4327
- key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index7, "key"])),
4328
- value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index7, "value"]))
4327
+ key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index8, "key"])),
4328
+ value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index8, "value"]))
4329
4329
  };
4330
4330
  });
4331
4331
  if (ctx.common.async) {
@@ -5113,10 +5113,10 @@ function cleanParams(params, data) {
5113
5113
  const p2 = typeof p === "string" ? { message: p } : p;
5114
5114
  return p2;
5115
5115
  }
5116
- function custom(check2, _params = {}, fatal) {
5117
- if (check2)
5116
+ function custom(check3, _params = {}, fatal) {
5117
+ if (check3)
5118
5118
  return ZodAny.create().superRefine((data, ctx) => {
5119
- const r = check2(data);
5119
+ const r = check3(data);
5120
5120
  if (r instanceof Promise) {
5121
5121
  return r.then((r2) => {
5122
5122
  if (!r2) {
@@ -6123,7 +6123,7 @@ pgTable(
6123
6123
  index("dns_migration_mailbox_migration_idx").on(table.migrationId)
6124
6124
  ]
6125
6125
  );
6126
- pgTable(
6126
+ var githubToken = pgTable(
6127
6127
  "github_token",
6128
6128
  {
6129
6129
  id: uuid("id").primaryKey().defaultRandom(),
@@ -6253,6 +6253,96 @@ pgTable(
6253
6253
  index("content_ingestion_runs_project_idx").on(table.projectKey)
6254
6254
  ]
6255
6255
  );
6256
+ pgTable(
6257
+ "refront_source_sync_state",
6258
+ {
6259
+ id: text("id").primaryKey().default("singleton"),
6260
+ boilerHeadSha: text("boiler_head_sha"),
6261
+ boilerTreeHash: text("boiler_tree_hash"),
6262
+ webHeadSha: text("web_head_sha"),
6263
+ webTreeHash: text("web_tree_hash"),
6264
+ status: text("status").notNull().default("idle"),
6265
+ direction: text("direction"),
6266
+ prRepoFullName: text("pr_repo_full_name"),
6267
+ prNumber: integer("pr_number"),
6268
+ prUrl: text("pr_url"),
6269
+ prBranch: text("pr_branch"),
6270
+ prExpectedTreeHash: text("pr_expected_tree_hash"),
6271
+ pendingBoilerHeadSha: text("pending_boiler_head_sha"),
6272
+ pendingBoilerTreeHash: text("pending_boiler_tree_hash"),
6273
+ pendingWebHeadSha: text("pending_web_head_sha"),
6274
+ pendingWebTreeHash: text("pending_web_tree_hash"),
6275
+ consumedWebHeadSha: text("consumed_web_head_sha"),
6276
+ consumedWebTreeHash: text("consumed_web_tree_hash"),
6277
+ conflictAttemptCount: integer("conflict_attempt_count").notNull().default(0),
6278
+ errorMessage: text("error_message"),
6279
+ lastCheckedAt: timestamp("last_checked_at", { withTimezone: true }),
6280
+ syncStartedAt: timestamp("sync_started_at", { withTimezone: true }),
6281
+ completedAt: timestamp("completed_at", { withTimezone: true }),
6282
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
6283
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
6284
+ },
6285
+ (table) => [
6286
+ check(
6287
+ "refront_source_sync_state_singleton_check",
6288
+ sql`${table.id} = 'singleton'`
6289
+ )
6290
+ ]
6291
+ );
6292
+ var repoFunnel = pgTable(
6293
+ "repo_funnel",
6294
+ {
6295
+ id: uuid("id").primaryKey().defaultRandom(),
6296
+ name: text("name").notNull(),
6297
+ enabled: boolean("enabled").notNull().default(true),
6298
+ sourceRepoFullName: text("source_repo_full_name").notNull(),
6299
+ sourceBranch: text("source_branch").notNull().default("main"),
6300
+ targetRepoFullName: text("target_repo_full_name").notNull(),
6301
+ targetBranch: text("target_branch").notNull().default("main"),
6302
+ githubTokenId: uuid("github_token_id"),
6303
+ sshServerId: uuid("ssh_server_id").notNull(),
6304
+ lastSyncedSha: text("last_synced_sha"),
6305
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
6306
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
6307
+ },
6308
+ (table) => [
6309
+ index("repo_funnel_source_idx").on(
6310
+ table.sourceRepoFullName,
6311
+ table.sourceBranch
6312
+ ),
6313
+ index("repo_funnel_enabled_idx").on(table.enabled),
6314
+ foreignKey({
6315
+ columns: [table.githubTokenId],
6316
+ foreignColumns: [githubToken.id],
6317
+ name: "repo_funnel_github_token_id_fk"
6318
+ }).onDelete("set null"),
6319
+ foreignKey({
6320
+ columns: [table.sshServerId],
6321
+ foreignColumns: [managedServer.id],
6322
+ name: "repo_funnel_ssh_server_id_fk"
6323
+ }).onDelete("restrict")
6324
+ ]
6325
+ );
6326
+ pgTable(
6327
+ "repo_funnel_log",
6328
+ {
6329
+ id: uuid("id").primaryKey().defaultRandom(),
6330
+ repoFunnelId: uuid("repo_funnel_id").notNull(),
6331
+ sourceCommitSha: text("source_commit_sha").notNull(),
6332
+ status: text("status").notNull().default("pending"),
6333
+ errorMessage: text("error_message"),
6334
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
6335
+ },
6336
+ (table) => [
6337
+ index("repo_funnel_log_funnel_idx").on(table.repoFunnelId),
6338
+ index("repo_funnel_log_status_idx").on(table.status),
6339
+ foreignKey({
6340
+ columns: [table.repoFunnelId],
6341
+ foreignColumns: [repoFunnel.id],
6342
+ name: "repo_funnel_log_repo_funnel_id_fk"
6343
+ }).onDelete("cascade")
6344
+ ]
6345
+ );
6256
6346
  var GITHUB_API = "https://api.github.com";
6257
6347
  var ReleaseProfileQuickCreateError = class extends Error {
6258
6348
  constructor(message, code = "INTERNAL_SERVER_ERROR") {
@@ -6619,6 +6709,10 @@ async function updateReleaseProfileSettings(profileId, fields) {
6619
6709
  setExprs.push(sql`has_trigger_dev = ${fields.hasTriggerDev}`);
6620
6710
  if (fields.workDirectory !== void 0)
6621
6711
  setExprs.push(sql`work_directory = ${fields.workDirectory}`);
6712
+ if (fields.internalTicketProjectId !== void 0)
6713
+ setExprs.push(
6714
+ sql`internal_ticket_project_id = ${fields.internalTicketProjectId}`
6715
+ );
6622
6716
  if (setExprs.length === 0) {
6623
6717
  throw new ReleaseProfileQuickCreateError(
6624
6718
  "No fields to update",
@@ -7652,7 +7746,7 @@ function getEncryptionKey() {
7652
7746
  throw new Error("ENCRYPTION_KEY must be a 64-character hex string");
7653
7747
  return buf;
7654
7748
  }
7655
- function encrypt(text9) {
7749
+ function encrypt(text11) {
7656
7750
  const key = getEncryptionKey();
7657
7751
  const iv = randomBytes(ENC_IV_LENGTH);
7658
7752
  const cipher = createCipheriv(
@@ -7660,7 +7754,7 @@ function encrypt(text9) {
7660
7754
  new Uint8Array(key),
7661
7755
  new Uint8Array(iv)
7662
7756
  );
7663
- let encrypted = cipher.update(text9, "utf8", "hex");
7757
+ let encrypted = cipher.update(text11, "utf8", "hex");
7664
7758
  encrypted += cipher.final("hex");
7665
7759
  const authTag = cipher.getAuthTag();
7666
7760
  return Buffer.concat([
@@ -8380,10 +8474,10 @@ async function r2GetObjectRange(bucket, key, range) {
8380
8474
  const body = result.Body;
8381
8475
  if (!body?.transformToString)
8382
8476
  throw new Error("R2 returned no readable body");
8383
- const text9 = await body.transformToString();
8477
+ const text11 = await body.transformToString();
8384
8478
  const header = `# range: bytes ${range.offset}-${end} of ${size} (${effectiveLen} bytes)`;
8385
8479
  return `${header}
8386
- ${text9}`;
8480
+ ${text11}`;
8387
8481
  } catch (e) {
8388
8482
  throw r2WrapError(bucket, key, e);
8389
8483
  }
@@ -8746,15 +8840,15 @@ async function sftpRead(opts, filePath, proxy, options) {
8746
8840
  clearTimeout(timer);
8747
8841
  cleanup?.();
8748
8842
  cleanup = void 0;
8749
- const text9 = Buffer.concat(
8843
+ const text11 = Buffer.concat(
8750
8844
  chunks.map((ch) => new Uint8Array(ch))
8751
8845
  ).toString("utf-8");
8752
8846
  if (!isWholeFileRequest) {
8753
8847
  const header = `# range: bytes ${offset}-${offset + effectiveLen - 1} of ${total} (${effectiveLen} bytes)`;
8754
8848
  resolve(`${header}
8755
- ${text9}`);
8849
+ ${text11}`);
8756
8850
  } else {
8757
- resolve(text9);
8851
+ resolve(text11);
8758
8852
  }
8759
8853
  });
8760
8854
  rs.on("error", (e) => {
@@ -8901,11 +8995,11 @@ function getKnownContainers(serverId, maxAgeMs = 5 * 6e4) {
8901
8995
  if (Date.now() - e.capturedAt > maxAgeMs) return void 0;
8902
8996
  return e.names;
8903
8997
  }
8904
- function truncateForLLM(text9, maxBytes) {
8905
- const totalBytes = Buffer.byteLength(text9, "utf8");
8998
+ function truncateForLLM(text11, maxBytes) {
8999
+ const totalBytes = Buffer.byteLength(text11, "utf8");
8906
9000
  if (totalBytes <= maxBytes)
8907
- return { text: text9, truncated: false, totalBytes, shownBytes: totalBytes };
8908
- const buf = Buffer.from(text9, "utf8");
9001
+ return { text: text11, truncated: false, totalBytes, shownBytes: totalBytes };
9002
+ const buf = Buffer.from(text11, "utf8");
8909
9003
  let cut = maxBytes;
8910
9004
  while (cut > 0 && (buf[cut] & 192) === 128) cut--;
8911
9005
  const head = buf.subarray(0, cut).toString("utf8");
@@ -8936,10 +9030,10 @@ function postprocessResult(result, meta) {
8936
9030
  if (!result.content?.length) return result;
8937
9031
  if (RAW_JSON_TOOLS.has(meta.toolName)) return result;
8938
9032
  const block = result.content[0];
8939
- let text9 = String(block.text ?? "");
8940
- const trunc = truncateForLLM(text9, RESPONSE_MAX_BYTES);
9033
+ let text11 = String(block.text ?? "");
9034
+ const trunc = truncateForLLM(text11, RESPONSE_MAX_BYTES);
8941
9035
  if (trunc.truncated) {
8942
- text9 = trunc.text + "\n\n... " + buildTruncationHint(
9036
+ text11 = trunc.text + "\n\n... " + buildTruncationHint(
8943
9037
  meta.toolName,
8944
9038
  meta.args,
8945
9039
  trunc.totalBytes,
@@ -8953,11 +9047,11 @@ function postprocessResult(result, meta) {
8953
9047
  const parts = [`took ${tookStr}`, sizeStr];
8954
9048
  if (meta.serverIdLabel) parts.push(`server: ${meta.serverIdLabel}`);
8955
9049
  if (meta.cached) parts.push("cached");
8956
- text9 = `${text9}
9050
+ text11 = `${text11}
8957
9051
 
8958
9052
  [${parts.join(", ")}]`;
8959
9053
  }
8960
- return { ...result, content: [{ ...block, text: text9 }] };
9054
+ return { ...result, content: [{ ...block, text: text11 }] };
8961
9055
  }
8962
9056
  function buildPipelineScript(commands, shell, marker, stopOnError) {
8963
9057
  if (shell === "powershell") {
@@ -9743,11 +9837,11 @@ CREATE TABLE IF NOT EXISTS _mcp_migrations (
9743
9837
  applied_by TEXT
9744
9838
  );
9745
9839
  `.trim();
9746
- function normaliseMigrationSql(sql26) {
9747
- return sql26.replace(/\r\n/g, "\n").trim() + "\n";
9840
+ function normaliseMigrationSql(sql27) {
9841
+ return sql27.replace(/\r\n/g, "\n").trim() + "\n";
9748
9842
  }
9749
- function migrationSha256(sql26) {
9750
- return createHash("sha256").update(sql26.replace(/\r\n/g, "\n"), "utf8").digest("hex");
9843
+ function migrationSha256(sql27) {
9844
+ return createHash("sha256").update(sql27.replace(/\r\n/g, "\n"), "utf8").digest("hex");
9751
9845
  }
9752
9846
  function dollarQuoteTag(value) {
9753
9847
  let tag = "_mcp";
@@ -10756,7 +10850,7 @@ var TOOLS = [
10756
10850
  },
10757
10851
  {
10758
10852
  name: "release-profile",
10759
- description: 'Create or update a release profile. Pick the operation with `action`:\n- "create": one-step creation \u2014 scans the GitHub repo, detects apps (Next.js/Docker/PM2), creates the profile plus dev/prod stages with smart defaults (dev: release-dev + PR webhook + auto-approve, prod: release-prod + manual + DB backup) and seeds the stage apps. Release branches are created on GitHub automatically. Required: repoFullName. Optional: githubKey, name, releaseType. Assign deployment servers afterwards in the dashboard (Releases \u2192 Profiles).\n- "update": change settings of an existing profile located by `releaseProfile` (name or repo). Changing releaseType reconfigures the stages (missing stages are created with smart defaults, out-of-scope stages are disabled). Required: releaseProfile. Optional: name, enabled, releaseType, githubKey, useChangesBranch, hasTriggerDev, workDirectory.\n\nRequires ci_cd permission.',
10853
+ description: 'Create or update a release profile. Pick the operation with `action`:\n- "create": one-step creation \u2014 scans the GitHub repo, detects apps (Next.js/Docker/PM2), creates the profile plus dev/prod stages with smart defaults (dev: release-dev + PR webhook + auto-approve, prod: release-prod + manual + DB backup) and seeds the stage apps. Release branches are created on GitHub automatically. Required: repoFullName. Optional: githubKey, name, releaseType. Assign deployment servers afterwards in the dashboard (Releases \u2192 Profiles).\n- "update": change settings of an existing profile located by `releaseProfile` (name or repo). Changing releaseType reconfigures the stages (missing stages are created with smart defaults, out-of-scope stages are disabled). Required: releaseProfile. Optional: name, enabled, releaseType, githubKey, useChangesBranch, hasTriggerDev, workDirectory, internalTicketProjectId.\n\nRequires ci_cd permission.',
10760
10854
  inputSchema: {
10761
10855
  type: "object",
10762
10856
  properties: {
@@ -10801,6 +10895,10 @@ var TOOLS = [
10801
10895
  workDirectory: {
10802
10896
  type: "string",
10803
10897
  description: 'Working directory within the repo (e.g. "."). Update only.'
10898
+ },
10899
+ internalTicketProjectId: {
10900
+ type: "string",
10901
+ description: "Refront project UUID for escalating fundamental/platform issues (update only). Pass empty string to clear."
10804
10902
  }
10805
10903
  },
10806
10904
  required: ["action"]
@@ -11460,6 +11558,38 @@ var TOOLS = [
11460
11558
  }
11461
11559
  }
11462
11560
  },
11561
+ {
11562
+ name: "search-wiki",
11563
+ description: "Search the team's curated knowledge wiki (the distilled layer ABOVE team memory): compiled pages about how systems actually work, customer setups/quirks, and known recurring issues with their standard fixes. Check this BEFORE search-team-memory \u2014 it is smaller, curated, and deduplicated, so a hit here is usually the complete answer. Every page lists its `sources` (team-memory ids, ticket numbers, commits): follow those with get-team-memory for full raw detail instead of broad searches. Fall back to search-team-memory when nothing relevant comes back or the page's `updated` date looks stale.",
11564
+ inputSchema: {
11565
+ type: "object",
11566
+ properties: {
11567
+ query: {
11568
+ type: "string",
11569
+ description: "The topic/problem in natural language, e.g. 'deploy pipeline failure modes' or 'customer acme integrations'."
11570
+ },
11571
+ limit: {
11572
+ type: "number",
11573
+ description: "Max pages to return (1-20, default 5)."
11574
+ }
11575
+ },
11576
+ required: ["query"]
11577
+ }
11578
+ },
11579
+ {
11580
+ name: "get-wiki-page",
11581
+ description: "Fetch one full knowledge-wiki page (markdown + frontmatter + sources) by the `slug` from a search-wiki result. The `sources` list is the provenance: team-memory ids (fetch via get-team-memory), ticket numbers, and commits.",
11582
+ inputSchema: {
11583
+ type: "object",
11584
+ properties: {
11585
+ slug: {
11586
+ type: "string",
11587
+ description: "Page slug from a search-wiki hit, e.g. 'wiki/engineering/team-memory'."
11588
+ }
11589
+ },
11590
+ required: ["slug"]
11591
+ }
11592
+ },
11463
11593
  // ----- Cursor Remote (Agent Control) -----
11464
11594
  {
11465
11595
  name: "cursor-remote-list",
@@ -11769,7 +11899,7 @@ async function executeToolCall(name, a, _serverId) {
11769
11899
  ]
11770
11900
  };
11771
11901
  }
11772
- const lines = data.hits.map((hit, index7) => {
11902
+ const lines = data.hits.map((hit, index8) => {
11773
11903
  const when = hit.lastMessageAt ? new Date(hit.lastMessageAt).toISOString().slice(0, 10) : "unknown date";
11774
11904
  const repo = hit.repo ?? "unknown repo";
11775
11905
  const sim = hit.similarity !== null ? ` \xB7 ${(hit.similarity * 100).toFixed(0)}% match` : "";
@@ -11779,7 +11909,7 @@ async function executeToolCall(name, a, _serverId) {
11779
11909
  ...Array.isArray(hit.tech) ? hit.tech.slice(0, 4) : []
11780
11910
  ].filter(Boolean);
11781
11911
  const tags = facets.length > 0 ? ` \xB7 ${facets.join(", ")}` : "";
11782
- return `${index7 + 1}. [${repo} \xB7 ${when}${sim}${tags}] ${hit.title}
11912
+ return `${index8 + 1}. [${repo} \xB7 ${when}${sim}${tags}] ${hit.title}
11783
11913
  id: ${hit.id}
11784
11914
  ${(hit.summary ?? hit.snippet).replace(/\s+/g, " ").slice(0, 500)}`;
11785
11915
  });
@@ -11881,6 +12011,114 @@ ${facets.join(", ")}` : ""),
11881
12011
  ]
11882
12012
  };
11883
12013
  }
12014
+ // ----- Knowledge wiki: search -----
12015
+ case "search-wiki": {
12016
+ const query = typeof a.query === "string" ? a.query.trim() : "";
12017
+ if (!query) {
12018
+ return { content: [{ type: "text", text: "Error: query is required" }] };
12019
+ }
12020
+ const res = await fetch(`${dashboardBaseUrl}/api/wiki/search`, {
12021
+ method: "POST",
12022
+ headers: {
12023
+ "content-type": "application/json",
12024
+ authorization: `Bearer ${apiKey}`
12025
+ },
12026
+ body: JSON.stringify({
12027
+ query,
12028
+ limit: typeof a.limit === "number" ? a.limit : void 0
12029
+ })
12030
+ });
12031
+ if (!res.ok) {
12032
+ const detail = await res.text().catch(() => "");
12033
+ return {
12034
+ content: [
12035
+ {
12036
+ type: "text",
12037
+ text: `Error: wiki search failed (${res.status}). ${detail.slice(0, 300)}`
12038
+ }
12039
+ ]
12040
+ };
12041
+ }
12042
+ const data = await res.json();
12043
+ if (data.count === 0) {
12044
+ return {
12045
+ content: [
12046
+ {
12047
+ type: "text",
12048
+ text: "No wiki pages matched. Fall back to search-team-memory for raw history \u2014 repeated misses here become insight-scout signals automatically."
12049
+ }
12050
+ ]
12051
+ };
12052
+ }
12053
+ const lines = data.hits.map((hit, index8) => {
12054
+ const sim = hit.similarity !== null ? ` \xB7 ${Math.round(hit.similarity * 100)}% match` : "";
12055
+ const tags = hit.tags.length ? ` \xB7 ${hit.tags.slice(0, 5).join(", ")}` : "";
12056
+ const sources = hit.sources.length ? `
12057
+ sources: ${hit.sources.slice(0, 6).map((s) => `${s.type}:${s.ref}`).join(", ")}` : "";
12058
+ return `${index8 + 1}. [${hit.status} \xB7 updated ${hit.pageUpdatedOn ?? "unknown"}${sim}${tags}] ${hit.title}
12059
+ slug: ${hit.slug}${sources}
12060
+ ${(hit.summary ?? hit.snippet).replace(/\s+/g, " ").slice(0, 400)}`;
12061
+ });
12062
+ return {
12063
+ content: [
12064
+ {
12065
+ type: "text",
12066
+ text: `Found ${data.count} wiki page(s) (${data.mode} search) \u2014 curated team knowledge.
12067
+ Call get-wiki-page with a slug for the full page; follow its sources (team-memory ids, tickets) for raw detail. Treat stale \`updated\` dates as a signal to also check team memory.
12068
+
12069
+ ` + lines.join("\n\n")
12070
+ }
12071
+ ]
12072
+ };
12073
+ }
12074
+ // ----- Knowledge wiki: full page -----
12075
+ case "get-wiki-page": {
12076
+ const slug = typeof a.slug === "string" ? a.slug.trim() : "";
12077
+ if (!slug) {
12078
+ return { content: [{ type: "text", text: "Error: slug is required" }] };
12079
+ }
12080
+ const res = await fetch(`${dashboardBaseUrl}/api/wiki/page`, {
12081
+ method: "POST",
12082
+ headers: {
12083
+ "content-type": "application/json",
12084
+ authorization: `Bearer ${apiKey}`
12085
+ },
12086
+ body: JSON.stringify({ slug })
12087
+ });
12088
+ if (!res.ok) {
12089
+ const detail = await res.text().catch(() => "");
12090
+ return {
12091
+ content: [
12092
+ {
12093
+ type: "text",
12094
+ text: `Error: wiki page fetch failed (${res.status}). ${detail.slice(0, 300)}`
12095
+ }
12096
+ ]
12097
+ };
12098
+ }
12099
+ const data = await res.json();
12100
+ if (!data.found || !data.page) {
12101
+ return {
12102
+ content: [
12103
+ { type: "text", text: `No wiki page found for slug "${slug}".` }
12104
+ ]
12105
+ };
12106
+ }
12107
+ const page = data.page;
12108
+ const sources = page.sources.length ? `
12109
+ Sources: ${page.sources.map((s) => `${s.type}:${s.ref}`).join(", ")}` : "";
12110
+ return {
12111
+ content: [
12112
+ {
12113
+ type: "text",
12114
+ text: `# ${page.title}
12115
+ [${page.slug} \xB7 ${page.status} \xB7 updated ${page.pageUpdatedOn ?? "unknown"}` + (page.tags.length ? ` \xB7 ${page.tags.join(", ")}` : "") + `]${sources}
12116
+
12117
+ ` + page.content
12118
+ }
12119
+ ]
12120
+ };
12121
+ }
11884
12122
  // ----- Cursor Remote (Agent Control) -----
11885
12123
  case "cursor-remote-list": {
11886
12124
  const onlineOnly = a.onlineOnly === true;
@@ -12964,8 +13202,8 @@ ${sample.join("\n")}${files.length > 5 ? `
12964
13202
  };
12965
13203
  const filtered = sortRows(applyFilter(only.rows));
12966
13204
  if (format === "json") {
12967
- const text10 = filtered.map((c) => JSON.stringify(c)).join("\n") || "(no containers)";
12968
- return { content: [{ type: "text", text: text10 }] };
13205
+ const text12 = filtered.map((c) => JSON.stringify(c)).join("\n") || "(no containers)";
13206
+ return { content: [{ type: "text", text: text12 }] };
12969
13207
  }
12970
13208
  if (groupByProject) {
12971
13209
  const groups = /* @__PURE__ */ new Map();
@@ -12992,8 +13230,8 @@ ${sample.join("\n")}${files.length > 5 ? `
12992
13230
  }
12993
13231
  const header = `${"NAMES".padEnd(36)} ${"IMAGE".padEnd(40)} ${"STATUS".padEnd(24)} ${"HEALTH".padEnd(10)} ${"PORTS".padEnd(40)} PROJECT`;
12994
13232
  const body = filtered.map((r) => `${fmtRow(r)} ${r.Project || ""}`);
12995
- const text9 = filtered.length === 0 ? "(no containers match)" : [header, ...body].join("\n");
12996
- return { content: [{ type: "text", text: text9 }] };
13233
+ const text11 = filtered.length === 0 ? "(no containers match)" : [header, ...body].join("\n");
13234
+ return { content: [{ type: "text", text: text11 }] };
12997
13235
  }
12998
13236
  if (format === "json") {
12999
13237
  const lines = [];
@@ -14181,6 +14419,7 @@ LIMIT ${limit};
14181
14419
  SELECT
14182
14420
  p.id, p.name, p.repo_full_name, p.enabled, p.release_type,
14183
14421
  p.work_directory, p.use_changes_branch, p.has_trigger_dev,
14422
+ p.internal_ticket_project_id,
14184
14423
  gt.label AS github_key,
14185
14424
  (
14186
14425
  SELECT string_agg(
@@ -14207,7 +14446,8 @@ LIMIT ${limit};
14207
14446
  `type=${p.release_type ?? "both"}`,
14208
14447
  `key=${p.github_key ?? "MG Software (default)"}`,
14209
14448
  p.use_changes_branch ? "changes-branch" : null,
14210
- p.has_trigger_dev ? "trigger.dev" : null
14449
+ p.has_trigger_dev ? "trigger.dev" : null,
14450
+ p.internal_ticket_project_id ? `internalTicketProject=${p.internal_ticket_project_id}` : null
14211
14451
  ].filter(Boolean).join(", ");
14212
14452
  return `${p.name} \u2014 ${p.repo_full_name} [${flags}]
14213
14453
  stages: ${p.stages ?? "(none)"}`;
@@ -14324,7 +14564,8 @@ ${lines.join("\n\n")}`
14324
14564
  githubTokenId,
14325
14565
  useChangesBranch: a.useChangesBranch !== void 0 ? a.useChangesBranch === true : void 0,
14326
14566
  hasTriggerDev: a.hasTriggerDev !== void 0 ? a.hasTriggerDev === true : void 0,
14327
- workDirectory: a.workDirectory !== void 0 ? String(a.workDirectory) : void 0
14567
+ workDirectory: a.workDirectory !== void 0 ? String(a.workDirectory) : void 0,
14568
+ internalTicketProjectId: a.internalTicketProjectId !== void 0 ? String(a.internalTicketProjectId).trim() || null : void 0
14328
14569
  });
14329
14570
  return {
14330
14571
  content: [
@@ -14335,7 +14576,8 @@ ${lines.join("\n\n")}`
14335
14576
  profileId: profile.id,
14336
14577
  name: result.profile.name,
14337
14578
  updated: true,
14338
- stagesReconfigured: result.stagesReconfigured
14579
+ stagesReconfigured: result.stagesReconfigured,
14580
+ internalTicketProjectId: result.profile.internal_ticket_project_id ?? null
14339
14581
  },
14340
14582
  null,
14341
14583
  2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mgsoftwarebv/mg-dashboard-mcp",
3
- "version": "7.4.3",
3
+ "version": "7.4.5",
4
4
  "description": "MCP Server for MG Dashboard - SSH, SFTP, Docker, domains, DNS, and environment config tools for Cursor",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",