@mgsoftwarebv/mg-dashboard-mcp 7.4.16 → 7.4.17

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 +122 -143
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1010,9 +1010,9 @@ ${raw2.substring(0, 500)}` }] };
1010
1010
  return { content: [{ type: "text", text: `No environment variables for ${project}/${env}.` }] };
1011
1011
  }
1012
1012
  const lines = vars.map((v) => `${v.isSecret ? "[secret]" : " "} ${v.name}`).sort();
1013
- const text22 = `Env vars for ${project}/${env} (${vars.length}) \u2014 values hidden, use action="get" with a key:
1013
+ const text21 = `Env vars for ${project}/${env} (${vars.length}) \u2014 values hidden, use action="get" with a key:
1014
1014
  ` + "-".repeat(50) + "\n" + lines.join("\n");
1015
- return { content: [{ type: "text", text: text22 }] };
1015
+ return { content: [{ type: "text", text: text21 }] };
1016
1016
  }
1017
1017
  if (action === "get") {
1018
1018
  const key2 = String(args2.key ?? "");
@@ -1099,9 +1099,9 @@ async function fetchAndFormatRun(conn, proxy, sshExec2, instance, runId) {
1099
1099
  return { content: [{ type: "text", text: `Invalid API response:
1100
1100
  ${rawJson.substring(0, 500)}` }] };
1101
1101
  }
1102
- let text22 = formatRunDetail(run);
1103
- if (logs) text22 += "\n\n--- Logs ---\n" + logs;
1104
- return { content: [{ type: "text", text: text22 }] };
1102
+ let text21 = formatRunDetail(run);
1103
+ if (logs) text21 += "\n\n--- Logs ---\n" + logs;
1104
+ return { content: [{ type: "text", text: text21 }] };
1105
1105
  }
1106
1106
  async function waitForCompletion(conn, proxy, sshExec2, instance, runId, waitSeconds) {
1107
1107
  const pollInterval = 3e3;
@@ -1123,10 +1123,10 @@ async function waitForCompletion(conn, proxy, sshExec2, instance, runId, waitSec
1123
1123
  continue;
1124
1124
  }
1125
1125
  if (TERMINAL_STATUSES.has(run.status)) {
1126
- let text22 = formatRunDetail(run);
1126
+ let text21 = formatRunDetail(run);
1127
1127
  const logs = await fetchRunLogs(runId, conn, proxy, sshExec2);
1128
- if (logs) text22 += "\n\n--- Logs ---\n" + logs;
1129
- return { content: [{ type: "text", text: text22 }] };
1128
+ if (logs) text21 += "\n\n--- Logs ---\n" + logs;
1129
+ return { content: [{ type: "text", text: text21 }] };
1130
1130
  }
1131
1131
  }
1132
1132
  return {
@@ -1138,32 +1138,65 @@ async function waitForCompletion(conn, proxy, sshExec2, instance, runId, waitSec
1138
1138
  }
1139
1139
 
1140
1140
  // src/github-code-access-tools.ts
1141
+ var FILE_PROPERTIES = {
1142
+ repository: {
1143
+ type: "string",
1144
+ description: "owner/repo, e.g. MGSoftwareBV/tickets-v2. Org must be allowlisted (CODE_BATTLE_GITHUB_ORGS)."
1145
+ },
1146
+ path: {
1147
+ type: "string",
1148
+ description: "File path inside the repo (not a directory)."
1149
+ },
1150
+ ref: {
1151
+ type: "string",
1152
+ description: "Optional commit sha, branch, or tag. Defaults to the repository default branch."
1153
+ }
1154
+ };
1155
+ var FILE_DESCRIPTION = "Read ONE source file from an ingested GitHub org/repo (CODE_BATTLE_GITHUB_ORGS, default MGSoftwareBV). Path + optional ref (defaults to the repo default branch). Returns metadata + text content (secrets redacted). Credential paths (.env, keys) are denied. Binary files return { binary: true } with no payload. Use list-dir to browse a folder first. Compact diffs stay on get_mg_dashboard_diff.";
1141
1156
  var GITHUB_CODE_ACCESS_TOOLS = [
1142
1157
  {
1143
- name: "get_mg_dashboard_file",
1144
- description: "Read ONE source file at a git ref for an allowlisted GitHub org/repo (CODE_BATTLE_GITHUB_ORGS, default MGSoftwareBV). Use after get_mg_dashboard_commits when commit subjects are not enough to judge exists / polish / new. Returns metadata + text content (secrets redacted). Credential paths (.env, keys) are denied. Binary files return { binary: true } with no payload. Full diffs are never attached to get_mg_dashboard_commits \u2014 use get_mg_dashboard_diff for a compact patch.",
1158
+ name: "read-file",
1159
+ description: FILE_DESCRIPTION,
1160
+ inputSchema: {
1161
+ type: "object",
1162
+ properties: FILE_PROPERTIES,
1163
+ required: ["repository", "path"]
1164
+ }
1165
+ },
1166
+ {
1167
+ name: "list-dir",
1168
+ description: "List ONE directory on an ingested GitHub org/repo (CODE_BATTLE_GITHUB_ORGS). Path is optional (empty or '/' = repo root). Ref is optional (defaults to the repo default branch). Returns name/path/type/size/sha per entry. Credential files are omitted. No file contents, no clone.",
1145
1169
  inputSchema: {
1146
1170
  type: "object",
1147
1171
  properties: {
1148
1172
  repository: {
1149
1173
  type: "string",
1150
- description: "owner/repo, e.g. MGSoftwareBV/mg-dashboard. Org must be allowlisted."
1174
+ description: "owner/repo, e.g. MGSoftwareBV/tickets-v2. Org must be allowlisted."
1151
1175
  },
1152
- ref: {
1176
+ path: {
1153
1177
  type: "string",
1154
- description: "Commit sha, branch, or tag."
1178
+ description: "Directory path (e.g. wbso-planning). Empty string or '/' for the repository root."
1155
1179
  },
1156
- path: {
1180
+ ref: {
1157
1181
  type: "string",
1158
- description: "File path inside the repo (not a directory)."
1182
+ description: "Optional commit sha, branch, or tag. Defaults to the repository default branch."
1159
1183
  }
1160
1184
  },
1161
- required: ["repository", "ref", "path"]
1185
+ required: ["repository"]
1186
+ }
1187
+ },
1188
+ {
1189
+ name: "get_mg_dashboard_file",
1190
+ description: `${FILE_DESCRIPTION} Alias of read-file.`,
1191
+ inputSchema: {
1192
+ type: "object",
1193
+ properties: FILE_PROPERTIES,
1194
+ required: ["repository", "path"]
1162
1195
  }
1163
1196
  },
1164
1197
  {
1165
1198
  name: "get_mg_dashboard_diff",
1166
- description: "Fetch a COMPACT unified diff for one commit sha XOR one pull request number, same org allowlist as get_mg_dashboard_file. Returns per-file path/status/+/- and a truncated patch (secrets redacted). Binary files are omitted. Does not change get_mg_dashboard_commits (metadata-only by design).",
1199
+ description: "Fetch a COMPACT unified diff for one commit sha XOR one pull request number, same org allowlist as read-file. Returns per-file path/status/+/- and a truncated patch (secrets redacted). Binary files are omitted. Does not change get_mg_dashboard_commits (metadata-only by design).",
1167
1200
  inputSchema: {
1168
1201
  type: "object",
1169
1202
  properties: {
@@ -1184,25 +1217,49 @@ var GITHUB_CODE_ACCESS_TOOLS = [
1184
1217
  }
1185
1218
  }
1186
1219
  ];
1220
+ function optionalString(value) {
1221
+ if (typeof value !== "string") return void 0;
1222
+ const trimmed = value.trim();
1223
+ return trimmed ? trimmed : void 0;
1224
+ }
1187
1225
  async function handleGithubCodeAccessTool(name, args2, ctx) {
1188
- if (name === "get_mg_dashboard_file") {
1189
- const repository = typeof args2.repository === "string" ? args2.repository.trim() : "";
1190
- const ref = typeof args2.ref === "string" ? args2.ref.trim() : "";
1191
- const path = typeof args2.path === "string" ? args2.path.trim() : "";
1192
- if (!repository || !ref || !path) {
1226
+ if (name === "get_mg_dashboard_file" || name === "read-file") {
1227
+ const repository = optionalString(args2.repository) ?? "";
1228
+ const path = optionalString(args2.path) ?? "";
1229
+ const ref = optionalString(args2.ref);
1230
+ if (!repository || !path) {
1193
1231
  return {
1194
1232
  content: [
1195
1233
  {
1196
1234
  type: "text",
1197
- text: "Error: repository, ref and path are required"
1235
+ text: "Error: repository and path are required"
1198
1236
  }
1199
1237
  ]
1200
1238
  };
1201
1239
  }
1202
- return proxyJson(ctx, "/api/activity/file", { repository, ref, path });
1240
+ return proxyJson(ctx, "/api/activity/file", {
1241
+ repository,
1242
+ path,
1243
+ ...ref ? { ref } : {}
1244
+ });
1245
+ }
1246
+ if (name === "list-dir") {
1247
+ const repository = optionalString(args2.repository) ?? "";
1248
+ if (!repository) {
1249
+ return {
1250
+ content: [{ type: "text", text: "Error: repository is required" }]
1251
+ };
1252
+ }
1253
+ const path = typeof args2.path === "string" ? args2.path : "";
1254
+ const ref = optionalString(args2.ref);
1255
+ return proxyJson(ctx, "/api/activity/list-dir", {
1256
+ repository,
1257
+ path,
1258
+ ...ref ? { ref } : {}
1259
+ });
1203
1260
  }
1204
1261
  if (name === "get_mg_dashboard_diff") {
1205
- const repository = typeof args2.repository === "string" ? args2.repository.trim() : "";
1262
+ const repository = optionalString(args2.repository) ?? "";
1206
1263
  if (!repository) {
1207
1264
  return {
1208
1265
  content: [
@@ -1210,7 +1267,7 @@ async function handleGithubCodeAccessTool(name, args2, ctx) {
1210
1267
  ]
1211
1268
  };
1212
1269
  }
1213
- const sha = typeof args2.sha === "string" ? args2.sha.trim() : void 0;
1270
+ const sha = optionalString(args2.sha);
1214
1271
  const pullNumber = typeof args2.pullNumber === "number" ? args2.pullNumber : void 0;
1215
1272
  const hasSha = Boolean(sha);
1216
1273
  const hasPr = pullNumber != null;
@@ -3935,10 +3992,10 @@ var ZodObject = class _ZodObject extends ZodType {
3935
3992
  // }) as any;
3936
3993
  // return merged;
3937
3994
  // }
3938
- catchall(index19) {
3995
+ catchall(index18) {
3939
3996
  return new _ZodObject({
3940
3997
  ...this._def,
3941
- catchall: index19
3998
+ catchall: index18
3942
3999
  });
3943
4000
  }
3944
4001
  pick(mask) {
@@ -4256,9 +4313,9 @@ function mergeValues(a, b) {
4256
4313
  return { valid: false };
4257
4314
  }
4258
4315
  const newArray = [];
4259
- for (let index19 = 0; index19 < a.length; index19++) {
4260
- const itemA = a[index19];
4261
- const itemB = b[index19];
4316
+ for (let index18 = 0; index18 < a.length; index18++) {
4317
+ const itemA = a[index18];
4318
+ const itemB = b[index18];
4262
4319
  const sharedValue = mergeValues(itemA, itemB);
4263
4320
  if (!sharedValue.valid) {
4264
4321
  return { valid: false };
@@ -4464,10 +4521,10 @@ var ZodMap = class extends ZodType {
4464
4521
  }
4465
4522
  const keyType = this._def.keyType;
4466
4523
  const valueType = this._def.valueType;
4467
- const pairs = [...ctx.data.entries()].map(([key, value], index19) => {
4524
+ const pairs = [...ctx.data.entries()].map(([key, value], index18) => {
4468
4525
  return {
4469
- key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index19, "key"])),
4470
- value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index19, "value"]))
4526
+ key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index18, "key"])),
4527
+ value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index18, "value"]))
4471
4528
  };
4472
4529
  });
4473
4530
  if (ctx.common.async) {
@@ -5788,88 +5845,6 @@ pgTable(
5788
5845
  index("idx_agent_memory_kind").on(table.kind)
5789
5846
  ]
5790
5847
  );
5791
- var agentWorldAgent = pgTable(
5792
- "agent_world_agent",
5793
- {
5794
- id: uuid("id").primaryKey().defaultRandom(),
5795
- name: text("name").notNull(),
5796
- color: text("color").notNull(),
5797
- /** Personality sliders 0–100: curiosity, sociability, diligence, calm. */
5798
- personality: jsonb("personality").$type().notNull().default({
5799
- curiosity: 50,
5800
- sociability: 50,
5801
- diligence: 50,
5802
- calm: 50
5803
- }),
5804
- /** Needs 0–100: higher = more urgent. */
5805
- needs: jsonb("needs").$type().notNull().default({ energy: 40, coffee: 30, focus: 35, social: 25 }),
5806
- position: jsonb("position").$type().notNull().default({ x: 0, y: 0, z: 0 }),
5807
- target: jsonb("target").$type(),
5808
- activity: text("activity").notNull().default("idle"),
5809
- waypoint: text("waypoint"),
5810
- memories: jsonb("memories").$type().notNull().default([]),
5811
- diaryCount: integer("diary_count").notNull().default(0),
5812
- lastSay: text("last_say"),
5813
- lastSayAt: timestamp("last_say_at", { withTimezone: true }),
5814
- sortOrder: integer("sort_order").notNull().default(0),
5815
- createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5816
- updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5817
- },
5818
- (table) => [index("idx_agent_world_agent_sort").on(table.sortOrder)]
5819
- );
5820
- pgTable(
5821
- "agent_world_event",
5822
- {
5823
- id: uuid("id").primaryKey().defaultRandom(),
5824
- /** say | diary | think | god | activity | memo | system */
5825
- type: text("type").notNull(),
5826
- agentId: uuid("agent_id").references(() => agentWorldAgent.id, {
5827
- onDelete: "set null"
5828
- }),
5829
- message: text("message").notNull(),
5830
- meta: jsonb("meta").$type().notNull().default({}),
5831
- createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
5832
- },
5833
- (table) => [
5834
- index("idx_agent_world_event_created").on(table.createdAt),
5835
- index("idx_agent_world_event_type").on(table.type),
5836
- index("idx_agent_world_event_agent").on(table.agentId),
5837
- // Diary / per-agent feed: WHERE agent_id ORDER BY created_at DESC LIMIT N
5838
- index("idx_agent_world_event_agent_created").on(
5839
- table.agentId,
5840
- table.createdAt
5841
- )
5842
- ]
5843
- );
5844
- pgTable(
5845
- "agent_world_memo",
5846
- {
5847
- id: uuid("id").primaryKey().defaultRandom(),
5848
- agentId: uuid("agent_id").references(() => agentWorldAgent.id, {
5849
- onDelete: "set null"
5850
- }),
5851
- title: text("title").notNull(),
5852
- content: text("content").notNull(),
5853
- location: text("location").notNull().default("whiteboard"),
5854
- reads: integer("reads").notNull().default(0),
5855
- createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5856
- updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5857
- },
5858
- (table) => [
5859
- index("idx_agent_world_memo_created").on(table.createdAt),
5860
- index("idx_agent_world_memo_location").on(table.location)
5861
- ]
5862
- );
5863
- pgTable("agent_world_state", {
5864
- id: text("id").primaryKey().default("world"),
5865
- tick: integer("tick").notNull().default(0),
5866
- /** Simulated minutes since day start (0–1439 wraps). */
5867
- simMinutes: integer("sim_minutes").notNull().default(540),
5868
- paused: boolean("paused").notNull().default(false),
5869
- lastThinkAt: timestamp("last_think_at", { withTimezone: true }),
5870
- lastThinkAgentId: uuid("last_think_agent_id"),
5871
- updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5872
- });
5873
5848
  var contentSourceType = pgEnum("content_source_type", [
5874
5849
  "own_site",
5875
5850
  "client_site",
@@ -9538,7 +9513,7 @@ function getEncryptionKey() {
9538
9513
  throw new Error("ENCRYPTION_KEY must be a 64-character hex string");
9539
9514
  return buf;
9540
9515
  }
9541
- function encrypt(text22) {
9516
+ function encrypt(text21) {
9542
9517
  const key = getEncryptionKey();
9543
9518
  const iv = randomBytes(ENC_IV_LENGTH);
9544
9519
  const cipher = createCipheriv(
@@ -9546,7 +9521,7 @@ function encrypt(text22) {
9546
9521
  new Uint8Array(key),
9547
9522
  new Uint8Array(iv)
9548
9523
  );
9549
- let encrypted = cipher.update(text22, "utf8", "hex");
9524
+ let encrypted = cipher.update(text21, "utf8", "hex");
9550
9525
  encrypted += cipher.final("hex");
9551
9526
  const authTag = cipher.getAuthTag();
9552
9527
  return Buffer.concat([
@@ -10266,10 +10241,10 @@ async function r2GetObjectRange(bucket, key, range) {
10266
10241
  const body = result.Body;
10267
10242
  if (!body?.transformToString)
10268
10243
  throw new Error("R2 returned no readable body");
10269
- const text22 = await body.transformToString();
10244
+ const text21 = await body.transformToString();
10270
10245
  const header = `# range: bytes ${range.offset}-${end} of ${size} (${effectiveLen} bytes)`;
10271
10246
  return `${header}
10272
- ${text22}`;
10247
+ ${text21}`;
10273
10248
  } catch (e) {
10274
10249
  throw r2WrapError(bucket, key, e);
10275
10250
  }
@@ -10632,15 +10607,15 @@ async function sftpRead(opts, filePath, proxy, options) {
10632
10607
  clearTimeout(timer);
10633
10608
  cleanup?.();
10634
10609
  cleanup = void 0;
10635
- const text22 = Buffer.concat(
10610
+ const text21 = Buffer.concat(
10636
10611
  chunks.map((ch) => new Uint8Array(ch))
10637
10612
  ).toString("utf-8");
10638
10613
  if (!isWholeFileRequest) {
10639
10614
  const header = `# range: bytes ${offset}-${offset + effectiveLen - 1} of ${total} (${effectiveLen} bytes)`;
10640
10615
  resolve(`${header}
10641
- ${text22}`);
10616
+ ${text21}`);
10642
10617
  } else {
10643
- resolve(text22);
10618
+ resolve(text21);
10644
10619
  }
10645
10620
  });
10646
10621
  rs.on("error", (e) => {
@@ -10675,6 +10650,8 @@ var RAW_JSON_TOOLS = /* @__PURE__ */ new Set([
10675
10650
  "get_mg_dashboard_commits",
10676
10651
  "get_mg_dashboard_file",
10677
10652
  "get_mg_dashboard_diff",
10653
+ "read-file",
10654
+ "list-dir",
10678
10655
  "extract_article",
10679
10656
  // Content family (2026-DASMG-040/041/042) — compact JSON consumed verbatim.
10680
10657
  // Consolidated action-based tools (the Cursor surface); each proxies to the
@@ -10793,11 +10770,11 @@ function getKnownContainers(serverId, maxAgeMs = 5 * 6e4) {
10793
10770
  if (Date.now() - e.capturedAt > maxAgeMs) return void 0;
10794
10771
  return e.names;
10795
10772
  }
10796
- function truncateForLLM(text22, maxBytes) {
10797
- const totalBytes = Buffer.byteLength(text22, "utf8");
10773
+ function truncateForLLM(text21, maxBytes) {
10774
+ const totalBytes = Buffer.byteLength(text21, "utf8");
10798
10775
  if (totalBytes <= maxBytes)
10799
- return { text: text22, truncated: false, totalBytes, shownBytes: totalBytes };
10800
- const buf = Buffer.from(text22, "utf8");
10776
+ return { text: text21, truncated: false, totalBytes, shownBytes: totalBytes };
10777
+ const buf = Buffer.from(text21, "utf8");
10801
10778
  let cut = maxBytes;
10802
10779
  while (cut > 0 && (buf[cut] & 192) === 128) cut--;
10803
10780
  const head = buf.subarray(0, cut).toString("utf8");
@@ -10828,10 +10805,10 @@ function postprocessResult(result, meta) {
10828
10805
  if (!result.content?.length) return result;
10829
10806
  if (RAW_JSON_TOOLS.has(meta.toolName)) return result;
10830
10807
  const block = result.content[0];
10831
- let text22 = String(block.text ?? "");
10832
- const trunc = truncateForLLM(text22, RESPONSE_MAX_BYTES);
10808
+ let text21 = String(block.text ?? "");
10809
+ const trunc = truncateForLLM(text21, RESPONSE_MAX_BYTES);
10833
10810
  if (trunc.truncated) {
10834
- text22 = trunc.text + "\n\n... " + buildTruncationHint(
10811
+ text21 = trunc.text + "\n\n... " + buildTruncationHint(
10835
10812
  meta.toolName,
10836
10813
  meta.args,
10837
10814
  trunc.totalBytes,
@@ -10845,11 +10822,11 @@ function postprocessResult(result, meta) {
10845
10822
  const parts = [`took ${tookStr}`, sizeStr];
10846
10823
  if (meta.serverIdLabel) parts.push(`server: ${meta.serverIdLabel}`);
10847
10824
  if (meta.cached) parts.push("cached");
10848
- text22 = `${text22}
10825
+ text21 = `${text21}
10849
10826
 
10850
10827
  [${parts.join(", ")}]`;
10851
10828
  }
10852
- return { ...result, content: [{ ...block, text: text22 }] };
10829
+ return { ...result, content: [{ ...block, text: text21 }] };
10853
10830
  }
10854
10831
  function buildPipelineScript(commands, shell, marker, stopOnError) {
10855
10832
  if (shell === "powershell") {
@@ -13796,6 +13773,8 @@ async function executeToolCall(name, a, _serverId) {
13796
13773
  }
13797
13774
  case "get_mg_dashboard_file":
13798
13775
  case "get_mg_dashboard_diff":
13776
+ case "read-file":
13777
+ case "list-dir":
13799
13778
  return handleGithubCodeAccessTool(name, a, {
13800
13779
  dashboardBaseUrl,
13801
13780
  apiKey: apiKey ?? ""
@@ -13950,7 +13929,7 @@ async function executeToolCall(name, a, _serverId) {
13950
13929
  ]
13951
13930
  };
13952
13931
  }
13953
- const lines = data.hits.map((hit, index19) => {
13932
+ const lines = data.hits.map((hit, index18) => {
13954
13933
  const when = hit.lastMessageAt ? new Date(hit.lastMessageAt).toISOString().slice(0, 10) : "unknown date";
13955
13934
  const repo = hit.repo ?? "unknown repo";
13956
13935
  const sim = hit.similarity !== null ? ` \xB7 ${(hit.similarity * 100).toFixed(0)}% match` : "";
@@ -13960,7 +13939,7 @@ async function executeToolCall(name, a, _serverId) {
13960
13939
  ...Array.isArray(hit.tech) ? hit.tech.slice(0, 4) : []
13961
13940
  ].filter(Boolean);
13962
13941
  const tags = facets.length > 0 ? ` \xB7 ${facets.join(", ")}` : "";
13963
- return `${index19 + 1}. [${repo} \xB7 ${when}${sim}${tags}] ${hit.title}
13942
+ return `${index18 + 1}. [${repo} \xB7 ${when}${sim}${tags}] ${hit.title}
13964
13943
  id: ${hit.id}
13965
13944
  ${(hit.summary ?? hit.snippet).replace(/\s+/g, " ").slice(0, 500)}`;
13966
13945
  });
@@ -14167,12 +14146,12 @@ Searchable via search-team-memory once indexing completes (usually immediate).`
14167
14146
  ]
14168
14147
  };
14169
14148
  }
14170
- const lines = data.hits.map((hit, index19) => {
14149
+ const lines = data.hits.map((hit, index18) => {
14171
14150
  const sim = hit.similarity !== null ? ` \xB7 ${Math.round(hit.similarity * 100)}% match` : "";
14172
14151
  const tags = hit.tags.length ? ` \xB7 ${hit.tags.slice(0, 5).join(", ")}` : "";
14173
14152
  const sources = hit.sources.length ? `
14174
14153
  sources: ${hit.sources.slice(0, 6).map((s) => `${s.type}:${s.ref}`).join(", ")}` : "";
14175
- return `${index19 + 1}. [${hit.status} \xB7 updated ${hit.pageUpdatedOn ?? "unknown"}${sim}${tags}] ${hit.title}
14154
+ return `${index18 + 1}. [${hit.status} \xB7 updated ${hit.pageUpdatedOn ?? "unknown"}${sim}${tags}] ${hit.title}
14176
14155
  slug: ${hit.slug}${sources}
14177
14156
  ${(hit.summary ?? hit.snippet).replace(/\s+/g, " ").slice(0, 400)}`;
14178
14157
  });
@@ -14350,7 +14329,7 @@ Archived sources (${archiveOnly.length}):
14350
14329
  let formatItems2 = function(items) {
14351
14330
  if (items.length === 0) return "(none)";
14352
14331
  return items.map(
14353
- (item, index19) => `${index19 + 1}. [${item.status} \xB7 ${item.folder} \xB7 updated ${item.updated ?? "unknown"}] ${item.title}
14332
+ (item, index18) => `${index18 + 1}. [${item.status} \xB7 ${item.folder} \xB7 updated ${item.updated ?? "unknown"}] ${item.title}
14354
14333
  slug: ${item.slug}`
14355
14334
  ).join("\n");
14356
14335
  };
@@ -14377,9 +14356,9 @@ Archived sources (${archiveOnly.length}):
14377
14356
  }
14378
14357
  const data = await res.json();
14379
14358
  const countLine = Object.entries(data.counts).sort(([left], [right]) => left.localeCompare(right)).map(([status, count]) => `${status} ${count}`).join(" \xB7 ");
14380
- const flagLines = data.flags.length === 0 ? "(none)" : data.flags.map((flag, index19) => {
14359
+ const flagLines = data.flags.length === 0 ? "(none)" : data.flags.map((flag, index18) => {
14381
14360
  const detail = flag.detail.replace(/\s+/g, " ").slice(0, 240);
14382
- return `${index19 + 1}. [${flag.kind} \xB7 ${flag.folder}${flag.status ? ` \xB7 page ${flag.status}` : ""}] ${flag.title}
14361
+ return `${index18 + 1}. [${flag.kind} \xB7 ${flag.folder}${flag.status ? ` \xB7 page ${flag.status}` : ""}] ${flag.title}
14383
14362
  slug: ${flag.slug}
14384
14363
  ${detail}`;
14385
14364
  }).join("\n");
@@ -15545,8 +15524,8 @@ ${sample.join("\n")}${files.length > 5 ? `
15545
15524
  };
15546
15525
  const filtered = sortRows(applyFilter(only.rows));
15547
15526
  if (format === "json") {
15548
- const text23 = filtered.map((c) => JSON.stringify(c)).join("\n") || "(no containers)";
15549
- return { content: [{ type: "text", text: text23 }] };
15527
+ const text22 = filtered.map((c) => JSON.stringify(c)).join("\n") || "(no containers)";
15528
+ return { content: [{ type: "text", text: text22 }] };
15550
15529
  }
15551
15530
  if (groupByProject) {
15552
15531
  const groups = /* @__PURE__ */ new Map();
@@ -15573,8 +15552,8 @@ ${sample.join("\n")}${files.length > 5 ? `
15573
15552
  }
15574
15553
  const header = `${"NAMES".padEnd(36)} ${"IMAGE".padEnd(40)} ${"STATUS".padEnd(24)} ${"HEALTH".padEnd(10)} ${"PORTS".padEnd(40)} PROJECT`;
15575
15554
  const body = filtered.map((r) => `${fmtRow(r)} ${r.Project || ""}`);
15576
- const text22 = filtered.length === 0 ? "(no containers match)" : [header, ...body].join("\n");
15577
- return { content: [{ type: "text", text: text22 }] };
15555
+ const text21 = filtered.length === 0 ? "(no containers match)" : [header, ...body].join("\n");
15556
+ return { content: [{ type: "text", text: text21 }] };
15578
15557
  }
15579
15558
  if (format === "json") {
15580
15559
  const lines = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mgsoftwarebv/mg-dashboard-mcp",
3
- "version": "7.4.16",
3
+ "version": "7.4.17",
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",