@taiga-ai/mcp-server 0.26.0-dev.486 → 0.26.0-dev.487
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 +74 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1385,6 +1385,49 @@ z.object({
|
|
|
1385
1385
|
...e.failingChecks === void 0 ? {} : { failingChecks: e.failingChecks },
|
|
1386
1386
|
...e.blockers === void 0 ? {} : { blockers: e.blockers }
|
|
1387
1387
|
}));
|
|
1388
|
+
/**
|
|
1389
|
+
* What a run's hardening came to, coverage included (PRO-2829). `passed`
|
|
1390
|
+
* counted only blocking findings, so a run whose scanners never ran said
|
|
1391
|
+
* "passed" all the same.
|
|
1392
|
+
*
|
|
1393
|
+
* - `failed`: blocking findings remain (the gaps are still listed).
|
|
1394
|
+
* - `not_scanned`: no scanner that applies to the repository ran to the end.
|
|
1395
|
+
* - `passed_with_gaps`: nothing blocks, but some scanner did not run.
|
|
1396
|
+
* - `passed`: nothing blocks and every scanner that applies ran.
|
|
1397
|
+
*/
|
|
1398
|
+
const HARDENING_VERDICTS = [
|
|
1399
|
+
"passed",
|
|
1400
|
+
"passed_with_gaps",
|
|
1401
|
+
"not_scanned",
|
|
1402
|
+
"failed"
|
|
1403
|
+
];
|
|
1404
|
+
/**
|
|
1405
|
+
* The verdict and the gaps of a hardening result (PRO-2829), for every reader
|
|
1406
|
+
* (the run read, the web's run page, the MCP), from what the agent reported.
|
|
1407
|
+
*
|
|
1408
|
+
* A gap is a scanner that applies and did not run: `not_run` (the scan never
|
|
1409
|
+
* reached it), `skipped` (its tool was missing), or `failed` with a reason,
|
|
1410
|
+
* which is a scanner that could not finish. A `failed` scanner without one
|
|
1411
|
+
* found something (tflint fails on a MAJOR that blocks nothing, and rows from
|
|
1412
|
+
* before `scannerReasons` used `failed` for "had findings"), so it ran and is
|
|
1413
|
+
* no gap. A scanner listed in `notApplicable` is no gap; on a result from
|
|
1414
|
+
* before that list, a skipped tflint is read the same way, as the only reason
|
|
1415
|
+
* the agent ever skipped it was a repository with no Terraform.
|
|
1416
|
+
*/
|
|
1417
|
+
function hardeningCoverage(result) {
|
|
1418
|
+
const notApplicable = new Set(result.notApplicable ?? []);
|
|
1419
|
+
const applies = Object.entries(result.scanners ?? {}).filter(([scanner, status]) => !notApplicable.has(scanner) && !(result.notApplicable === void 0 && scanner === "tflint" && status === "skipped"));
|
|
1420
|
+
const reasons = result.scannerReasons ?? {};
|
|
1421
|
+
const gaps = applies.filter(([scanner, status]) => status === "not_run" || status === "skipped" || status === "failed" && scanner in reasons).map(([scanner, status]) => ({
|
|
1422
|
+
scanner,
|
|
1423
|
+
status,
|
|
1424
|
+
reason: reasons[scanner] ?? null
|
|
1425
|
+
}));
|
|
1426
|
+
return {
|
|
1427
|
+
verdict: !result.passed ? "failed" : gaps.length === applies.length ? "not_scanned" : gaps.length > 0 ? "passed_with_gaps" : "passed",
|
|
1428
|
+
gaps
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1388
1431
|
[...BUILD_RUN_ACTIVE_STATUSES.filter((s) => s !== "reviewing")];
|
|
1389
1432
|
//#endregion
|
|
1390
1433
|
//#region ../../packages/types/dist/agents.js
|
|
@@ -3942,6 +3985,34 @@ function hardeningSaid(blocking, named) {
|
|
|
3942
3985
|
const recorded = named.length > shown.length ? `, ${named.length} recorded in taiga_get_run` : "";
|
|
3943
3986
|
return `${count}: ${shown.join("; ")}${rest > 0 ? `; and ${rest} more${recorded}` : ""}.`;
|
|
3944
3987
|
}
|
|
3988
|
+
/** How each hardening verdict reads (PRO-2829): "passed" only when every scanner that applies ran. */
|
|
3989
|
+
const VERDICT_SAID = {
|
|
3990
|
+
passed: "Hardening passed: every scanner that applies ran and nothing blocks",
|
|
3991
|
+
passed_with_gaps: "Hardening passed, but not every scanner ran, so its checks are missing from the result",
|
|
3992
|
+
not_scanned: "No security scanner ran in hardening: \"passed\" only means no blocking finding was recorded",
|
|
3993
|
+
failed: "Hardening failed: blocking findings remain"
|
|
3994
|
+
};
|
|
3995
|
+
/**
|
|
3996
|
+
* What a run's hardening came to, coverage included (PRO-2829), from the
|
|
3997
|
+
* verdict the API reads off it, or read here from an API from before that.
|
|
3998
|
+
* Null without a hardening result.
|
|
3999
|
+
*/
|
|
4000
|
+
function scanSaid(hardening) {
|
|
4001
|
+
if (!hardening || typeof hardening !== "object") return null;
|
|
4002
|
+
const h = hardening;
|
|
4003
|
+
const coverage = typeof h.verdict === "string" && HARDENING_VERDICTS.includes(h.verdict) && Array.isArray(h.gaps) ? {
|
|
4004
|
+
verdict: h.verdict,
|
|
4005
|
+
gaps: h.gaps
|
|
4006
|
+
} : typeof h.passed === "boolean" && h.scanners ? hardeningCoverage(h) : null;
|
|
4007
|
+
if (!coverage) return null;
|
|
4008
|
+
const gaps = coverage.gaps.map((gap) => `${gap.scanner}${gap.status === "failed" ? " did not finish" : ""}${gap.reason ? ` (${gap.reason})` : ""}`);
|
|
4009
|
+
const missing = gaps.length > 0 ? `; did not run: ${gaps.join(", ")}` : "";
|
|
4010
|
+
return {
|
|
4011
|
+
verdict: coverage.verdict,
|
|
4012
|
+
gaps: gaps.length,
|
|
4013
|
+
said: `${VERDICT_SAID[coverage.verdict]}${missing}.`
|
|
4014
|
+
};
|
|
4015
|
+
}
|
|
3945
4016
|
/**
|
|
3946
4017
|
* What each failedReason means for the next move (PRO-2800): reviewers met dispatch_rejected and agent_reported as
|
|
3947
4018
|
* bare enums. As @taiga/types documents them.
|
|
@@ -3968,9 +4039,11 @@ function readableRun(run, opts = {}) {
|
|
|
3968
4039
|
const hardening = run["hardeningResult"];
|
|
3969
4040
|
const blocking = typeof hardening?.blockingFindings === "number" ? hardening.blockingFindings : 0;
|
|
3970
4041
|
const named = Array.isArray(hardening?.blocking) ? hardening.blocking : [];
|
|
4042
|
+
const scan = scanSaid(hardening);
|
|
3971
4043
|
return {
|
|
3972
4044
|
...rest,
|
|
3973
4045
|
...means ? { failedReasonMeans: means } : {},
|
|
4046
|
+
...scan && scan.gaps + (scan.verdict === "not_scanned" ? 1 : 0) > 0 ? { scanCoverage: scan.said } : {},
|
|
3974
4047
|
...blocking > 0 ? { hardeningNote: hardeningSaid(blocking, named) } : {},
|
|
3975
4048
|
...opts.row || error === void 0 ? {} : { error },
|
|
3976
4049
|
...opts.row || reviewEscalation === void 0 ? {} : { reviewEscalation },
|
|
@@ -4172,7 +4245,7 @@ function registerBuildTools(server, client) {
|
|
|
4172
4245
|
}));
|
|
4173
4246
|
server.registerTool("taiga_get_run", {
|
|
4174
4247
|
title: "Get run",
|
|
4175
|
-
description: "Read one run with its steps: outcome, disposition, pull request, hardening, and per step its title, status, commit, files changed, verification and headline (first paragraph of the agent's report). verification is Taiga's own check after the step (tests, lint, build), so a docs-only step can fail on the repository's failing tests (verificationNote says when one failed throughout). A failed or stopped run has stoppedIn, lastProgressAt and failedReasonMeans (what its failedReason means). full: true adds complete instructions and reports. actions: resume and retry_from_failed_step are taiga_resume_initiative; webOnlyActions (start_over) are in the web; to stop it, move the initiative out of Build. A maintenance run has no initiative and is retried from its finding.",
|
|
4248
|
+
description: "Read one run with its steps: outcome, disposition, pull request, hardening (scanCoverage names the security scanners that did not run, and why; hardeningResult.verdict is passed only when every one ran), and per step its title, status, commit, files changed, verification and headline (first paragraph of the agent's report). verification is Taiga's own check after the step (tests, lint, build), so a docs-only step can fail on the repository's failing tests (verificationNote says when one failed throughout). A failed or stopped run has stoppedIn, lastProgressAt and failedReasonMeans (what its failedReason means). full: true adds complete instructions and reports. actions: resume and retry_from_failed_step are taiga_resume_initiative; webOnlyActions (start_over) are in the web; to stop it, move the initiative out of Build. A maintenance run has no initiative and is retried from its finding.",
|
|
4176
4249
|
inputSchema: z.object({
|
|
4177
4250
|
runId,
|
|
4178
4251
|
full: z.boolean().optional().describe("Carry each step's complete instructions and report (default false: a summary)")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taiga-ai/mcp-server",
|
|
3
|
-
"version": "0.26.0-dev.
|
|
3
|
+
"version": "0.26.0-dev.487",
|
|
4
4
|
"description": "Taiga for AI coding assistants: read products, policies, initiatives and runs, and operate the line, over MCP",
|
|
5
5
|
"mcpName": "ga.tai/mcp-server",
|
|
6
6
|
"type": "module",
|