@mgsoftwarebv/mg-dashboard-mcp 7.4.7 → 7.4.9
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 +257 -43
- 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, doublePrecision, foreignKey } from 'drizzle-orm/pg-core';
|
|
23
|
+
import { pgTable, timestamp, jsonb, uuid, boolean, text, pgEnum, integer, uniqueIndex, index, check, bigint, doublePrecision, foreignKey, date, real } 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;
|
|
@@ -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 text14 = `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: text14 }] };
|
|
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 text14 = formatRunDetail(run);
|
|
1083
|
+
if (logs) text14 += "\n\n--- Logs ---\n" + logs;
|
|
1084
|
+
return { content: [{ type: "text", text: text14 }] };
|
|
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 text14 = formatRunDetail(run);
|
|
1107
1107
|
const logs = await fetchRunLogs(runId, conn, proxy, sshExec2);
|
|
1108
|
-
if (logs)
|
|
1109
|
-
return { content: [{ type: "text", text:
|
|
1108
|
+
if (logs) text14 += "\n\n--- Logs ---\n" + logs;
|
|
1109
|
+
return { content: [{ type: "text", text: text14 }] };
|
|
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(index11) {
|
|
3797
3797
|
return new _ZodObject({
|
|
3798
3798
|
...this._def,
|
|
3799
|
-
catchall:
|
|
3799
|
+
catchall: index11
|
|
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 index11 = 0; index11 < a.length; index11++) {
|
|
4118
|
+
const itemA = a[index11];
|
|
4119
|
+
const itemB = b[index11];
|
|
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], index11) => {
|
|
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, [index11, "key"])),
|
|
4328
|
+
value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index11, "value"]))
|
|
4329
4329
|
};
|
|
4330
4330
|
});
|
|
4331
4331
|
if (ctx.common.async) {
|
|
@@ -6153,6 +6153,12 @@ var directorySubmissionStatus = pgEnum(
|
|
|
6153
6153
|
"manual"
|
|
6154
6154
|
]
|
|
6155
6155
|
);
|
|
6156
|
+
var directoryAccountStatus = pgEnum("directory_account_status", [
|
|
6157
|
+
"pending_verification",
|
|
6158
|
+
"active",
|
|
6159
|
+
"failed",
|
|
6160
|
+
"captcha_blocked"
|
|
6161
|
+
]);
|
|
6156
6162
|
var linkDirectory = pgTable(
|
|
6157
6163
|
"link_directory",
|
|
6158
6164
|
{
|
|
@@ -6245,6 +6251,32 @@ pgTable(
|
|
|
6245
6251
|
)
|
|
6246
6252
|
]
|
|
6247
6253
|
);
|
|
6254
|
+
pgTable(
|
|
6255
|
+
"directory_account",
|
|
6256
|
+
{
|
|
6257
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
6258
|
+
clientId: uuid("client_id").notNull().references(() => linkBuildingClient.id, { onDelete: "cascade" }),
|
|
6259
|
+
directoryId: uuid("directory_id").notNull().references(() => linkDirectory.id, { onDelete: "cascade" }),
|
|
6260
|
+
email: text("email").notNull(),
|
|
6261
|
+
passwordEncrypted: text("password_encrypted").notNull(),
|
|
6262
|
+
status: directoryAccountStatus("status").notNull().default("pending_verification"),
|
|
6263
|
+
registerUrl: text("register_url"),
|
|
6264
|
+
loginUrl: text("login_url"),
|
|
6265
|
+
lastError: text("last_error"),
|
|
6266
|
+
registeredAt: timestamp("registered_at", { withTimezone: true }),
|
|
6267
|
+
verifiedAt: timestamp("verified_at", { withTimezone: true }),
|
|
6268
|
+
lastLoginAt: timestamp("last_login_at", { withTimezone: true }),
|
|
6269
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
6270
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
6271
|
+
},
|
|
6272
|
+
(table) => [
|
|
6273
|
+
uniqueIndex("directory_account_client_directory_uidx").on(
|
|
6274
|
+
table.clientId,
|
|
6275
|
+
table.directoryId
|
|
6276
|
+
),
|
|
6277
|
+
index("directory_account_status_idx").on(table.status)
|
|
6278
|
+
]
|
|
6279
|
+
);
|
|
6248
6280
|
var githubToken = pgTable(
|
|
6249
6281
|
"github_token",
|
|
6250
6282
|
{
|
|
@@ -6506,6 +6538,97 @@ pgTable(
|
|
|
6506
6538
|
}).onDelete("cascade")
|
|
6507
6539
|
]
|
|
6508
6540
|
);
|
|
6541
|
+
pgTable(
|
|
6542
|
+
"wiki_page",
|
|
6543
|
+
{
|
|
6544
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
6545
|
+
slug: text("slug").notNull().unique(),
|
|
6546
|
+
title: text("title").notNull().default(""),
|
|
6547
|
+
summary: text("summary"),
|
|
6548
|
+
content: text("content").notNull().default(""),
|
|
6549
|
+
status: text("status").notNull().default("draft"),
|
|
6550
|
+
pageUpdatedOn: date("page_updated_on"),
|
|
6551
|
+
reviewedBy: text("reviewed_by"),
|
|
6552
|
+
reviewedOn: date("reviewed_on"),
|
|
6553
|
+
lastVerifiedOn: date("last_verified_on"),
|
|
6554
|
+
verifyCount: integer("verify_count").notNull().default(0),
|
|
6555
|
+
verifyNote: text("verify_note"),
|
|
6556
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
6557
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
6558
|
+
},
|
|
6559
|
+
(table) => [
|
|
6560
|
+
index("idx_wiki_page_status").on(table.status),
|
|
6561
|
+
index("idx_wiki_page_last_verified").on(table.lastVerifiedOn)
|
|
6562
|
+
]
|
|
6563
|
+
);
|
|
6564
|
+
pgTable(
|
|
6565
|
+
"wiki_page_flag",
|
|
6566
|
+
{
|
|
6567
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
6568
|
+
pageSlug: text("page_slug").notNull(),
|
|
6569
|
+
kind: text("kind").notNull(),
|
|
6570
|
+
detail: text("detail").notNull().default(""),
|
|
6571
|
+
createdBy: text("created_by"),
|
|
6572
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
6573
|
+
resolvedAt: timestamp("resolved_at", { withTimezone: true }),
|
|
6574
|
+
resolvedBy: text("resolved_by")
|
|
6575
|
+
},
|
|
6576
|
+
(table) => [index("idx_wiki_page_flag_created").on(table.createdAt)]
|
|
6577
|
+
);
|
|
6578
|
+
pgTable(
|
|
6579
|
+
"wiki_page_evidence",
|
|
6580
|
+
{
|
|
6581
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
6582
|
+
pageSlug: text("page_slug").notNull(),
|
|
6583
|
+
evidenceType: text("evidence_type").notNull(),
|
|
6584
|
+
evidenceRef: text("evidence_ref").notNull(),
|
|
6585
|
+
matchScore: real("match_score"),
|
|
6586
|
+
matchReason: text("match_reason"),
|
|
6587
|
+
snippet: text("snippet"),
|
|
6588
|
+
status: text("status").notNull().default("pending"),
|
|
6589
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
6590
|
+
resolvedAt: timestamp("resolved_at", { withTimezone: true })
|
|
6591
|
+
},
|
|
6592
|
+
(table) => [
|
|
6593
|
+
uniqueIndex("wiki_page_evidence_page_slug_evidence_type_evidence_ref_key").on(
|
|
6594
|
+
table.pageSlug,
|
|
6595
|
+
table.evidenceType,
|
|
6596
|
+
table.evidenceRef
|
|
6597
|
+
),
|
|
6598
|
+
index("idx_wiki_page_evidence_created").on(table.createdAt)
|
|
6599
|
+
]
|
|
6600
|
+
);
|
|
6601
|
+
pgTable(
|
|
6602
|
+
"wiki_page_read",
|
|
6603
|
+
{
|
|
6604
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
6605
|
+
slug: text("slug").notNull(),
|
|
6606
|
+
caller: text("caller"),
|
|
6607
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
6608
|
+
},
|
|
6609
|
+
(table) => [
|
|
6610
|
+
index("idx_wiki_page_read_slug").on(table.slug, table.createdAt),
|
|
6611
|
+
index("idx_wiki_page_read_created").on(table.createdAt)
|
|
6612
|
+
]
|
|
6613
|
+
);
|
|
6614
|
+
pgTable(
|
|
6615
|
+
"wiki_verify_event",
|
|
6616
|
+
{
|
|
6617
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
6618
|
+
pageSlug: text("page_slug").notNull(),
|
|
6619
|
+
outcome: text("outcome").notNull(),
|
|
6620
|
+
runMode: text("run_mode"),
|
|
6621
|
+
note: text("note"),
|
|
6622
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
6623
|
+
},
|
|
6624
|
+
(table) => [
|
|
6625
|
+
index("idx_wiki_verify_event_created").on(table.createdAt),
|
|
6626
|
+
index("idx_wiki_verify_event_outcome_created").on(
|
|
6627
|
+
table.outcome,
|
|
6628
|
+
table.createdAt
|
|
6629
|
+
)
|
|
6630
|
+
]
|
|
6631
|
+
);
|
|
6509
6632
|
var GITHUB_API = "https://api.github.com";
|
|
6510
6633
|
var ReleaseProfileQuickCreateError = class extends Error {
|
|
6511
6634
|
constructor(message, code = "INTERNAL_SERVER_ERROR") {
|
|
@@ -7909,7 +8032,7 @@ function getEncryptionKey() {
|
|
|
7909
8032
|
throw new Error("ENCRYPTION_KEY must be a 64-character hex string");
|
|
7910
8033
|
return buf;
|
|
7911
8034
|
}
|
|
7912
|
-
function encrypt(
|
|
8035
|
+
function encrypt(text14) {
|
|
7913
8036
|
const key = getEncryptionKey();
|
|
7914
8037
|
const iv = randomBytes(ENC_IV_LENGTH);
|
|
7915
8038
|
const cipher = createCipheriv(
|
|
@@ -7917,7 +8040,7 @@ function encrypt(text13) {
|
|
|
7917
8040
|
new Uint8Array(key),
|
|
7918
8041
|
new Uint8Array(iv)
|
|
7919
8042
|
);
|
|
7920
|
-
let encrypted = cipher.update(
|
|
8043
|
+
let encrypted = cipher.update(text14, "utf8", "hex");
|
|
7921
8044
|
encrypted += cipher.final("hex");
|
|
7922
8045
|
const authTag = cipher.getAuthTag();
|
|
7923
8046
|
return Buffer.concat([
|
|
@@ -8637,10 +8760,10 @@ async function r2GetObjectRange(bucket, key, range) {
|
|
|
8637
8760
|
const body = result.Body;
|
|
8638
8761
|
if (!body?.transformToString)
|
|
8639
8762
|
throw new Error("R2 returned no readable body");
|
|
8640
|
-
const
|
|
8763
|
+
const text14 = await body.transformToString();
|
|
8641
8764
|
const header = `# range: bytes ${range.offset}-${end} of ${size} (${effectiveLen} bytes)`;
|
|
8642
8765
|
return `${header}
|
|
8643
|
-
${
|
|
8766
|
+
${text14}`;
|
|
8644
8767
|
} catch (e) {
|
|
8645
8768
|
throw r2WrapError(bucket, key, e);
|
|
8646
8769
|
}
|
|
@@ -9003,15 +9126,15 @@ async function sftpRead(opts, filePath, proxy, options) {
|
|
|
9003
9126
|
clearTimeout(timer);
|
|
9004
9127
|
cleanup?.();
|
|
9005
9128
|
cleanup = void 0;
|
|
9006
|
-
const
|
|
9129
|
+
const text14 = Buffer.concat(
|
|
9007
9130
|
chunks.map((ch) => new Uint8Array(ch))
|
|
9008
9131
|
).toString("utf-8");
|
|
9009
9132
|
if (!isWholeFileRequest) {
|
|
9010
9133
|
const header = `# range: bytes ${offset}-${offset + effectiveLen - 1} of ${total} (${effectiveLen} bytes)`;
|
|
9011
9134
|
resolve(`${header}
|
|
9012
|
-
${
|
|
9135
|
+
${text14}`);
|
|
9013
9136
|
} else {
|
|
9014
|
-
resolve(
|
|
9137
|
+
resolve(text14);
|
|
9015
9138
|
}
|
|
9016
9139
|
});
|
|
9017
9140
|
rs.on("error", (e) => {
|
|
@@ -9158,11 +9281,11 @@ function getKnownContainers(serverId, maxAgeMs = 5 * 6e4) {
|
|
|
9158
9281
|
if (Date.now() - e.capturedAt > maxAgeMs) return void 0;
|
|
9159
9282
|
return e.names;
|
|
9160
9283
|
}
|
|
9161
|
-
function truncateForLLM(
|
|
9162
|
-
const totalBytes = Buffer.byteLength(
|
|
9284
|
+
function truncateForLLM(text14, maxBytes) {
|
|
9285
|
+
const totalBytes = Buffer.byteLength(text14, "utf8");
|
|
9163
9286
|
if (totalBytes <= maxBytes)
|
|
9164
|
-
return { text:
|
|
9165
|
-
const buf = Buffer.from(
|
|
9287
|
+
return { text: text14, truncated: false, totalBytes, shownBytes: totalBytes };
|
|
9288
|
+
const buf = Buffer.from(text14, "utf8");
|
|
9166
9289
|
let cut = maxBytes;
|
|
9167
9290
|
while (cut > 0 && (buf[cut] & 192) === 128) cut--;
|
|
9168
9291
|
const head = buf.subarray(0, cut).toString("utf8");
|
|
@@ -9193,10 +9316,10 @@ function postprocessResult(result, meta) {
|
|
|
9193
9316
|
if (!result.content?.length) return result;
|
|
9194
9317
|
if (RAW_JSON_TOOLS.has(meta.toolName)) return result;
|
|
9195
9318
|
const block = result.content[0];
|
|
9196
|
-
let
|
|
9197
|
-
const trunc = truncateForLLM(
|
|
9319
|
+
let text14 = String(block.text ?? "");
|
|
9320
|
+
const trunc = truncateForLLM(text14, RESPONSE_MAX_BYTES);
|
|
9198
9321
|
if (trunc.truncated) {
|
|
9199
|
-
|
|
9322
|
+
text14 = trunc.text + "\n\n... " + buildTruncationHint(
|
|
9200
9323
|
meta.toolName,
|
|
9201
9324
|
meta.args,
|
|
9202
9325
|
trunc.totalBytes,
|
|
@@ -9210,11 +9333,11 @@ function postprocessResult(result, meta) {
|
|
|
9210
9333
|
const parts = [`took ${tookStr}`, sizeStr];
|
|
9211
9334
|
if (meta.serverIdLabel) parts.push(`server: ${meta.serverIdLabel}`);
|
|
9212
9335
|
if (meta.cached) parts.push("cached");
|
|
9213
|
-
|
|
9336
|
+
text14 = `${text14}
|
|
9214
9337
|
|
|
9215
9338
|
[${parts.join(", ")}]`;
|
|
9216
9339
|
}
|
|
9217
|
-
return { ...result, content: [{ ...block, text:
|
|
9340
|
+
return { ...result, content: [{ ...block, text: text14 }] };
|
|
9218
9341
|
}
|
|
9219
9342
|
function buildPipelineScript(commands, shell, marker, stopOnError) {
|
|
9220
9343
|
if (shell === "powershell") {
|
|
@@ -11721,6 +11844,32 @@ var TOOLS = [
|
|
|
11721
11844
|
}
|
|
11722
11845
|
}
|
|
11723
11846
|
},
|
|
11847
|
+
{
|
|
11848
|
+
name: "submit-team-memory",
|
|
11849
|
+
description: "Manually push a curated problem\u2192solution note into the team's searchable memory (agent_memory). Use ONLY when the user explicitly asks to push/share context to team memory (e.g. no agent-host daemon). Do NOT auto-submit. Do NOT dump raw chat. English; no secrets/PII. Pass repo for the current project. Distinct from wiki intake \u2014 this is searchable via search-team-memory.",
|
|
11850
|
+
inputSchema: {
|
|
11851
|
+
type: "object",
|
|
11852
|
+
properties: {
|
|
11853
|
+
title: {
|
|
11854
|
+
type: "string",
|
|
11855
|
+
description: "Short English title for the note (max 300 chars)."
|
|
11856
|
+
},
|
|
11857
|
+
content: {
|
|
11858
|
+
type: "string",
|
|
11859
|
+
description: "Problem / root cause / solution / context markdown (min ~40 chars, max ~24k stored)."
|
|
11860
|
+
},
|
|
11861
|
+
repo: {
|
|
11862
|
+
type: "string",
|
|
11863
|
+
description: "Git repository, e.g. 'github.com/MGSoftwareBV/fenicks' or 'github.com/MGSoftwareBV/mg-boiler'."
|
|
11864
|
+
},
|
|
11865
|
+
externalRef: {
|
|
11866
|
+
type: "string",
|
|
11867
|
+
description: "Optional client dedupe key; re-submitting the same ref upserts the row."
|
|
11868
|
+
}
|
|
11869
|
+
},
|
|
11870
|
+
required: ["title", "content", "repo"]
|
|
11871
|
+
}
|
|
11872
|
+
},
|
|
11724
11873
|
{
|
|
11725
11874
|
name: "search-wiki",
|
|
11726
11875
|
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.",
|
|
@@ -12095,7 +12244,7 @@ async function executeToolCall(name, a, _serverId) {
|
|
|
12095
12244
|
]
|
|
12096
12245
|
};
|
|
12097
12246
|
}
|
|
12098
|
-
const lines = data.hits.map((hit,
|
|
12247
|
+
const lines = data.hits.map((hit, index11) => {
|
|
12099
12248
|
const when = hit.lastMessageAt ? new Date(hit.lastMessageAt).toISOString().slice(0, 10) : "unknown date";
|
|
12100
12249
|
const repo = hit.repo ?? "unknown repo";
|
|
12101
12250
|
const sim = hit.similarity !== null ? ` \xB7 ${(hit.similarity * 100).toFixed(0)}% match` : "";
|
|
@@ -12105,7 +12254,7 @@ async function executeToolCall(name, a, _serverId) {
|
|
|
12105
12254
|
...Array.isArray(hit.tech) ? hit.tech.slice(0, 4) : []
|
|
12106
12255
|
].filter(Boolean);
|
|
12107
12256
|
const tags = facets.length > 0 ? ` \xB7 ${facets.join(", ")}` : "";
|
|
12108
|
-
return `${
|
|
12257
|
+
return `${index11 + 1}. [${repo} \xB7 ${when}${sim}${tags}] ${hit.title}
|
|
12109
12258
|
id: ${hit.id}
|
|
12110
12259
|
${(hit.summary ?? hit.snippet).replace(/\s+/g, " ").slice(0, 500)}`;
|
|
12111
12260
|
});
|
|
@@ -12207,6 +12356,71 @@ ${facets.join(", ")}` : ""),
|
|
|
12207
12356
|
]
|
|
12208
12357
|
};
|
|
12209
12358
|
}
|
|
12359
|
+
// ----- Team memory: manual curated submit (no daemon) -----
|
|
12360
|
+
case "submit-team-memory": {
|
|
12361
|
+
const title = typeof a.title === "string" ? a.title.trim() : "";
|
|
12362
|
+
const content = typeof a.content === "string" ? a.content.trim() : "";
|
|
12363
|
+
const repo = typeof a.repo === "string" ? a.repo.trim() : "";
|
|
12364
|
+
const externalRef = typeof a.externalRef === "string" ? a.externalRef.trim() : void 0;
|
|
12365
|
+
if (!title || !content || !repo) {
|
|
12366
|
+
return {
|
|
12367
|
+
content: [
|
|
12368
|
+
{
|
|
12369
|
+
type: "text",
|
|
12370
|
+
text: "Error: title, content, and repo are required."
|
|
12371
|
+
}
|
|
12372
|
+
]
|
|
12373
|
+
};
|
|
12374
|
+
}
|
|
12375
|
+
if (content.length < 40) {
|
|
12376
|
+
return {
|
|
12377
|
+
content: [
|
|
12378
|
+
{
|
|
12379
|
+
type: "text",
|
|
12380
|
+
text: "Error: content must be at least 40 characters (curated problem\u2192solution, not a one-liner)."
|
|
12381
|
+
}
|
|
12382
|
+
]
|
|
12383
|
+
};
|
|
12384
|
+
}
|
|
12385
|
+
const res = await fetch(`${dashboardBaseUrl}/api/team-memory/submit`, {
|
|
12386
|
+
method: "POST",
|
|
12387
|
+
headers: {
|
|
12388
|
+
"content-type": "application/json",
|
|
12389
|
+
authorization: `Bearer ${apiKey}`
|
|
12390
|
+
},
|
|
12391
|
+
body: JSON.stringify({
|
|
12392
|
+
title,
|
|
12393
|
+
content,
|
|
12394
|
+
gitRepository: repo,
|
|
12395
|
+
...externalRef ? { externalRef } : {}
|
|
12396
|
+
})
|
|
12397
|
+
});
|
|
12398
|
+
if (!res.ok) {
|
|
12399
|
+
const detail = await res.text().catch(() => "");
|
|
12400
|
+
return {
|
|
12401
|
+
content: [
|
|
12402
|
+
{
|
|
12403
|
+
type: "text",
|
|
12404
|
+
text: `Error: team-memory submit failed (${res.status}). ${detail.slice(0, 400)}`
|
|
12405
|
+
}
|
|
12406
|
+
]
|
|
12407
|
+
};
|
|
12408
|
+
}
|
|
12409
|
+
const data = await res.json();
|
|
12410
|
+
return {
|
|
12411
|
+
content: [
|
|
12412
|
+
{
|
|
12413
|
+
type: "text",
|
|
12414
|
+
text: `Submitted to team memory${data.upserted ? "" : " (unchanged \u2014 identical content)"}.
|
|
12415
|
+
id: ${data.id}
|
|
12416
|
+
localConversationId: ${data.localConversationId}
|
|
12417
|
+
repo: ${repo}
|
|
12418
|
+
summarized: ${data.summarized}, embedded: ${data.embedded}
|
|
12419
|
+
Searchable via search-team-memory once indexing completes (usually immediate).`
|
|
12420
|
+
}
|
|
12421
|
+
]
|
|
12422
|
+
};
|
|
12423
|
+
}
|
|
12210
12424
|
// ----- Knowledge wiki: search -----
|
|
12211
12425
|
case "search-wiki": {
|
|
12212
12426
|
const query = typeof a.query === "string" ? a.query.trim() : "";
|
|
@@ -12237,22 +12451,22 @@ ${facets.join(", ")}` : ""),
|
|
|
12237
12451
|
};
|
|
12238
12452
|
}
|
|
12239
12453
|
const data = await res.json();
|
|
12240
|
-
if (data.count === 0) {
|
|
12454
|
+
if (data.count === 0 || data.confident === false) {
|
|
12241
12455
|
return {
|
|
12242
12456
|
content: [
|
|
12243
12457
|
{
|
|
12244
12458
|
type: "text",
|
|
12245
|
-
text: "No wiki
|
|
12459
|
+
text: data.hint ?? "No confident wiki answer. Fall back to search-team-memory for raw history \u2014 repeated misses here become insight-scout / gap-filler signals automatically."
|
|
12246
12460
|
}
|
|
12247
12461
|
]
|
|
12248
12462
|
};
|
|
12249
12463
|
}
|
|
12250
|
-
const lines = data.hits.map((hit,
|
|
12464
|
+
const lines = data.hits.map((hit, index11) => {
|
|
12251
12465
|
const sim = hit.similarity !== null ? ` \xB7 ${Math.round(hit.similarity * 100)}% match` : "";
|
|
12252
12466
|
const tags = hit.tags.length ? ` \xB7 ${hit.tags.slice(0, 5).join(", ")}` : "";
|
|
12253
12467
|
const sources = hit.sources.length ? `
|
|
12254
12468
|
sources: ${hit.sources.slice(0, 6).map((s) => `${s.type}:${s.ref}`).join(", ")}` : "";
|
|
12255
|
-
return `${
|
|
12469
|
+
return `${index11 + 1}. [${hit.status} \xB7 updated ${hit.pageUpdatedOn ?? "unknown"}${sim}${tags}] ${hit.title}
|
|
12256
12470
|
slug: ${hit.slug}${sources}
|
|
12257
12471
|
${(hit.summary ?? hit.snippet).replace(/\s+/g, " ").slice(0, 400)}`;
|
|
12258
12472
|
});
|
|
@@ -13459,8 +13673,8 @@ ${sample.join("\n")}${files.length > 5 ? `
|
|
|
13459
13673
|
};
|
|
13460
13674
|
const filtered = sortRows(applyFilter(only.rows));
|
|
13461
13675
|
if (format === "json") {
|
|
13462
|
-
const
|
|
13463
|
-
return { content: [{ type: "text", text:
|
|
13676
|
+
const text15 = filtered.map((c) => JSON.stringify(c)).join("\n") || "(no containers)";
|
|
13677
|
+
return { content: [{ type: "text", text: text15 }] };
|
|
13464
13678
|
}
|
|
13465
13679
|
if (groupByProject) {
|
|
13466
13680
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -13487,8 +13701,8 @@ ${sample.join("\n")}${files.length > 5 ? `
|
|
|
13487
13701
|
}
|
|
13488
13702
|
const header = `${"NAMES".padEnd(36)} ${"IMAGE".padEnd(40)} ${"STATUS".padEnd(24)} ${"HEALTH".padEnd(10)} ${"PORTS".padEnd(40)} PROJECT`;
|
|
13489
13703
|
const body = filtered.map((r) => `${fmtRow(r)} ${r.Project || ""}`);
|
|
13490
|
-
const
|
|
13491
|
-
return { content: [{ type: "text", text:
|
|
13704
|
+
const text14 = filtered.length === 0 ? "(no containers match)" : [header, ...body].join("\n");
|
|
13705
|
+
return { content: [{ type: "text", text: text14 }] };
|
|
13492
13706
|
}
|
|
13493
13707
|
if (format === "json") {
|
|
13494
13708
|
const lines = [];
|
package/package.json
CHANGED