@mgsoftwarebv/mg-dashboard-mcp 7.4.25 → 7.4.27

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 +443 -57
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -724,10 +724,10 @@ var TRIGGER_TOOL_MODULE_MAP = {
724
724
  "trigger-env": "settings"
725
725
  };
726
726
  async function discoverInstance(projectSlug, conn, proxy, sshExec2) {
727
- const sql36 = `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`;
727
+ const sql37 = `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`;
728
728
  const cmd = [
729
729
  `PORT=$(docker port "${WA_CONTAINER}" 3000/tcp 2>/dev/null | head -1 | sed 's/.*://')`,
730
- `ROW=$(docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql36}" 2>/dev/null | tr -d '[:space:]')`,
730
+ `ROW=$(docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql37}" 2>/dev/null | tr -d '[:space:]')`,
731
731
  'echo "$PORT|$ROW"'
732
732
  ].join(" && ");
733
733
  const result = await sshExec2(conn, cmd, proxy);
@@ -749,8 +749,8 @@ async function discoverInstance(projectSlug, conn, proxy, sshExec2) {
749
749
  return { port, apiKey: apiKey2, projectRef: projectRef || "" };
750
750
  }
751
751
  async function fetchRunLogs(runId, conn, proxy, sshExec2) {
752
- const sql36 = `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`;
753
- const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql36}" 2>/dev/null`;
752
+ const sql37 = `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`;
753
+ const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql37}" 2>/dev/null`;
754
754
  const result = await sshExec2(conn, cmd, proxy);
755
755
  const output = result.stdout.trim();
756
756
  if (!output) return "";
@@ -832,8 +832,8 @@ async function handleTriggerTool(name, args2, deps) {
832
832
  switch (name) {
833
833
  // -----------------------------------------------------------------
834
834
  case "trigger-list": {
835
- const sql36 = 'SELECT slug, name FROM \\"Project\\" ORDER BY name';
836
- const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql36}" 2>/dev/null`;
835
+ const sql37 = 'SELECT slug, name FROM \\"Project\\" ORDER BY name';
836
+ const cmd = `docker exec "${PG_CONTAINER}" psql -U postgres -d main -t -A -c "${sql37}" 2>/dev/null`;
837
837
  const result = await sshExec2(conn, cmd, proxy);
838
838
  const output = result.stdout.trim();
839
839
  if (!output) {
@@ -6341,6 +6341,52 @@ pgTable("two_factor", {
6341
6341
  secret: text("secret").notNull(),
6342
6342
  backupCodes: text("backup_codes")
6343
6343
  });
6344
+ var oauthApplications = pgTable("oauth_application", {
6345
+ id: uuid("id").primaryKey().defaultRandom(),
6346
+ clientId: text("client_id").notNull().unique(),
6347
+ clientSecret: text("client_secret"),
6348
+ name: text("name").notNull(),
6349
+ icon: text("icon"),
6350
+ metadata: text("metadata"),
6351
+ redirectUrls: text("redirect_urls").notNull(),
6352
+ type: text("type").notNull(),
6353
+ disabled: boolean("disabled").notNull().default(false),
6354
+ userId: uuid("user_id").references(() => users.id, { onDelete: "cascade" }),
6355
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
6356
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
6357
+ });
6358
+ pgTable("oauth_access_token", {
6359
+ id: uuid("id").primaryKey().defaultRandom(),
6360
+ accessToken: text("access_token").notNull().unique(),
6361
+ refreshToken: text("refresh_token").unique(),
6362
+ accessTokenExpiresAt: timestamp("access_token_expires_at", {
6363
+ withTimezone: true
6364
+ }).notNull(),
6365
+ refreshTokenExpiresAt: timestamp("refresh_token_expires_at", {
6366
+ withTimezone: true
6367
+ }),
6368
+ clientId: text("client_id").notNull().references(() => oauthApplications.clientId, { onDelete: "cascade" }),
6369
+ userId: uuid("user_id").references(() => users.id, { onDelete: "cascade" }),
6370
+ scopes: text("scopes").notNull().default(""),
6371
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
6372
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
6373
+ });
6374
+ pgTable("oauth_consent", {
6375
+ id: uuid("id").primaryKey().defaultRandom(),
6376
+ clientId: text("client_id").notNull().references(() => oauthApplications.clientId, { onDelete: "cascade" }),
6377
+ userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
6378
+ scopes: text("scopes").notNull().default(""),
6379
+ consentGiven: boolean("consent_given").notNull().default(false),
6380
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
6381
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
6382
+ });
6383
+ pgTable("jwks", {
6384
+ id: uuid("id").primaryKey().defaultRandom(),
6385
+ publicKey: text("public_key").notNull(),
6386
+ privateKey: text("private_key").notNull(),
6387
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
6388
+ expiresAt: timestamp("expires_at", { withTimezone: true })
6389
+ });
6344
6390
  var WIKI_EMBEDDING_DIMENSIONS = 1536;
6345
6391
  var vector = customType({
6346
6392
  dataType(config) {
@@ -6384,6 +6430,7 @@ pgTable(
6384
6430
  lastVerifiedOn: date("last_verified_on"),
6385
6431
  verifyCount: integer("verify_count").notNull().default(0),
6386
6432
  verifyNote: text("verify_note"),
6433
+ /** Pending git export. Not indexed: a dirty btree blocked HOT updates (2026-DASMG-208). */
6387
6434
  dirty: boolean("dirty").notNull().default(false),
6388
6435
  vaultSyncedAt: timestamp("vault_synced_at", { withTimezone: true }),
6389
6436
  /** Flattened frontmatter aliases for tsv weight A. */
@@ -6399,7 +6446,6 @@ pgTable(
6399
6446
  (table) => [
6400
6447
  index("idx_wiki_page_status").on(table.status),
6401
6448
  index("idx_wiki_page_last_verified").on(table.lastVerifiedOn),
6402
- index("idx_wiki_page_dirty").on(table.dirty),
6403
6449
  index("idx_wiki_page_lease_expires").on(table.leaseExpiresAt).where(sql`${table.leaseExpiresAt} IS NOT NULL`)
6404
6450
  ]
6405
6451
  );
@@ -6451,6 +6497,54 @@ pgTable(
6451
6497
  index("idx_wiki_page_evidence_created").on(table.createdAt)
6452
6498
  ]
6453
6499
  );
6500
+ pgTable(
6501
+ "wiki_source_origin",
6502
+ {
6503
+ id: uuid("id").primaryKey().defaultRandom(),
6504
+ sourceType: text("source_type").notNull(),
6505
+ sourceRef: text("source_ref").notNull(),
6506
+ originEventId: uuid("origin_event_id"),
6507
+ derivedFromType: text("derived_from_type"),
6508
+ derivedFromRef: text("derived_from_ref"),
6509
+ contentHash: text("content_hash"),
6510
+ contentVersion: text("content_version"),
6511
+ observationType: text("observation_type").notNull().default("unknown"),
6512
+ observedAt: timestamp("observed_at", { withTimezone: true }),
6513
+ fetchStatus: text("fetch_status").notNull().default("unknown"),
6514
+ clusterReason: text("cluster_reason"),
6515
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
6516
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
6517
+ },
6518
+ (table) => [
6519
+ uniqueIndex("wiki_source_origin_source_type_source_ref_key").on(
6520
+ table.sourceType,
6521
+ table.sourceRef
6522
+ ),
6523
+ index("idx_wiki_source_origin_event").on(table.originEventId),
6524
+ index("idx_wiki_source_origin_hash").on(table.contentHash)
6525
+ ]
6526
+ );
6527
+ pgTable(
6528
+ "wiki_evidence_decision",
6529
+ {
6530
+ id: uuid("id").primaryKey().defaultRandom(),
6531
+ pageSlug: text("page_slug").notNull(),
6532
+ mode: text("mode").notNull(),
6533
+ contractVersion: text("contract_version").notNull(),
6534
+ sourceVersions: jsonb("source_versions").$type().notNull().default([]),
6535
+ clusters: jsonb("clusters").$type().notNull().default([]),
6536
+ clusterReasons: text("cluster_reasons").array().notNull().default([]),
6537
+ legacyConfidence: text("legacy_confidence"),
6538
+ originConfidence: text("origin_confidence"),
6539
+ liveAutoAccept: boolean("live_auto_accept").notNull().default(false),
6540
+ originAutoAccept: boolean("origin_auto_accept").notNull().default(false),
6541
+ hasConflict: boolean("has_conflict").notNull().default(false),
6542
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
6543
+ },
6544
+ (table) => [
6545
+ index("idx_wiki_evidence_decision_slug").on(table.pageSlug, table.createdAt)
6546
+ ]
6547
+ );
6454
6548
  pgTable(
6455
6549
  "wiki_page_link",
6456
6550
  {
@@ -6477,11 +6571,16 @@ pgTable(
6477
6571
  slug: text("slug").notNull(),
6478
6572
  caller: text("caller"),
6479
6573
  includedArchive: boolean("included_archive").notNull().default(false),
6574
+ requestId: uuid("request_id"),
6575
+ sessionId: text("session_id"),
6576
+ taskId: text("task_id"),
6577
+ callerKind: text("caller_kind"),
6480
6578
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
6481
6579
  },
6482
6580
  (table) => [
6483
6581
  index("idx_wiki_page_read_slug").on(table.slug, table.createdAt),
6484
- index("idx_wiki_page_read_created").on(table.createdAt)
6582
+ index("idx_wiki_page_read_created").on(table.createdAt),
6583
+ index("idx_wiki_page_read_request_id").on(table.requestId)
6485
6584
  ]
6486
6585
  );
6487
6586
  pgTable(
@@ -6570,9 +6669,17 @@ pgTable(
6570
6669
  topScore: real("top_score"),
6571
6670
  topSlug: text("top_slug"),
6572
6671
  caller: text("caller"),
6672
+ requestId: uuid("request_id"),
6673
+ sessionId: text("session_id"),
6674
+ taskId: text("task_id"),
6675
+ callerKind: text("caller_kind"),
6676
+ configRevision: text("config_revision"),
6573
6677
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
6574
6678
  },
6575
- (table) => [index("idx_wiki_search_log_created").on(table.createdAt)]
6679
+ (table) => [
6680
+ index("idx_wiki_search_log_created").on(table.createdAt),
6681
+ index("idx_wiki_search_log_request_id").on(table.requestId)
6682
+ ]
6576
6683
  );
6577
6684
  pgTable(
6578
6685
  "team_memory_search_log",
@@ -6585,9 +6692,16 @@ pgTable(
6585
6692
  caller: text("caller"),
6586
6693
  repo: text("repo"),
6587
6694
  confident: boolean("confident"),
6695
+ requestId: uuid("request_id"),
6696
+ sessionId: text("session_id"),
6697
+ taskId: text("task_id"),
6698
+ callerKind: text("caller_kind"),
6588
6699
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
6589
6700
  },
6590
- (table) => [index("idx_team_memory_search_log_created").on(table.createdAt)]
6701
+ (table) => [
6702
+ index("idx_team_memory_search_log_created").on(table.createdAt),
6703
+ index("idx_team_memory_search_log_request_id").on(table.requestId)
6704
+ ]
6591
6705
  );
6592
6706
  pgTable(
6593
6707
  "wiki_agent_run",
@@ -6684,7 +6798,8 @@ pgTable("brain_config", {
6684
6798
  key: text("key").primaryKey(),
6685
6799
  value: jsonb("value").$type().notNull(),
6686
6800
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
6687
- updatedBy: text("updated_by")
6801
+ updatedBy: text("updated_by"),
6802
+ revision: bigint("revision", { mode: "number" }).notNull().default(1)
6688
6803
  });
6689
6804
  pgTable(
6690
6805
  "brain_metrics_daily",
@@ -6736,18 +6851,61 @@ pgTable(
6736
6851
  baselineMetrics: jsonb("baseline_metrics"),
6737
6852
  outcomeMetrics: jsonb("outcome_metrics"),
6738
6853
  verdict: text("verdict").notNull().default("pending"),
6854
+ operationalStatus: text("operational_status").notNull().default("pending"),
6855
+ effectVerdict: text("effect_verdict"),
6856
+ effectReason: text("effect_reason"),
6857
+ experiment: jsonb("experiment").$type().notNull().default({}),
6858
+ activatedAt: timestamp("activated_at", { withTimezone: true }),
6859
+ activationEvidence: jsonb("activation_evidence"),
6739
6860
  evidenceRefs: text("evidence_refs").array().notNull().default([]),
6740
6861
  createdBy: text("created_by"),
6741
6862
  suggestionId: uuid("suggestion_id"),
6742
6863
  ticketNumber: text("ticket_number"),
6743
6864
  ticketId: text("ticket_id"),
6865
+ configRevision: bigint("config_revision", { mode: "number" }),
6866
+ mutationStatus: text("mutation_status").notNull().default("applied"),
6744
6867
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
6745
6868
  verdictAt: timestamp("verdict_at", { withTimezone: true }),
6746
6869
  revertedAt: timestamp("reverted_at", { withTimezone: true })
6747
6870
  },
6748
6871
  (table) => [
6749
6872
  index("idx_brain_change_ledger_verdict").on(table.verdict, table.createdAt),
6750
- index("idx_brain_change_ledger_scope").on(table.scope, table.createdAt)
6873
+ index("idx_brain_change_ledger_scope").on(table.scope, table.createdAt),
6874
+ index("idx_brain_change_ledger_operational").on(
6875
+ table.operationalStatus,
6876
+ table.createdAt
6877
+ )
6878
+ ]
6879
+ );
6880
+ pgTable(
6881
+ "brain_suggestion_implementation",
6882
+ {
6883
+ suggestionId: uuid("suggestion_id").primaryKey(),
6884
+ ledgerId: uuid("ledger_id").notNull(),
6885
+ claimedAt: timestamp("claimed_at", { withTimezone: true }).notNull().defaultNow(),
6886
+ claimedBy: text("claimed_by")
6887
+ },
6888
+ (table) => [
6889
+ uniqueIndex("brain_suggestion_implementation_ledger_id_key").on(
6890
+ table.ledgerId
6891
+ )
6892
+ ]
6893
+ );
6894
+ pgTable(
6895
+ "brain_ticket_outbox",
6896
+ {
6897
+ ledgerId: uuid("ledger_id").primaryKey(),
6898
+ idempotencyKey: text("idempotency_key").notNull(),
6899
+ status: text("status").notNull().default("pending"),
6900
+ ticketNumber: text("ticket_number"),
6901
+ ticketId: text("ticket_id"),
6902
+ attempts: integer("attempts").notNull().default(0),
6903
+ lastError: text("last_error"),
6904
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
6905
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
6906
+ },
6907
+ (table) => [
6908
+ uniqueIndex("brain_ticket_outbox_idempotency_key").on(table.idempotencyKey)
6751
6909
  ]
6752
6910
  );
6753
6911
  pgTable(
@@ -6783,6 +6941,134 @@ pgTable(
6783
6941
  },
6784
6942
  (table) => [index("idx_wiki_eval_label_snapshot").on(table.snapshotId)]
6785
6943
  );
6944
+ pgTable("wiki_eval_dataset", {
6945
+ version: text("version").primaryKey(),
6946
+ evaluatorVersion: text("evaluator_version").notNull(),
6947
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
6948
+ });
6949
+ pgTable(
6950
+ "wiki_eval_case",
6951
+ {
6952
+ id: uuid("id").primaryKey().defaultRandom(),
6953
+ datasetVersion: text("dataset_version").notNull(),
6954
+ caseKey: text("case_key").notNull(),
6955
+ query: text("query").notNull(),
6956
+ language: text("language").notNull().default("en"),
6957
+ originEventId: text("origin_event_id").notNull(),
6958
+ partition: text("partition").notNull(),
6959
+ aclFolders: text("acl_folders").array().notNull().default([]),
6960
+ goldSlugs: text("gold_slugs").array().notNull().default([]),
6961
+ supportedSlugs: text("supported_slugs").array().notNull().default([]),
6962
+ labelKind: text("label_kind").notNull().default("gold"),
6963
+ unanswerable: boolean("unanswerable").notNull().default(false),
6964
+ queryEmbedding: real("query_embedding").array(),
6965
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
6966
+ },
6967
+ (table) => [
6968
+ uniqueIndex("wiki_eval_case_dataset_version_case_key_key").on(
6969
+ table.datasetVersion,
6970
+ table.caseKey
6971
+ ),
6972
+ index("idx_wiki_eval_case_origin").on(table.originEventId)
6973
+ ]
6974
+ );
6975
+ pgTable(
6976
+ "wiki_eval_corpus_snapshot",
6977
+ {
6978
+ id: uuid("id").primaryKey().defaultRandom(),
6979
+ version: text("version").notNull(),
6980
+ fingerprint: text("fingerprint").notNull(),
6981
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
6982
+ },
6983
+ (table) => [
6984
+ uniqueIndex("wiki_eval_corpus_snapshot_version_key").on(table.version)
6985
+ ]
6986
+ );
6987
+ pgTable(
6988
+ "wiki_eval_corpus_page",
6989
+ {
6990
+ id: uuid("id").primaryKey().defaultRandom(),
6991
+ snapshotId: uuid("snapshot_id").notNull(),
6992
+ slug: text("slug").notNull(),
6993
+ title: text("title").notNull().default(""),
6994
+ content: text("content").notNull().default(""),
6995
+ aliases: text("aliases").array().notNull().default([]),
6996
+ embedding: real("embedding").array(),
6997
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
6998
+ },
6999
+ (table) => [
7000
+ uniqueIndex("wiki_eval_corpus_page_snapshot_id_slug_key").on(
7001
+ table.snapshotId,
7002
+ table.slug
7003
+ ),
7004
+ index("idx_wiki_eval_corpus_page_snapshot").on(table.snapshotId)
7005
+ ]
7006
+ );
7007
+ pgTable(
7008
+ "wiki_eval_corpus_chunk",
7009
+ {
7010
+ id: uuid("id").primaryKey().defaultRandom(),
7011
+ snapshotId: uuid("snapshot_id").notNull(),
7012
+ slug: text("slug").notNull(),
7013
+ headingPath: text("heading_path").notNull().default(""),
7014
+ chunkIndex: integer("chunk_index").notNull().default(0),
7015
+ content: text("content").notNull().default(""),
7016
+ embedding: real("embedding").array()
7017
+ },
7018
+ (table) => [
7019
+ index("idx_wiki_eval_corpus_chunk_snapshot_slug").on(
7020
+ table.snapshotId,
7021
+ table.slug
7022
+ )
7023
+ ]
7024
+ );
7025
+ pgTable(
7026
+ "wiki_eval_run",
7027
+ {
7028
+ id: uuid("id").primaryKey().defaultRandom(),
7029
+ datasetVersion: text("dataset_version").notNull(),
7030
+ corpusSnapshotId: uuid("corpus_snapshot_id"),
7031
+ evaluatorVersion: text("evaluator_version").notNull(),
7032
+ experimentId: text("experiment_id").notNull(),
7033
+ baselineVariantId: text("baseline_variant_id").notNull(),
7034
+ candidateVariantId: text("candidate_variant_id").notNull(),
7035
+ baselineConfig: jsonb("baseline_config").$type().notNull().default({}),
7036
+ candidateConfig: jsonb("candidate_config").$type().notNull().default({}),
7037
+ status: text("status").notNull().default("running"),
7038
+ availability: text("availability").notNull().default("incomplete"),
7039
+ plannedCases: integer("planned_cases").notNull().default(0),
7040
+ attemptedCases: integer("attempted_cases").notNull().default(0),
7041
+ completedPairs: integer("completed_pairs").notNull().default(0),
7042
+ failedCases: integer("failed_cases").notNull().default(0),
7043
+ timeoutCases: integer("timeout_cases").notNull().default(0),
7044
+ report: jsonb("report").$type().notNull().default({}),
7045
+ lockKey: text("lock_key"),
7046
+ startedAt: timestamp("started_at", { withTimezone: true }).notNull().defaultNow(),
7047
+ heartbeatAt: timestamp("heartbeat_at", { withTimezone: true }).notNull().defaultNow(),
7048
+ finishedAt: timestamp("finished_at", { withTimezone: true }),
7049
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
7050
+ },
7051
+ (table) => [
7052
+ index("idx_wiki_eval_run_created").on(table.createdAt),
7053
+ uniqueIndex("wiki_eval_run_lock_key_running_key").on(table.lockKey).where(sql`${table.status} = 'running'`)
7054
+ ]
7055
+ );
7056
+ pgTable(
7057
+ "wiki_eval_trial",
7058
+ {
7059
+ id: uuid("id").primaryKey().defaultRandom(),
7060
+ runId: uuid("run_id").notNull(),
7061
+ caseKey: text("case_key").notNull(),
7062
+ variantId: text("variant_id").notNull(),
7063
+ rankedSlugs: text("ranked_slugs").array().notNull().default([]),
7064
+ latencyMs: integer("latency_ms"),
7065
+ status: text("status").notNull().default("ok"),
7066
+ error: text("error"),
7067
+ costsAvailable: boolean("costs_available").notNull().default(false),
7068
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
7069
+ },
7070
+ (table) => [index("idx_wiki_eval_trial_run").on(table.runId)]
7071
+ );
6786
7072
  pgTable("wiki_status_dirty", {
6787
7073
  slug: text("slug").primaryKey(),
6788
7074
  markedAt: timestamp("marked_at", { withTimezone: true }).notNull().defaultNow(),
@@ -6829,7 +7115,8 @@ pgTable(
6829
7115
  index("idx_agent_memory_repo").on(table.gitRepository),
6830
7116
  index("idx_agent_memory_user").on(table.userId),
6831
7117
  index("idx_agent_memory_kind").on(table.kind),
6832
- index("idx_agent_memory_automated_created").on(table.createdAt).where(sql`kind = 'automated'`)
7118
+ index("idx_agent_memory_automated_created").on(table.createdAt).where(sql`kind = 'automated'`),
7119
+ index("idx_agent_memory_non_transcript_join").on(table.localConversationId).where(sql`source IS DISTINCT FROM 'transcript'`)
6833
7120
  ]
6834
7121
  );
6835
7122
  var contentSourceType = pgEnum("content_source_type", [
@@ -7387,7 +7674,8 @@ pgTable(
7387
7674
  id: uuid("id").primaryKey().defaultRandom(),
7388
7675
  tokenHash: text("token_hash").notNull(),
7389
7676
  userId: uuid("user_id").notNull(),
7390
- apiKeyId: uuid("api_key_id").notNull(),
7677
+ apiKeyId: uuid("api_key_id"),
7678
+ helperDeviceId: uuid("helper_device_id"),
7391
7679
  repo: text("repo").notNull(),
7392
7680
  write: boolean("write").notNull().default(true),
7393
7681
  principal: text("principal").notNull(),
@@ -7398,7 +7686,42 @@ pgTable(
7398
7686
  (table) => [
7399
7687
  uniqueIndex("git_credential_grant_token_hash_uidx").on(table.tokenHash),
7400
7688
  index("git_credential_grant_expires_idx").on(table.expiresAt),
7401
- index("git_credential_grant_user_idx").on(table.userId, table.expiresAt)
7689
+ index("git_credential_grant_user_idx").on(table.userId, table.expiresAt),
7690
+ index("git_credential_grant_helper_device_idx").on(table.helperDeviceId)
7691
+ ]
7692
+ );
7693
+ pgTable(
7694
+ "git_helper_enroll",
7695
+ {
7696
+ id: uuid("id").primaryKey().defaultRandom(),
7697
+ userId: uuid("user_id").notNull(),
7698
+ codeHash: text("code_hash").notNull(),
7699
+ expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
7700
+ usedAt: timestamp("used_at", { withTimezone: true }),
7701
+ issuedIp: text("issued_ip").notNull().default(""),
7702
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
7703
+ },
7704
+ (table) => [
7705
+ uniqueIndex("git_helper_enroll_code_hash_uidx").on(table.codeHash),
7706
+ index("git_helper_enroll_user_idx").on(table.userId, table.expiresAt)
7707
+ ]
7708
+ );
7709
+ pgTable(
7710
+ "git_helper_device",
7711
+ {
7712
+ id: uuid("id").primaryKey().defaultRandom(),
7713
+ userId: uuid("user_id").notNull(),
7714
+ tokenHash: text("token_hash").notNull(),
7715
+ expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
7716
+ revokedAt: timestamp("revoked_at", { withTimezone: true }),
7717
+ lastUsedAt: timestamp("last_used_at", { withTimezone: true }),
7718
+ issuedIp: text("issued_ip").notNull().default(""),
7719
+ userAgent: text("user_agent").notNull().default(""),
7720
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
7721
+ },
7722
+ (table) => [
7723
+ uniqueIndex("git_helper_device_token_hash_uidx").on(table.tokenHash),
7724
+ index("git_helper_device_user_idx").on(table.userId, table.expiresAt)
7402
7725
  ]
7403
7726
  );
7404
7727
  var directoryLinkType = pgEnum("directory_link_type", [
@@ -9391,6 +9714,8 @@ var TRANSIENT_GITHUB_STATUSES = /* @__PURE__ */ new Set([
9391
9714
  var DEFAULT_BUDGET_PER_MINUTE = 75;
9392
9715
  var DEFAULT_INTERACTIVE_CACHE_MAX_AGE_MS = 5 * 6e4;
9393
9716
  var DEFAULT_INTERACTIVE_STALE_MAX_AGE_MS = 30 * 6e4;
9717
+ var GITHUB_API_CACHE_MAX_BODY_BYTES = 1024 * 1024;
9718
+ var GITHUB_API_CACHE_META_COLUMNS = "etag, status, expires_at, updated_at";
9394
9719
  var BUDGET_STATE_KEY = "github_api_budget_per_minute";
9395
9720
  var DEFAULT_BLOCK_MS = 15 * 60 * 1e3;
9396
9721
  var MAX_ATTEMPTS = 4;
@@ -9491,6 +9816,12 @@ function mergeGithubApiStatDelta(current, add) {
9491
9816
  breakerHitCount: current.breakerHitCount + add.breakerHitCount
9492
9817
  };
9493
9818
  }
9819
+ function githubApiCacheBodyBytes(body) {
9820
+ return Buffer.byteLength(body, "utf8");
9821
+ }
9822
+ function shouldPersistGithubApiCacheBody(body) {
9823
+ return githubApiCacheBodyBytes(body) <= GITHUB_API_CACHE_MAX_BODY_BYTES;
9824
+ }
9494
9825
  function cacheKeyFor(url, tokenKey) {
9495
9826
  return createHash("sha256").update(`${tokenKey}:${url}`).digest("hex");
9496
9827
  }
@@ -9743,9 +10074,9 @@ async function recordBreakerHit(input) {
9743
10074
  breakerHit: true
9744
10075
  });
9745
10076
  }
9746
- async function loadEtagCache(key) {
10077
+ async function loadEtagCacheMeta(key) {
9747
10078
  const rows = await getDb().execute(sql`
9748
- SELECT etag, body, status, expires_at, updated_at
10079
+ SELECT ${sql.raw(GITHUB_API_CACHE_META_COLUMNS)}
9749
10080
  FROM github_api_cache
9750
10081
  WHERE cache_key = ${key}
9751
10082
  LIMIT 1
@@ -9754,13 +10085,22 @@ async function loadEtagCache(key) {
9754
10085
  if (!row) return null;
9755
10086
  return {
9756
10087
  etag: row.etag,
9757
- body: row.body,
9758
10088
  status: row.status,
9759
10089
  expiresAt: row.expires_at,
9760
10090
  updatedAt: row.updated_at
9761
10091
  };
9762
10092
  }
10093
+ async function loadEtagCacheBody(key) {
10094
+ const rows = await getDb().execute(sql`
10095
+ SELECT body
10096
+ FROM github_api_cache
10097
+ WHERE cache_key = ${key}
10098
+ LIMIT 1
10099
+ `);
10100
+ return rows[0]?.body ?? null;
10101
+ }
9763
10102
  async function saveEtagCache(input) {
10103
+ if (!shouldPersistGithubApiCacheBody(input.body)) return;
9764
10104
  const expiresAt = input.maxAgeMs != null && input.maxAgeMs > 0 ? new Date(Date.now() + input.maxAgeMs).toISOString() : null;
9765
10105
  await getDb().execute(sql`
9766
10106
  INSERT INTO github_api_cache (
@@ -9831,8 +10171,8 @@ async function githubGatewayFetch(url, init, options) {
9831
10171
  }
9832
10172
  const key = useCache ? cacheKeyFor(url, options.tokenKey) : null;
9833
10173
  if (key && !options.bypassSoftCache) {
9834
- const soft = await loadEtagCache(key);
9835
- const softOk = soft?.body != null && (priority === "interactive" ? canInteractiveSoftServe({
10174
+ const soft = await loadEtagCacheMeta(key);
10175
+ const softOk = soft != null && (priority === "interactive" ? canInteractiveSoftServe({
9836
10176
  expiresAt: soft.expiresAt,
9837
10177
  updatedAt: soft.updatedAt,
9838
10178
  maxAgeMs
@@ -9841,27 +10181,30 @@ async function githubGatewayFetch(url, init, options) {
9841
10181
  updatedAt: soft.updatedAt,
9842
10182
  maxAgeMs
9843
10183
  }));
9844
- if (softOk && soft?.body != null) {
9845
- const isFresh = isSoftCacheFresh({
9846
- expiresAt: soft.expiresAt,
9847
- updatedAt: soft.updatedAt,
9848
- maxAgeMs
9849
- });
9850
- await recordStat({
9851
- tokenKey: options.tokenKey,
9852
- jobId: options.jobId,
9853
- cacheHit: true
9854
- });
9855
- if (priority === "interactive" && !isFresh) {
9856
- void githubGatewayFetch(url, init, {
9857
- ...options,
9858
- bypassSoftCache: true,
9859
- priority: "background",
9860
- maxAgeMs: maxAgeMs ?? DEFAULT_INTERACTIVE_CACHE_MAX_AGE_MS
9861
- }).catch(() => {
10184
+ if (softOk) {
10185
+ const body = await loadEtagCacheBody(key);
10186
+ if (body != null) {
10187
+ const isFresh = isSoftCacheFresh({
10188
+ expiresAt: soft.expiresAt,
10189
+ updatedAt: soft.updatedAt,
10190
+ maxAgeMs
10191
+ });
10192
+ await recordStat({
10193
+ tokenKey: options.tokenKey,
10194
+ jobId: options.jobId,
10195
+ cacheHit: true
9862
10196
  });
10197
+ if (priority === "interactive" && !isFresh) {
10198
+ void githubGatewayFetch(url, init, {
10199
+ ...options,
10200
+ bypassSoftCache: true,
10201
+ priority: "background",
10202
+ maxAgeMs: maxAgeMs ?? DEFAULT_INTERACTIVE_CACHE_MAX_AGE_MS
10203
+ }).catch(() => {
10204
+ });
10205
+ }
10206
+ return cachedJsonResponse(body, soft.status ?? 200, "soft");
9863
10207
  }
9864
- return cachedJsonResponse(soft.body, soft.status ?? 200, "soft");
9865
10208
  }
9866
10209
  }
9867
10210
  const budgetPerMinute = await resolveGithubBudgetPerMinute(
@@ -9901,7 +10244,7 @@ async function githubGatewayFetch(url, init, options) {
9901
10244
  headers.set("X-GitHub-Api-Version", "2022-11-28");
9902
10245
  }
9903
10246
  if (key) {
9904
- const cached = await loadEtagCache(key);
10247
+ const cached = await loadEtagCacheMeta(key);
9905
10248
  if (cached?.etag) headers.set("If-None-Match", cached.etag);
9906
10249
  }
9907
10250
  let lastError = null;
@@ -9928,17 +10271,14 @@ async function githubGatewayFetch(url, init, options) {
9928
10271
  }
9929
10272
  await updateRateLimitHeaders(options.tokenKey, response);
9930
10273
  if (response.status === 304 && key) {
9931
- const cached = await loadEtagCache(key);
10274
+ const cached = await loadEtagCacheMeta(key);
10275
+ const body = await loadEtagCacheBody(key);
9932
10276
  await recordStat({
9933
10277
  tokenKey: options.tokenKey,
9934
10278
  jobId: options.jobId,
9935
10279
  cacheHit: true
9936
10280
  });
9937
- return cachedJsonResponse(
9938
- cached?.body ?? "",
9939
- cached?.status ?? 200,
9940
- "hit"
9941
- );
10281
+ return cachedJsonResponse(body ?? "", cached?.status ?? 200, "hit");
9942
10282
  }
9943
10283
  if (response.status === 403 || response.status === 429 || isTransientGitHubStatus(response.status)) {
9944
10284
  const bodyText = summarizeGitHubErrorBody(
@@ -13540,11 +13880,11 @@ CREATE TABLE IF NOT EXISTS _mcp_migrations (
13540
13880
  applied_by TEXT
13541
13881
  );
13542
13882
  `.trim();
13543
- function normaliseMigrationSql(sql36) {
13544
- return sql36.replace(/\r\n/g, "\n").trim() + "\n";
13883
+ function normaliseMigrationSql(sql37) {
13884
+ return sql37.replace(/\r\n/g, "\n").trim() + "\n";
13545
13885
  }
13546
- function migrationSha256(sql36) {
13547
- return createHash("sha256").update(sql36.replace(/\r\n/g, "\n"), "utf8").digest("hex");
13886
+ function migrationSha256(sql37) {
13887
+ return createHash("sha256").update(sql37.replace(/\r\n/g, "\n"), "utf8").digest("hex");
13548
13888
  }
13549
13889
  function dollarQuoteTag(value) {
13550
13890
  let tag = "_mcp";
@@ -15235,6 +15575,18 @@ var TOOLS = [
15235
15575
  limit: {
15236
15576
  type: "number",
15237
15577
  description: "Max results to return (1-25, default 8)."
15578
+ },
15579
+ requestId: {
15580
+ type: "string",
15581
+ description: "Parent wiki search requestId when this is a fallback after search-wiki."
15582
+ },
15583
+ sessionId: {
15584
+ type: "string",
15585
+ description: "Optional session id (distinct from API key)."
15586
+ },
15587
+ taskId: {
15588
+ type: "string",
15589
+ description: "Optional agent task id for the same request chain."
15238
15590
  }
15239
15591
  },
15240
15592
  required: ["query"]
@@ -15305,6 +15657,18 @@ var TOOLS = [
15305
15657
  includeArchived: {
15306
15658
  type: "boolean",
15307
15659
  description: "Include lifecycle-archived pages (decommissioned systems). Default false \u2014 archived is hidden unless you opt in."
15660
+ },
15661
+ requestId: {
15662
+ type: "string",
15663
+ description: "Optional correlation UUID. Generated by the server when omitted; pass it to get-wiki-page and search-team-memory."
15664
+ },
15665
+ sessionId: {
15666
+ type: "string",
15667
+ description: "Optional session id (distinct from API key)."
15668
+ },
15669
+ taskId: {
15670
+ type: "string",
15671
+ description: "Optional agent task id for the same request chain."
15308
15672
  }
15309
15673
  },
15310
15674
  required: ["query"]
@@ -15323,6 +15687,18 @@ var TOOLS = [
15323
15687
  include_all_sources: {
15324
15688
  type: "boolean",
15325
15689
  description: "Return every active source plus the archived history (also enriched). Default false \u2014 compact active list only."
15690
+ },
15691
+ requestId: {
15692
+ type: "string",
15693
+ description: "Pass the requestId returned by search-wiki so this read joins the same request."
15694
+ },
15695
+ sessionId: {
15696
+ type: "string",
15697
+ description: "Optional session id (distinct from API key)."
15698
+ },
15699
+ taskId: {
15700
+ type: "string",
15701
+ description: "Optional agent task id for the same request chain."
15326
15702
  }
15327
15703
  },
15328
15704
  required: ["slug"]
@@ -15853,7 +16229,10 @@ async function executeToolCall(name, a, _serverId) {
15853
16229
  query,
15854
16230
  repo: typeof a.repo === "string" ? a.repo : void 0,
15855
16231
  scope: a.scope === "mine" ? "mine" : "team",
15856
- limit: typeof a.limit === "number" ? a.limit : void 0
16232
+ limit: typeof a.limit === "number" ? a.limit : void 0,
16233
+ requestId: typeof a.requestId === "string" ? a.requestId : void 0,
16234
+ sessionId: typeof a.sessionId === "string" ? a.sessionId : void 0,
16235
+ taskId: typeof a.taskId === "string" ? a.taskId : void 0
15857
16236
  })
15858
16237
  });
15859
16238
  if (!res.ok) {
@@ -16070,7 +16449,10 @@ Searchable via search-team-memory once indexing completes (usually immediate).`
16070
16449
  body: JSON.stringify({
16071
16450
  query,
16072
16451
  limit: typeof a.limit === "number" ? a.limit : void 0,
16073
- includeArchived: typeof a.includeArchived === "boolean" ? a.includeArchived : void 0
16452
+ includeArchived: typeof a.includeArchived === "boolean" ? a.includeArchived : void 0,
16453
+ requestId: typeof a.requestId === "string" ? a.requestId : void 0,
16454
+ sessionId: typeof a.sessionId === "string" ? a.sessionId : void 0,
16455
+ taskId: typeof a.taskId === "string" ? a.taskId : void 0
16074
16456
  })
16075
16457
  });
16076
16458
  if (!res.ok) {
@@ -16086,11 +16468,13 @@ Searchable via search-team-memory once indexing completes (usually immediate).`
16086
16468
  }
16087
16469
  const data = await res.json();
16088
16470
  if (data.count === 0 || data.confident === false) {
16471
+ const requestLine = data.requestId ? `
16472
+ Pass requestId ${data.requestId} to search-team-memory so the fallback joins this wiki search.` : "";
16089
16473
  return {
16090
16474
  content: [
16091
16475
  {
16092
16476
  type: "text",
16093
- 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."
16477
+ 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.") + requestLine
16094
16478
  }
16095
16479
  ]
16096
16480
  };
@@ -16109,9 +16493,8 @@ Searchable via search-team-memory once indexing completes (usually immediate).`
16109
16493
  {
16110
16494
  type: "text",
16111
16495
  text: `Found ${data.count} wiki page(s) (${data.mode} search) \u2014 curated team knowledge.
16112
- 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.
16113
-
16114
- ` + lines.join("\n\n")
16496
+ ` + (data.requestId ? `requestId: ${data.requestId} \u2014 pass this to get-wiki-page and search-team-memory for the same request.
16497
+ ` : "") + "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.\n\n" + lines.join("\n\n")
16115
16498
  }
16116
16499
  ]
16117
16500
  };
@@ -16131,7 +16514,10 @@ Call get-wiki-page with a slug for the full page; follow its sources (team-memor
16131
16514
  },
16132
16515
  body: JSON.stringify({
16133
16516
  slug,
16134
- include_all_sources: includeAllSources
16517
+ include_all_sources: includeAllSources,
16518
+ requestId: typeof a.requestId === "string" ? a.requestId : void 0,
16519
+ sessionId: typeof a.sessionId === "string" ? a.sessionId : void 0,
16520
+ taskId: typeof a.taskId === "string" ? a.taskId : void 0
16135
16521
  })
16136
16522
  });
16137
16523
  if (!res.ok) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mgsoftwarebv/mg-dashboard-mcp",
3
- "version": "7.4.25",
3
+ "version": "7.4.27",
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",