@mgsoftwarebv/mg-dashboard-mcp 7.4.5 → 7.4.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 +309 -52
- 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, foreignKey } from 'drizzle-orm/pg-core';
|
|
23
|
+
import { pgTable, timestamp, jsonb, uuid, boolean, text, pgEnum, integer, uniqueIndex, index, check, bigint, doublePrecision, 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
|
|
706
|
+
const sql28 = `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 "${
|
|
709
|
+
`ROW=$(docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql28}" 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
|
|
732
|
-
const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${
|
|
731
|
+
const sql28 = `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 "${sql28}" 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
|
|
815
|
-
const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${
|
|
814
|
+
const sql28 = 'SELECT slug, name FROM \\"Project\\" ORDER BY name';
|
|
815
|
+
const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql28}" 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
|
|
993
|
+
const text13 = `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:
|
|
995
|
+
return { content: [{ type: "text", text: text13 }] };
|
|
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
|
|
1083
|
-
if (logs)
|
|
1084
|
-
return { content: [{ type: "text", text:
|
|
1082
|
+
let text13 = formatRunDetail(run);
|
|
1083
|
+
if (logs) text13 += "\n\n--- Logs ---\n" + logs;
|
|
1084
|
+
return { content: [{ type: "text", text: text13 }] };
|
|
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
|
|
1106
|
+
let text13 = formatRunDetail(run);
|
|
1107
1107
|
const logs = await fetchRunLogs(runId, conn, proxy, sshExec2);
|
|
1108
|
-
if (logs)
|
|
1109
|
-
return { content: [{ type: "text", text:
|
|
1108
|
+
if (logs) text13 += "\n\n--- Logs ---\n" + logs;
|
|
1109
|
+
return { content: [{ type: "text", text: text13 }] };
|
|
1110
1110
|
}
|
|
1111
1111
|
}
|
|
1112
1112
|
return {
|
|
@@ -3793,10 +3793,10 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
3793
3793
|
// }) as any;
|
|
3794
3794
|
// return merged;
|
|
3795
3795
|
// }
|
|
3796
|
-
catchall(
|
|
3796
|
+
catchall(index10) {
|
|
3797
3797
|
return new _ZodObject({
|
|
3798
3798
|
...this._def,
|
|
3799
|
-
catchall:
|
|
3799
|
+
catchall: index10
|
|
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
|
|
4118
|
-
const itemA = a[
|
|
4119
|
-
const itemB = b[
|
|
4117
|
+
for (let index10 = 0; index10 < a.length; index10++) {
|
|
4118
|
+
const itemA = a[index10];
|
|
4119
|
+
const itemB = b[index10];
|
|
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],
|
|
4325
|
+
const pairs = [...ctx.data.entries()].map(([key, value], index10) => {
|
|
4326
4326
|
return {
|
|
4327
|
-
key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [
|
|
4328
|
-
value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [
|
|
4327
|
+
key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index10, "key"])),
|
|
4328
|
+
value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index10, "value"]))
|
|
4329
4329
|
};
|
|
4330
4330
|
});
|
|
4331
4331
|
if (ctx.common.async) {
|
|
@@ -6123,6 +6123,128 @@ pgTable(
|
|
|
6123
6123
|
index("dns_migration_mailbox_migration_idx").on(table.migrationId)
|
|
6124
6124
|
]
|
|
6125
6125
|
);
|
|
6126
|
+
var directoryLinkType = pgEnum("directory_link_type", [
|
|
6127
|
+
"dofollow",
|
|
6128
|
+
"nofollow",
|
|
6129
|
+
"conditional"
|
|
6130
|
+
]);
|
|
6131
|
+
var directoryPricing = pgEnum("directory_pricing", [
|
|
6132
|
+
"free",
|
|
6133
|
+
"freemium",
|
|
6134
|
+
"paid"
|
|
6135
|
+
]);
|
|
6136
|
+
var directoryRegion = pgEnum("directory_region", ["nl", "intl"]);
|
|
6137
|
+
var directoryAutomationLevel = pgEnum("directory_automation_level", [
|
|
6138
|
+
"auto",
|
|
6139
|
+
"semi",
|
|
6140
|
+
"manual"
|
|
6141
|
+
]);
|
|
6142
|
+
var directorySubmissionStatus = pgEnum(
|
|
6143
|
+
"directory_submission_status",
|
|
6144
|
+
[
|
|
6145
|
+
"pending",
|
|
6146
|
+
"queued",
|
|
6147
|
+
"submitted",
|
|
6148
|
+
"verification_needed",
|
|
6149
|
+
"awaiting_review",
|
|
6150
|
+
"live",
|
|
6151
|
+
"rejected",
|
|
6152
|
+
"failed",
|
|
6153
|
+
"manual"
|
|
6154
|
+
]
|
|
6155
|
+
);
|
|
6156
|
+
var linkDirectory = pgTable(
|
|
6157
|
+
"link_directory",
|
|
6158
|
+
{
|
|
6159
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
6160
|
+
name: text("name").notNull(),
|
|
6161
|
+
url: text("url").notNull(),
|
|
6162
|
+
submitUrl: text("submit_url").notNull(),
|
|
6163
|
+
dr: integer("dr").notNull().default(0),
|
|
6164
|
+
linkType: directoryLinkType("link_type").notNull().default("nofollow"),
|
|
6165
|
+
pricing: directoryPricing("pricing").notNull().default("free"),
|
|
6166
|
+
category: text("category").notNull().default("General Directory"),
|
|
6167
|
+
region: directoryRegion("region").notNull().default("intl"),
|
|
6168
|
+
automationLevel: directoryAutomationLevel("automation_level").notNull().default("auto"),
|
|
6169
|
+
enabled: boolean("enabled").notNull().default(false),
|
|
6170
|
+
formMapping: jsonb("form_mapping").$type(),
|
|
6171
|
+
lastCheckedAt: timestamp("last_checked_at", { withTimezone: true }),
|
|
6172
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
6173
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
6174
|
+
},
|
|
6175
|
+
(table) => [
|
|
6176
|
+
uniqueIndex("link_directory_submit_url_uidx").on(table.submitUrl),
|
|
6177
|
+
index("link_directory_enabled_dr_idx").on(table.enabled, table.dr),
|
|
6178
|
+
index("link_directory_region_idx").on(table.region)
|
|
6179
|
+
]
|
|
6180
|
+
);
|
|
6181
|
+
var linkBuildingClient = pgTable(
|
|
6182
|
+
"link_building_client",
|
|
6183
|
+
{
|
|
6184
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
6185
|
+
name: text("name").notNull(),
|
|
6186
|
+
websiteUrl: text("website_url").notNull(),
|
|
6187
|
+
mailboxAddress: text("mailbox_address"),
|
|
6188
|
+
refrontMailAccountId: text("refront_mail_account_id"),
|
|
6189
|
+
profile: jsonb("profile").$type().notNull().default({}),
|
|
6190
|
+
weeklyPace: integer("weekly_pace").notNull().default(12),
|
|
6191
|
+
autoSubmit: boolean("auto_submit").notNull().default(false),
|
|
6192
|
+
startingDr: doublePrecision("starting_dr"),
|
|
6193
|
+
currentDr: doublePrecision("current_dr"),
|
|
6194
|
+
isActive: boolean("is_active").notNull().default(true),
|
|
6195
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
6196
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
6197
|
+
},
|
|
6198
|
+
(table) => [
|
|
6199
|
+
uniqueIndex("link_building_client_website_uidx").on(table.websiteUrl),
|
|
6200
|
+
index("link_building_client_active_idx").on(table.isActive)
|
|
6201
|
+
]
|
|
6202
|
+
);
|
|
6203
|
+
pgTable(
|
|
6204
|
+
"directory_submission",
|
|
6205
|
+
{
|
|
6206
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
6207
|
+
clientId: uuid("client_id").notNull().references(() => linkBuildingClient.id, { onDelete: "cascade" }),
|
|
6208
|
+
directoryId: uuid("directory_id").notNull().references(() => linkDirectory.id, { onDelete: "cascade" }),
|
|
6209
|
+
status: directorySubmissionStatus("status").notNull().default("pending"),
|
|
6210
|
+
listingUrl: text("listing_url"),
|
|
6211
|
+
dofollowConfirmed: boolean("dofollow_confirmed"),
|
|
6212
|
+
screenshotPath: text("screenshot_path"),
|
|
6213
|
+
log: jsonb("log").$type().notNull().default({}),
|
|
6214
|
+
queuedAt: timestamp("queued_at", { withTimezone: true }),
|
|
6215
|
+
submittedAt: timestamp("submitted_at", { withTimezone: true }),
|
|
6216
|
+
verifiedAt: timestamp("verified_at", { withTimezone: true }),
|
|
6217
|
+
lastError: text("last_error"),
|
|
6218
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
6219
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
6220
|
+
},
|
|
6221
|
+
(table) => [
|
|
6222
|
+
uniqueIndex("directory_submission_client_directory_uidx").on(
|
|
6223
|
+
table.clientId,
|
|
6224
|
+
table.directoryId
|
|
6225
|
+
),
|
|
6226
|
+
index("directory_submission_status_idx").on(table.status),
|
|
6227
|
+
index("directory_submission_client_status_idx").on(
|
|
6228
|
+
table.clientId,
|
|
6229
|
+
table.status
|
|
6230
|
+
)
|
|
6231
|
+
]
|
|
6232
|
+
);
|
|
6233
|
+
pgTable(
|
|
6234
|
+
"client_dr_snapshot",
|
|
6235
|
+
{
|
|
6236
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
6237
|
+
clientId: uuid("client_id").notNull().references(() => linkBuildingClient.id, { onDelete: "cascade" }),
|
|
6238
|
+
dr: doublePrecision("dr").notNull(),
|
|
6239
|
+
measuredAt: timestamp("measured_at", { withTimezone: true }).notNull().defaultNow()
|
|
6240
|
+
},
|
|
6241
|
+
(table) => [
|
|
6242
|
+
index("client_dr_snapshot_client_measured_idx").on(
|
|
6243
|
+
table.clientId,
|
|
6244
|
+
table.measuredAt
|
|
6245
|
+
)
|
|
6246
|
+
]
|
|
6247
|
+
);
|
|
6126
6248
|
var githubToken = pgTable(
|
|
6127
6249
|
"github_token",
|
|
6128
6250
|
{
|
|
@@ -6253,6 +6375,47 @@ pgTable(
|
|
|
6253
6375
|
index("content_ingestion_runs_project_idx").on(table.projectKey)
|
|
6254
6376
|
]
|
|
6255
6377
|
);
|
|
6378
|
+
var refrontCustomer = pgTable(
|
|
6379
|
+
"refront_customer",
|
|
6380
|
+
{
|
|
6381
|
+
id: uuid("id").primaryKey(),
|
|
6382
|
+
name: text("name").notNull(),
|
|
6383
|
+
status: text("status"),
|
|
6384
|
+
teamId: text("team_id"),
|
|
6385
|
+
teamName: text("team_name"),
|
|
6386
|
+
syncedAt: timestamp("synced_at", { withTimezone: true }).notNull(),
|
|
6387
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
6388
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
6389
|
+
},
|
|
6390
|
+
(table) => [
|
|
6391
|
+
index("idx_refront_customer_status").on(table.status),
|
|
6392
|
+
index("idx_refront_customer_name").on(table.name)
|
|
6393
|
+
]
|
|
6394
|
+
);
|
|
6395
|
+
pgTable(
|
|
6396
|
+
"refront_project",
|
|
6397
|
+
{
|
|
6398
|
+
id: uuid("id").primaryKey(),
|
|
6399
|
+
name: text("name").notNull(),
|
|
6400
|
+
customerId: uuid("customer_id").references(() => refrontCustomer.id, {
|
|
6401
|
+
onDelete: "set null"
|
|
6402
|
+
}),
|
|
6403
|
+
status: text("status"),
|
|
6404
|
+
internal: boolean("internal").notNull().default(false),
|
|
6405
|
+
/** Ticket prefix code when known (e.g. MBC from 2026-MBC-*). */
|
|
6406
|
+
code: text("code"),
|
|
6407
|
+
teamId: text("team_id"),
|
|
6408
|
+
teamName: text("team_name"),
|
|
6409
|
+
syncedAt: timestamp("synced_at", { withTimezone: true }).notNull(),
|
|
6410
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
6411
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
6412
|
+
},
|
|
6413
|
+
(table) => [
|
|
6414
|
+
index("idx_refront_project_customer").on(table.customerId),
|
|
6415
|
+
index("idx_refront_project_status").on(table.status),
|
|
6416
|
+
index("idx_refront_project_code").on(table.code)
|
|
6417
|
+
]
|
|
6418
|
+
);
|
|
6256
6419
|
pgTable(
|
|
6257
6420
|
"refront_source_sync_state",
|
|
6258
6421
|
{
|
|
@@ -7746,7 +7909,7 @@ function getEncryptionKey() {
|
|
|
7746
7909
|
throw new Error("ENCRYPTION_KEY must be a 64-character hex string");
|
|
7747
7910
|
return buf;
|
|
7748
7911
|
}
|
|
7749
|
-
function encrypt(
|
|
7912
|
+
function encrypt(text13) {
|
|
7750
7913
|
const key = getEncryptionKey();
|
|
7751
7914
|
const iv = randomBytes(ENC_IV_LENGTH);
|
|
7752
7915
|
const cipher = createCipheriv(
|
|
@@ -7754,7 +7917,7 @@ function encrypt(text11) {
|
|
|
7754
7917
|
new Uint8Array(key),
|
|
7755
7918
|
new Uint8Array(iv)
|
|
7756
7919
|
);
|
|
7757
|
-
let encrypted = cipher.update(
|
|
7920
|
+
let encrypted = cipher.update(text13, "utf8", "hex");
|
|
7758
7921
|
encrypted += cipher.final("hex");
|
|
7759
7922
|
const authTag = cipher.getAuthTag();
|
|
7760
7923
|
return Buffer.concat([
|
|
@@ -8474,10 +8637,10 @@ async function r2GetObjectRange(bucket, key, range) {
|
|
|
8474
8637
|
const body = result.Body;
|
|
8475
8638
|
if (!body?.transformToString)
|
|
8476
8639
|
throw new Error("R2 returned no readable body");
|
|
8477
|
-
const
|
|
8640
|
+
const text13 = await body.transformToString();
|
|
8478
8641
|
const header = `# range: bytes ${range.offset}-${end} of ${size} (${effectiveLen} bytes)`;
|
|
8479
8642
|
return `${header}
|
|
8480
|
-
${
|
|
8643
|
+
${text13}`;
|
|
8481
8644
|
} catch (e) {
|
|
8482
8645
|
throw r2WrapError(bucket, key, e);
|
|
8483
8646
|
}
|
|
@@ -8840,15 +9003,15 @@ async function sftpRead(opts, filePath, proxy, options) {
|
|
|
8840
9003
|
clearTimeout(timer);
|
|
8841
9004
|
cleanup?.();
|
|
8842
9005
|
cleanup = void 0;
|
|
8843
|
-
const
|
|
9006
|
+
const text13 = Buffer.concat(
|
|
8844
9007
|
chunks.map((ch) => new Uint8Array(ch))
|
|
8845
9008
|
).toString("utf-8");
|
|
8846
9009
|
if (!isWholeFileRequest) {
|
|
8847
9010
|
const header = `# range: bytes ${offset}-${offset + effectiveLen - 1} of ${total} (${effectiveLen} bytes)`;
|
|
8848
9011
|
resolve(`${header}
|
|
8849
|
-
${
|
|
9012
|
+
${text13}`);
|
|
8850
9013
|
} else {
|
|
8851
|
-
resolve(
|
|
9014
|
+
resolve(text13);
|
|
8852
9015
|
}
|
|
8853
9016
|
});
|
|
8854
9017
|
rs.on("error", (e) => {
|
|
@@ -8995,11 +9158,11 @@ function getKnownContainers(serverId, maxAgeMs = 5 * 6e4) {
|
|
|
8995
9158
|
if (Date.now() - e.capturedAt > maxAgeMs) return void 0;
|
|
8996
9159
|
return e.names;
|
|
8997
9160
|
}
|
|
8998
|
-
function truncateForLLM(
|
|
8999
|
-
const totalBytes = Buffer.byteLength(
|
|
9161
|
+
function truncateForLLM(text13, maxBytes) {
|
|
9162
|
+
const totalBytes = Buffer.byteLength(text13, "utf8");
|
|
9000
9163
|
if (totalBytes <= maxBytes)
|
|
9001
|
-
return { text:
|
|
9002
|
-
const buf = Buffer.from(
|
|
9164
|
+
return { text: text13, truncated: false, totalBytes, shownBytes: totalBytes };
|
|
9165
|
+
const buf = Buffer.from(text13, "utf8");
|
|
9003
9166
|
let cut = maxBytes;
|
|
9004
9167
|
while (cut > 0 && (buf[cut] & 192) === 128) cut--;
|
|
9005
9168
|
const head = buf.subarray(0, cut).toString("utf8");
|
|
@@ -9030,10 +9193,10 @@ function postprocessResult(result, meta) {
|
|
|
9030
9193
|
if (!result.content?.length) return result;
|
|
9031
9194
|
if (RAW_JSON_TOOLS.has(meta.toolName)) return result;
|
|
9032
9195
|
const block = result.content[0];
|
|
9033
|
-
let
|
|
9034
|
-
const trunc = truncateForLLM(
|
|
9196
|
+
let text13 = String(block.text ?? "");
|
|
9197
|
+
const trunc = truncateForLLM(text13, RESPONSE_MAX_BYTES);
|
|
9035
9198
|
if (trunc.truncated) {
|
|
9036
|
-
|
|
9199
|
+
text13 = trunc.text + "\n\n... " + buildTruncationHint(
|
|
9037
9200
|
meta.toolName,
|
|
9038
9201
|
meta.args,
|
|
9039
9202
|
trunc.totalBytes,
|
|
@@ -9047,11 +9210,11 @@ function postprocessResult(result, meta) {
|
|
|
9047
9210
|
const parts = [`took ${tookStr}`, sizeStr];
|
|
9048
9211
|
if (meta.serverIdLabel) parts.push(`server: ${meta.serverIdLabel}`);
|
|
9049
9212
|
if (meta.cached) parts.push("cached");
|
|
9050
|
-
|
|
9213
|
+
text13 = `${text13}
|
|
9051
9214
|
|
|
9052
9215
|
[${parts.join(", ")}]`;
|
|
9053
9216
|
}
|
|
9054
|
-
return { ...result, content: [{ ...block, text:
|
|
9217
|
+
return { ...result, content: [{ ...block, text: text13 }] };
|
|
9055
9218
|
}
|
|
9056
9219
|
function buildPipelineScript(commands, shell, marker, stopOnError) {
|
|
9057
9220
|
if (shell === "powershell") {
|
|
@@ -9837,11 +10000,11 @@ CREATE TABLE IF NOT EXISTS _mcp_migrations (
|
|
|
9837
10000
|
applied_by TEXT
|
|
9838
10001
|
);
|
|
9839
10002
|
`.trim();
|
|
9840
|
-
function normaliseMigrationSql(
|
|
9841
|
-
return
|
|
10003
|
+
function normaliseMigrationSql(sql28) {
|
|
10004
|
+
return sql28.replace(/\r\n/g, "\n").trim() + "\n";
|
|
9842
10005
|
}
|
|
9843
|
-
function migrationSha256(
|
|
9844
|
-
return createHash("sha256").update(
|
|
10006
|
+
function migrationSha256(sql28) {
|
|
10007
|
+
return createHash("sha256").update(sql28.replace(/\r\n/g, "\n"), "utf8").digest("hex");
|
|
9845
10008
|
}
|
|
9846
10009
|
function dollarQuoteTag(value) {
|
|
9847
10010
|
let tag = "_mcp";
|
|
@@ -11571,6 +11734,10 @@ var TOOLS = [
|
|
|
11571
11734
|
limit: {
|
|
11572
11735
|
type: "number",
|
|
11573
11736
|
description: "Max pages to return (1-20, default 5)."
|
|
11737
|
+
},
|
|
11738
|
+
includeArchived: {
|
|
11739
|
+
type: "boolean",
|
|
11740
|
+
description: "Include lifecycle-archived pages (decommissioned systems). Default false \u2014 archived is hidden unless you opt in."
|
|
11574
11741
|
}
|
|
11575
11742
|
},
|
|
11576
11743
|
required: ["query"]
|
|
@@ -11590,6 +11757,35 @@ var TOOLS = [
|
|
|
11590
11757
|
required: ["slug"]
|
|
11591
11758
|
}
|
|
11592
11759
|
},
|
|
11760
|
+
{
|
|
11761
|
+
name: "flag-wiki-page",
|
|
11762
|
+
description: "Report that a knowledge-wiki page was WRONG, outdated or incomplete when you actually used it during real work. This is the wiki's feedback loop: open flags jump the daily reviewer queue and show in the backoffice review panel, so the page gets fixed instead of misleading the next agent. Call it right after discovering the mismatch, with a concrete `detail` of what was wrong and what turned out to be true.",
|
|
11763
|
+
inputSchema: {
|
|
11764
|
+
type: "object",
|
|
11765
|
+
properties: {
|
|
11766
|
+
slug: {
|
|
11767
|
+
type: "string",
|
|
11768
|
+
description: "Slug of the page that misled you, e.g. 'wiki/known-issues/pm2-stale-env-after-reload'."
|
|
11769
|
+
},
|
|
11770
|
+
kind: {
|
|
11771
|
+
type: "string",
|
|
11772
|
+
enum: [
|
|
11773
|
+
"feedback",
|
|
11774
|
+
"stale",
|
|
11775
|
+
"duplicate",
|
|
11776
|
+
"unverified",
|
|
11777
|
+
"obsolete-candidate"
|
|
11778
|
+
],
|
|
11779
|
+
description: "feedback (default) = wrong/incomplete in practice; stale = outdated vs current reality; duplicate = covers the same thing as another page; obsolete-candidate = the described system/practice appears no longer in use."
|
|
11780
|
+
},
|
|
11781
|
+
detail: {
|
|
11782
|
+
type: "string",
|
|
11783
|
+
description: "What was wrong and what is actually true (be concrete: the claim, the observed reality, ticket/commit refs if any). Min 5 chars."
|
|
11784
|
+
}
|
|
11785
|
+
},
|
|
11786
|
+
required: ["slug", "detail"]
|
|
11787
|
+
}
|
|
11788
|
+
},
|
|
11593
11789
|
// ----- Cursor Remote (Agent Control) -----
|
|
11594
11790
|
{
|
|
11595
11791
|
name: "cursor-remote-list",
|
|
@@ -11899,7 +12095,7 @@ async function executeToolCall(name, a, _serverId) {
|
|
|
11899
12095
|
]
|
|
11900
12096
|
};
|
|
11901
12097
|
}
|
|
11902
|
-
const lines = data.hits.map((hit,
|
|
12098
|
+
const lines = data.hits.map((hit, index10) => {
|
|
11903
12099
|
const when = hit.lastMessageAt ? new Date(hit.lastMessageAt).toISOString().slice(0, 10) : "unknown date";
|
|
11904
12100
|
const repo = hit.repo ?? "unknown repo";
|
|
11905
12101
|
const sim = hit.similarity !== null ? ` \xB7 ${(hit.similarity * 100).toFixed(0)}% match` : "";
|
|
@@ -11909,7 +12105,7 @@ async function executeToolCall(name, a, _serverId) {
|
|
|
11909
12105
|
...Array.isArray(hit.tech) ? hit.tech.slice(0, 4) : []
|
|
11910
12106
|
].filter(Boolean);
|
|
11911
12107
|
const tags = facets.length > 0 ? ` \xB7 ${facets.join(", ")}` : "";
|
|
11912
|
-
return `${
|
|
12108
|
+
return `${index10 + 1}. [${repo} \xB7 ${when}${sim}${tags}] ${hit.title}
|
|
11913
12109
|
id: ${hit.id}
|
|
11914
12110
|
${(hit.summary ?? hit.snippet).replace(/\s+/g, " ").slice(0, 500)}`;
|
|
11915
12111
|
});
|
|
@@ -12025,7 +12221,8 @@ ${facets.join(", ")}` : ""),
|
|
|
12025
12221
|
},
|
|
12026
12222
|
body: JSON.stringify({
|
|
12027
12223
|
query,
|
|
12028
|
-
limit: typeof a.limit === "number" ? a.limit : void 0
|
|
12224
|
+
limit: typeof a.limit === "number" ? a.limit : void 0,
|
|
12225
|
+
includeArchived: typeof a.includeArchived === "boolean" ? a.includeArchived : void 0
|
|
12029
12226
|
})
|
|
12030
12227
|
});
|
|
12031
12228
|
if (!res.ok) {
|
|
@@ -12050,12 +12247,12 @@ ${facets.join(", ")}` : ""),
|
|
|
12050
12247
|
]
|
|
12051
12248
|
};
|
|
12052
12249
|
}
|
|
12053
|
-
const lines = data.hits.map((hit,
|
|
12250
|
+
const lines = data.hits.map((hit, index10) => {
|
|
12054
12251
|
const sim = hit.similarity !== null ? ` \xB7 ${Math.round(hit.similarity * 100)}% match` : "";
|
|
12055
12252
|
const tags = hit.tags.length ? ` \xB7 ${hit.tags.slice(0, 5).join(", ")}` : "";
|
|
12056
12253
|
const sources = hit.sources.length ? `
|
|
12057
12254
|
sources: ${hit.sources.slice(0, 6).map((s) => `${s.type}:${s.ref}`).join(", ")}` : "";
|
|
12058
|
-
return `${
|
|
12255
|
+
return `${index10 + 1}. [${hit.status} \xB7 updated ${hit.pageUpdatedOn ?? "unknown"}${sim}${tags}] ${hit.title}
|
|
12059
12256
|
slug: ${hit.slug}${sources}
|
|
12060
12257
|
${(hit.summary ?? hit.snippet).replace(/\s+/g, " ").slice(0, 400)}`;
|
|
12061
12258
|
});
|
|
@@ -12119,6 +12316,66 @@ Sources: ${page.sources.map((s) => `${s.type}:${s.ref}`).join(", ")}` : "";
|
|
|
12119
12316
|
]
|
|
12120
12317
|
};
|
|
12121
12318
|
}
|
|
12319
|
+
// ----- Knowledge wiki: feedback flag -----
|
|
12320
|
+
case "flag-wiki-page": {
|
|
12321
|
+
const slug = typeof a.slug === "string" ? a.slug.trim() : "";
|
|
12322
|
+
const detail = typeof a.detail === "string" ? a.detail.trim() : "";
|
|
12323
|
+
if (!slug || detail.length < 5) {
|
|
12324
|
+
return {
|
|
12325
|
+
content: [
|
|
12326
|
+
{
|
|
12327
|
+
type: "text",
|
|
12328
|
+
text: "Error: slug and a concrete detail (min 5 chars) are required"
|
|
12329
|
+
}
|
|
12330
|
+
]
|
|
12331
|
+
};
|
|
12332
|
+
}
|
|
12333
|
+
const kind = typeof a.kind === "string" && [
|
|
12334
|
+
"feedback",
|
|
12335
|
+
"stale",
|
|
12336
|
+
"duplicate",
|
|
12337
|
+
"unverified",
|
|
12338
|
+
"obsolete-candidate"
|
|
12339
|
+
].includes(a.kind) ? a.kind : "feedback";
|
|
12340
|
+
const res = await fetch(`${dashboardBaseUrl}/api/wiki/flag`, {
|
|
12341
|
+
method: "POST",
|
|
12342
|
+
headers: {
|
|
12343
|
+
"content-type": "application/json",
|
|
12344
|
+
authorization: `Bearer ${apiKey}`
|
|
12345
|
+
},
|
|
12346
|
+
body: JSON.stringify({ slug, kind, detail })
|
|
12347
|
+
});
|
|
12348
|
+
if (!res.ok) {
|
|
12349
|
+
const errDetail = await res.text().catch(() => "");
|
|
12350
|
+
return {
|
|
12351
|
+
content: [
|
|
12352
|
+
{
|
|
12353
|
+
type: "text",
|
|
12354
|
+
text: `Error: wiki flag failed (${res.status}). ${errDetail.slice(0, 300)}`
|
|
12355
|
+
}
|
|
12356
|
+
]
|
|
12357
|
+
};
|
|
12358
|
+
}
|
|
12359
|
+
const data = await res.json();
|
|
12360
|
+
if (!data.found || !data.flag) {
|
|
12361
|
+
return {
|
|
12362
|
+
content: [
|
|
12363
|
+
{
|
|
12364
|
+
type: "text",
|
|
12365
|
+
text: `No wiki page found for slug "${slug}" \u2014 nothing flagged. Check the slug via search-wiki.`
|
|
12366
|
+
}
|
|
12367
|
+
]
|
|
12368
|
+
};
|
|
12369
|
+
}
|
|
12370
|
+
return {
|
|
12371
|
+
content: [
|
|
12372
|
+
{
|
|
12373
|
+
type: "text",
|
|
12374
|
+
text: `Flagged ${data.flag.slug} (${kind}). The daily wiki reviewer will pick it up next run; it also shows in the backoffice review queue.`
|
|
12375
|
+
}
|
|
12376
|
+
]
|
|
12377
|
+
};
|
|
12378
|
+
}
|
|
12122
12379
|
// ----- Cursor Remote (Agent Control) -----
|
|
12123
12380
|
case "cursor-remote-list": {
|
|
12124
12381
|
const onlineOnly = a.onlineOnly === true;
|
|
@@ -13202,8 +13459,8 @@ ${sample.join("\n")}${files.length > 5 ? `
|
|
|
13202
13459
|
};
|
|
13203
13460
|
const filtered = sortRows(applyFilter(only.rows));
|
|
13204
13461
|
if (format === "json") {
|
|
13205
|
-
const
|
|
13206
|
-
return { content: [{ type: "text", text:
|
|
13462
|
+
const text14 = filtered.map((c) => JSON.stringify(c)).join("\n") || "(no containers)";
|
|
13463
|
+
return { content: [{ type: "text", text: text14 }] };
|
|
13207
13464
|
}
|
|
13208
13465
|
if (groupByProject) {
|
|
13209
13466
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -13230,8 +13487,8 @@ ${sample.join("\n")}${files.length > 5 ? `
|
|
|
13230
13487
|
}
|
|
13231
13488
|
const header = `${"NAMES".padEnd(36)} ${"IMAGE".padEnd(40)} ${"STATUS".padEnd(24)} ${"HEALTH".padEnd(10)} ${"PORTS".padEnd(40)} PROJECT`;
|
|
13232
13489
|
const body = filtered.map((r) => `${fmtRow(r)} ${r.Project || ""}`);
|
|
13233
|
-
const
|
|
13234
|
-
return { content: [{ type: "text", text:
|
|
13490
|
+
const text13 = filtered.length === 0 ? "(no containers match)" : [header, ...body].join("\n");
|
|
13491
|
+
return { content: [{ type: "text", text: text13 }] };
|
|
13235
13492
|
}
|
|
13236
13493
|
if (format === "json") {
|
|
13237
13494
|
const lines = [];
|
package/package.json
CHANGED