@mgsoftwarebv/mg-dashboard-mcp 7.0.20 → 7.0.22

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 CHANGED
@@ -6205,9 +6205,25 @@ function normalizeRepoIdentifier(value) {
6205
6205
  return s || null;
6206
6206
  }
6207
6207
  var HANDOFF_PROMPT_CHARS = 4e3;
6208
+ function buildCommitInstruction(args2) {
6209
+ const branchLine = args2.commitBranch ? `Create or switch to the branch \`${args2.commitBranch}\` (from the current HEAD) and push it with \`git push -u origin ${args2.commitBranch}\`.` : "Push to the current branch.";
6210
+ return [
6211
+ "",
6212
+ "---",
6213
+ "When the task is complete, commit and push your work:",
6214
+ "- Stage ONLY the files you changed for this task \u2014 never commit unrelated, pre-existing local changes.",
6215
+ `- Use this commit message: \`${args2.commitMessage}\`.`,
6216
+ `- ${branchLine}`,
6217
+ "- If the push is rejected, run `git pull --rebase` and push again."
6218
+ ].join("\n");
6219
+ }
6208
6220
  async function queueAgentRun(args2) {
6209
6221
  const db2 = getDb();
6210
- const handoffPrompt = args2.prompt.trim().slice(0, HANDOFF_PROMPT_CHARS);
6222
+ const cappedPrompt = args2.prompt.trim().slice(0, HANDOFF_PROMPT_CHARS);
6223
+ const handoffPrompt = args2.autoCommit ? cappedPrompt + buildCommitInstruction({
6224
+ commitMessage: args2.commitMessage ?? "agent: automated change",
6225
+ commitBranch: args2.commitBranch
6226
+ }) : cappedPrompt;
6211
6227
  const metadata = { ...args2.metadata ?? {}, source: args2.source };
6212
6228
  await db2.execute(sql`
6213
6229
  INSERT INTO agent_host_command (host_id, user_id, command_type, payload)
@@ -6215,12 +6231,7 @@ async function queueAgentRun(args2) {
6215
6231
  ${args2.workspace.host_id}, ${args2.userId}, 'open_chat_in_ide',
6216
6232
  ${JSON.stringify({
6217
6233
  workspacePath: args2.workspace.path,
6218
- prompt: handoffPrompt,
6219
- ...args2.autoCommit ? {
6220
- autoCommit: true,
6221
- commitBranch: args2.commitBranch ?? null,
6222
- commitMessage: args2.commitMessage ?? null
6223
- } : {}
6234
+ prompt: handoffPrompt
6224
6235
  })}::jsonb
6225
6236
  )
6226
6237
  `);
@@ -8197,6 +8208,7 @@ function formatBytes(bytes) {
8197
8208
  }
8198
8209
  var RESPONSE_MAX_BYTES = 8192;
8199
8210
  var NO_FOOTER_TOOLS = /* @__PURE__ */ new Set();
8211
+ var RAW_JSON_TOOLS = /* @__PURE__ */ new Set(["get_mg_dashboard_commits"]);
8200
8212
  var TOOL_CACHE_TTL_MS = {
8201
8213
  "list-servers": 6e4,
8202
8214
  "docker-list": 3e4
@@ -8329,6 +8341,7 @@ function isTransientSshError(stderr, exitCode) {
8329
8341
  }
8330
8342
  function postprocessResult(result, meta) {
8331
8343
  if (!result.content?.length) return result;
8344
+ if (RAW_JSON_TOOLS.has(meta.toolName)) return result;
8332
8345
  const block = result.content[0];
8333
8346
  let text7 = String(block.text ?? "");
8334
8347
  const trunc = truncateForLLM(text7, RESPONSE_MAX_BYTES);
@@ -10297,6 +10310,44 @@ var TOOLS = [
10297
10310
  }
10298
10311
  },
10299
10312
  // ----- Team memory -----
10313
+ {
10314
+ name: "get_mg_dashboard_commits",
10315
+ description: "Fetch a SAFE, COMPACT MG Dashboard git commit feed for ONE actor over an EXACT time range \u2014 the 'what was actually built' signal for daily operational reports (e.g. Hermes' rolling 19:00\u219219:00 Europe/Amsterdam Prince report), complementing Refront ticket activity. Backed by code_battle_commits (GitHub push webhook + nightly sync). Returns METADATA ONLY per commit: timestamp, repo (org/repo), sha, isMerge, additions, deletions, filesChanged \u2014 plus period summary counts. NEVER returns commit messages, branches, diffs or code (not stored here); message-derived ticket links are therefore out of scope (see `limitations`). The actor is mapped to ONE github login via, in order: MG_DASHBOARD_COMMIT_AUTHOR_ALIASES override, the MG Dashboard user's linked github_username, then code_battle_participants by login or display name. When it can't be mapped (or is ambiguous) the response carries an explicit `limitations` entry explaining how to fix it instead of guessing. dateFrom/dateTo accept a full ISO-8601 timestamp WITH offset (for the exact 19:00\u219219:00 window) or a bare YYYY-MM-DD date (local-midnight boundaries in `timezone`). The window is half-open [from, to).",
10316
+ inputSchema: {
10317
+ type: "object",
10318
+ properties: {
10319
+ actor: {
10320
+ type: "string",
10321
+ description: "Who to fetch commits for: a github login, an MG Dashboard user UUID/email/full name (e.g. 'Prince Rainier S. Mercado'), or a Code Battle display name. Resolved to one github login, returned as actor.githubUsername."
10322
+ },
10323
+ dateFrom: {
10324
+ type: "string",
10325
+ description: "Inclusive start: an ISO-8601 timestamp with offset (e.g. 2026-06-24T19:00:00+02:00) or YYYY-MM-DD (interpreted in `timezone`)."
10326
+ },
10327
+ dateTo: {
10328
+ type: "string",
10329
+ description: "Exclusive end: an ISO-8601 timestamp with offset (e.g. 2026-06-25T19:00:00+02:00) or YYYY-MM-DD (the whole calendar day is included)."
10330
+ },
10331
+ timezone: {
10332
+ type: "string",
10333
+ description: "IANA timezone for bare-date boundaries + output timestamps. Default Europe/Amsterdam."
10334
+ },
10335
+ repository: {
10336
+ type: "string",
10337
+ description: "Optional repo filter; accepts 'repo' or 'org/repo' (org prefix ignored), matched case-insensitively."
10338
+ },
10339
+ includeMerges: {
10340
+ type: "boolean",
10341
+ description: "Include merge commits in the commits list (default false). Summary counts always report merges separately."
10342
+ },
10343
+ pageSize: {
10344
+ type: "number",
10345
+ description: "Max commits listed (1-500, default 100). Summary counts are always the true period totals."
10346
+ }
10347
+ },
10348
+ required: ["actor", "dateFrom", "dateTo"]
10349
+ }
10350
+ },
10300
10351
  {
10301
10352
  name: "search-team-memory",
10302
10353
  description: "Search the team's ENTIRE past Cursor history (every developer, every project) for how something was handled before. Use this FIRST, before investigating from scratch, whenever you: hit a non-trivial bug or error, are about to build something that may have been done before, need a project-specific convention/gotcha, or the user asks 'have we done X', 'how did we fix Y', or 'did we solve this already'. Hybrid semantic + keyword search over mirrored conversations. Returns ranked past chats with repo, date, a solution snippet and a similarity score. Phrase the query as the problem in natural language (e.g. 'release pipeline PM2 deploy fails with module not found').",
@@ -10362,7 +10413,7 @@ var TOOLS = [
10362
10413
  },
10363
10414
  {
10364
10415
  name: "cursor-remote-run",
10365
- description: "Open a Cursor agent chat in a teammate's real IDE to make a code change. Resolve `who` (workspace owner name/email or machine name) + `project` (repo 'org/repo', URL, or workspace name) to a single online workspace, then hand off via the agent-host daemon: it opens that workspace's Cursor window, prefills the prompt and auto-submits it, so the developer sees the agent working live in their IDE. Use this when an AI (e.g. a ticket assistant) should hand a self-contained, well-scoped fix prompt to a developer's PC. There is no headless run and no diff-approval step \u2014 the developer reviews and commits in the IDE itself, unless autoCommit is set. The chat runs on the developer's default Cursor model (no model override). Optionally set autoCommit to have the daemon wait until the agent stops editing, then pull --rebase + commit + push the changes (clean-only: skipped if the workspace already had uncommitted changes). Returns the conversationId and a dashboard link to follow the chat. Call cursor-remote-list first if unsure about who/project.",
10416
+ description: "Open a Cursor agent chat in a teammate's real IDE to make a code change. Resolve `who` (workspace owner name/email or machine name) + `project` (repo 'org/repo', URL, or workspace name) to a single online workspace, then hand off via the agent-host daemon: it opens that workspace's Cursor window, prefills the prompt and auto-submits it, so the developer sees the agent working live in their IDE. Use this when an AI (e.g. a ticket assistant) should hand a self-contained, well-scoped fix prompt to a developer's PC. There is no headless run and no diff-approval step \u2014 the developer reviews and commits in the IDE itself, unless autoCommit is set. The chat runs on the developer's default Cursor model (no model override). Set autoCommit to append a commit + push instruction to the prompt so the agent itself commits and pushes its work when done (it stages only the files it changed). Returns the conversationId and a dashboard link to follow the chat. Call cursor-remote-list first if unsure about who/project.",
10366
10417
  inputSchema: {
10367
10418
  type: "object",
10368
10419
  properties: {
@@ -10384,11 +10435,11 @@ var TOOLS = [
10384
10435
  },
10385
10436
  autoCommit: {
10386
10437
  type: "boolean",
10387
- description: "When true, after the agent finishes editing the daemon runs pull --rebase + commit + push automatically. Clean-only: skipped if the workspace already had uncommitted changes at handoff time, so pre-existing work-in-progress is never committed. Default false (developer commits manually in the IDE)."
10438
+ description: "When true, a commit + push instruction is appended to the prompt so the agent commits and pushes its own work when the task is done (staging only the files it changed, leaving any pre-existing local changes untouched). Default false (developer commits manually in the IDE)."
10388
10439
  },
10389
10440
  commitBranch: {
10390
10441
  type: "string",
10391
- description: "Only with autoCommit. Branch to commit + push the agent's changes to (e.g. a ticket number like '2025-REFRO-119'); created from the current HEAD if it doesn't exist. Omit to commit on the workspace's current branch."
10442
+ description: "Only with autoCommit. Branch the agent is told to commit + push to (e.g. a ticket number like '2025-REFRO-119'); created from the current HEAD if it doesn't exist. Omit to commit on the workspace's current branch."
10392
10443
  }
10393
10444
  },
10394
10445
  required: ["project", "prompt"]
@@ -10477,6 +10528,53 @@ async function executeToolCall(name, a, _serverId) {
10477
10528
  const ctx = authContext;
10478
10529
  try {
10479
10530
  switch (name) {
10531
+ // ----- MG Dashboard git commits (for external daily reports) -----
10532
+ case "get_mg_dashboard_commits": {
10533
+ const actor = typeof a.actor === "string" ? a.actor.trim() : "";
10534
+ const dateFrom = typeof a.dateFrom === "string" ? a.dateFrom.trim() : "";
10535
+ const dateTo = typeof a.dateTo === "string" ? a.dateTo.trim() : "";
10536
+ if (!actor || !dateFrom || !dateTo) {
10537
+ return {
10538
+ content: [
10539
+ {
10540
+ type: "text",
10541
+ text: "Error: actor, dateFrom and dateTo are required"
10542
+ }
10543
+ ]
10544
+ };
10545
+ }
10546
+ const res = await fetch(`${dashboardBaseUrl}/api/activity/commits`, {
10547
+ method: "POST",
10548
+ headers: {
10549
+ "content-type": "application/json",
10550
+ authorization: `Bearer ${apiKey}`
10551
+ },
10552
+ body: JSON.stringify({
10553
+ actor,
10554
+ dateFrom,
10555
+ dateTo,
10556
+ timezone: typeof a.timezone === "string" ? a.timezone : void 0,
10557
+ repository: typeof a.repository === "string" ? a.repository : void 0,
10558
+ includeMerges: typeof a.includeMerges === "boolean" ? a.includeMerges : void 0,
10559
+ pageSize: typeof a.pageSize === "number" ? a.pageSize : void 0
10560
+ })
10561
+ });
10562
+ if (!res.ok) {
10563
+ const detail = await res.text().catch(() => "");
10564
+ return {
10565
+ content: [
10566
+ {
10567
+ type: "text",
10568
+ text: `Error: mg-dashboard commits fetch failed (${res.status}). ${detail.slice(0, 300)}`
10569
+ }
10570
+ ]
10571
+ };
10572
+ }
10573
+ const data = await res.json();
10574
+ return {
10575
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
10576
+ };
10577
+ }
10480
10578
  // ----- Team memory -----
10481
10579
  case "search-team-memory": {
10482
10580
  const query = typeof a.query === "string" ? a.query.trim() : "";
@@ -10746,7 +10844,7 @@ ${candidates || " (none online \u2014 start the MG Agent Host)"}`
10746
10844
  conversationUrl,
10747
10845
  autoCommit,
10748
10846
  commitBranch: autoCommit ? commitBranch ?? "(current branch)" : null,
10749
- note: autoCommit ? `Opens the workspace's real Cursor IDE, prefills the prompt and auto-submits it. After the agent stops editing, the daemon will pull --rebase + commit + push to ${commitBranch ?? "the current branch"} (skipped if the workspace had uncommitted changes at start).` : "Opens the workspace's real Cursor IDE, prefills the prompt and auto-submits it. The developer sees the agent working live and reviews/commits in the IDE \u2014 no diff approval step."
10847
+ note: autoCommit ? `Opens the workspace's real Cursor IDE, prefills the prompt and auto-submits it. The prompt instructs the agent to commit + push its own changes to ${commitBranch ?? "the current branch"} when done (staging only what it changed).` : "Opens the workspace's real Cursor IDE, prefills the prompt and auto-submits it. The developer sees the agent working live and reviews/commits in the IDE \u2014 no diff approval step."
10750
10848
  },
10751
10849
  null,
10752
10850
  2