@vibekiln/cutline-mcp-cli 0.1.1 → 0.2.0
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/commands/setup.d.ts +2 -0
- package/dist/commands/setup.js +108 -5
- package/dist/index.js +9 -1
- package/dist/servers/{chunk-WWTNBUIX.js → chunk-LI4AZPSJ.js} +29 -24
- package/dist/servers/cutline-server.js +87 -17
- package/dist/servers/{data-client-2YBU5KRO.js → data-client-PYMN6TQ7.js} +1 -1
- package/dist/servers/exploration-server.js +1 -1
- package/dist/servers/integrations-server.js +1 -1
- package/dist/servers/output-server.js +1 -1
- package/dist/servers/premortem-server.js +1 -1
- package/dist/servers/tools-server.js +1 -1
- package/package.json +1 -1
package/dist/commands/setup.d.ts
CHANGED
package/dist/commands/setup.js
CHANGED
|
@@ -27,6 +27,7 @@ const SERVER_NAMES = [
|
|
|
27
27
|
'output',
|
|
28
28
|
'integrations',
|
|
29
29
|
];
|
|
30
|
+
const AUDIT_DIMENSIONS = ['engineering', 'security', 'reliability', 'scalability'];
|
|
30
31
|
async function detectTier(options) {
|
|
31
32
|
const refreshToken = await getRefreshToken();
|
|
32
33
|
if (!refreshToken)
|
|
@@ -83,14 +84,100 @@ function prompt(question) {
|
|
|
83
84
|
});
|
|
84
85
|
});
|
|
85
86
|
}
|
|
86
|
-
function
|
|
87
|
+
function parseDimensionCsv(csv) {
|
|
88
|
+
if (!csv)
|
|
89
|
+
return [];
|
|
90
|
+
return csv
|
|
91
|
+
.split(',')
|
|
92
|
+
.map((s) => s.trim())
|
|
93
|
+
.filter(Boolean);
|
|
94
|
+
}
|
|
95
|
+
function normalizeAuditDimensions(values) {
|
|
96
|
+
const allowed = new Set(AUDIT_DIMENSIONS);
|
|
97
|
+
const deduped = [...new Set(values.map((v) => v.trim().toLowerCase()).filter(Boolean))];
|
|
98
|
+
const valid = deduped.filter((v) => allowed.has(v));
|
|
99
|
+
const invalid = deduped.filter((v) => !allowed.has(v));
|
|
100
|
+
return { valid, invalid };
|
|
101
|
+
}
|
|
102
|
+
async function resolveHiddenAuditDimensions(options) {
|
|
103
|
+
const explicit = [
|
|
104
|
+
...(options.hideAuditDimension ?? []),
|
|
105
|
+
...parseDimensionCsv(options.hideAuditDimensions),
|
|
106
|
+
];
|
|
107
|
+
if (explicit.length > 0) {
|
|
108
|
+
const { valid, invalid } = normalizeAuditDimensions(explicit);
|
|
109
|
+
if (invalid.length > 0) {
|
|
110
|
+
console.log(chalk.yellow(` Ignoring invalid audit dimensions: ${invalid.join(', ')} ` +
|
|
111
|
+
`(allowed: ${AUDIT_DIMENSIONS.join(', ')})`));
|
|
112
|
+
}
|
|
113
|
+
return valid;
|
|
114
|
+
}
|
|
115
|
+
const answer = await prompt(chalk.cyan(` Hide any code audit dimensions? ` +
|
|
116
|
+
`(comma-separated: ${AUDIT_DIMENSIONS.join(', ')}; Enter for none): `));
|
|
117
|
+
if (!answer)
|
|
118
|
+
return [];
|
|
119
|
+
const { valid, invalid } = normalizeAuditDimensions(parseDimensionCsv(answer));
|
|
120
|
+
if (invalid.length > 0) {
|
|
121
|
+
console.log(chalk.yellow(` Ignoring invalid audit dimensions: ${invalid.join(', ')} ` +
|
|
122
|
+
`(allowed: ${AUDIT_DIMENSIONS.join(', ')})`));
|
|
123
|
+
}
|
|
124
|
+
return valid;
|
|
125
|
+
}
|
|
126
|
+
function writeAuditVisibilityConfig(hiddenDimensions) {
|
|
127
|
+
const configDir = join(homedir(), '.cutline-mcp');
|
|
128
|
+
const configPath = join(configDir, 'config.json');
|
|
129
|
+
let existing = {};
|
|
130
|
+
try {
|
|
131
|
+
if (existsSync(configPath)) {
|
|
132
|
+
existing = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
existing = {};
|
|
137
|
+
}
|
|
138
|
+
const next = {
|
|
139
|
+
...existing,
|
|
140
|
+
audit_visibility: {
|
|
141
|
+
...(existing.audit_visibility ?? {}),
|
|
142
|
+
hidden_dimensions: hiddenDimensions,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
mkdirSync(configDir, { recursive: true });
|
|
146
|
+
writeFileSync(configPath, JSON.stringify(next, null, 2) + '\n');
|
|
147
|
+
}
|
|
148
|
+
function resolveServeRuntime() {
|
|
149
|
+
// Optional explicit override for advanced environments.
|
|
150
|
+
if (process.env.CUTLINE_MCP_BIN?.trim()) {
|
|
151
|
+
return {
|
|
152
|
+
command: process.env.CUTLINE_MCP_BIN.trim(),
|
|
153
|
+
argsPrefix: [],
|
|
154
|
+
source: 'binary',
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
// Prefer the globally installed binary for faster/more reliable startup.
|
|
158
|
+
const voltaBin = join(homedir(), '.volta', 'bin', 'cutline-mcp');
|
|
159
|
+
if (existsSync(voltaBin)) {
|
|
160
|
+
return {
|
|
161
|
+
command: voltaBin,
|
|
162
|
+
argsPrefix: [],
|
|
163
|
+
source: 'binary',
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// Fallback for machines without a global install.
|
|
87
167
|
const voltaNpx = join(homedir(), '.volta', 'bin', 'npx');
|
|
88
168
|
const npxCommand = existsSync(voltaNpx) ? voltaNpx : 'npx';
|
|
169
|
+
return {
|
|
170
|
+
command: npxCommand,
|
|
171
|
+
argsPrefix: ['-y', '@vibekiln/cutline-mcp-cli@latest'],
|
|
172
|
+
source: 'npx',
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function buildServerConfig(runtime) {
|
|
89
176
|
const config = {};
|
|
90
177
|
for (const name of SERVER_NAMES) {
|
|
91
178
|
config[`cutline-${name}`] = {
|
|
92
|
-
command:
|
|
93
|
-
args: [
|
|
179
|
+
command: runtime.command,
|
|
180
|
+
args: [...runtime.argsPrefix, 'serve', name],
|
|
94
181
|
};
|
|
95
182
|
}
|
|
96
183
|
return config;
|
|
@@ -197,8 +284,17 @@ export async function setupCommand(options) {
|
|
|
197
284
|
}
|
|
198
285
|
catch { /* ignore parse errors */ }
|
|
199
286
|
}
|
|
287
|
+
const hiddenAuditDimensions = await resolveHiddenAuditDimensions(options);
|
|
288
|
+
writeAuditVisibilityConfig(hiddenAuditDimensions);
|
|
289
|
+
if (hiddenAuditDimensions.length > 0) {
|
|
290
|
+
console.log(chalk.dim(` Hidden audit dimensions: ${hiddenAuditDimensions.join(', ')}\n`));
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
console.log(chalk.dim(' Hidden audit dimensions: none\n'));
|
|
294
|
+
}
|
|
200
295
|
// ── 3. Write MCP server config to IDEs ───────────────────────────────────
|
|
201
|
-
const
|
|
296
|
+
const runtime = resolveServeRuntime();
|
|
297
|
+
const serverConfig = buildServerConfig(runtime);
|
|
202
298
|
const home = homedir();
|
|
203
299
|
const ideConfigs = [
|
|
204
300
|
{ name: 'Cursor', path: join(home, '.cursor', 'mcp.json') },
|
|
@@ -217,6 +313,12 @@ export async function setupCommand(options) {
|
|
|
217
313
|
}
|
|
218
314
|
if (wroteAny) {
|
|
219
315
|
console.log(chalk.dim('\n MCP server entries merged into IDE config (existing servers preserved).\n'));
|
|
316
|
+
if (runtime.source === 'binary') {
|
|
317
|
+
console.log(chalk.dim(` Using local MCP binary: ${runtime.command}\n`));
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
console.log(chalk.dim(' Local `cutline-mcp` binary not found — using npx fallback.\n'));
|
|
321
|
+
}
|
|
220
322
|
}
|
|
221
323
|
else {
|
|
222
324
|
console.log(chalk.yellow('\n No IDE config files found. Printing config for manual setup:\n'));
|
|
@@ -231,7 +333,8 @@ export async function setupCommand(options) {
|
|
|
231
333
|
console.log(chalk.dim(' If you prefer `claude mcp add` instead of ~/.claude.json:\n'));
|
|
232
334
|
const coreServers = ['constraints', 'premortem', 'tools', 'exploration'];
|
|
233
335
|
for (const name of coreServers) {
|
|
234
|
-
|
|
336
|
+
const invocation = [runtime.command, ...runtime.argsPrefix, 'serve', name].join(' ');
|
|
337
|
+
console.log(chalk.cyan(` claude mcp add cutline-${name} -- ${invocation}`));
|
|
235
338
|
}
|
|
236
339
|
console.log();
|
|
237
340
|
// ── 6. What you can do ───────────────────────────────────────────────────
|
package/dist/index.js
CHANGED
|
@@ -54,7 +54,15 @@ program
|
|
|
54
54
|
.option('--staging', 'Use staging environment')
|
|
55
55
|
.option('--skip-login', 'Skip authentication (use existing credentials)')
|
|
56
56
|
.option('--project-root <path>', 'Project root directory for IDE rules (default: cwd)')
|
|
57
|
-
.
|
|
57
|
+
.option('--hide-audit-dimension <name>', 'Hide one audit dimension in surfaced code audit output (repeatable)', (value, prev) => [...prev, value], [])
|
|
58
|
+
.option('--hide-audit-dimensions <csv>', 'Hide multiple audit dimensions (comma-separated: engineering,security,reliability,scalability)')
|
|
59
|
+
.action((opts) => setupCommand({
|
|
60
|
+
staging: opts.staging,
|
|
61
|
+
skipLogin: opts.skipLogin,
|
|
62
|
+
projectRoot: opts.projectRoot,
|
|
63
|
+
hideAuditDimension: opts.hideAuditDimension,
|
|
64
|
+
hideAuditDimensions: opts.hideAuditDimensions,
|
|
65
|
+
}));
|
|
58
66
|
program
|
|
59
67
|
.command('init')
|
|
60
68
|
.description('Generate IDE rules only (setup runs this automatically)')
|
|
@@ -287,6 +287,24 @@ async function exchangeRefreshToken(refreshToken, firebaseApiKey, maxRetries = 3
|
|
|
287
287
|
}
|
|
288
288
|
throw lastError || new Error("Token exchange failed after retries");
|
|
289
289
|
}
|
|
290
|
+
var AUDIT_DIMENSIONS = ["engineering", "security", "reliability", "scalability"];
|
|
291
|
+
function readLocalCutlineConfig() {
|
|
292
|
+
try {
|
|
293
|
+
const configPath = path.join(os.homedir(), ".cutline-mcp", "config.json");
|
|
294
|
+
if (!fs.existsSync(configPath))
|
|
295
|
+
return null;
|
|
296
|
+
return JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
297
|
+
} catch {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function getHiddenAuditDimensions() {
|
|
302
|
+
const config = readLocalCutlineConfig();
|
|
303
|
+
const hidden = config?.audit_visibility?.hidden_dimensions ?? [];
|
|
304
|
+
const allowed = new Set(AUDIT_DIMENSIONS);
|
|
305
|
+
const normalized = [...new Set(hidden.map((d) => String(d).trim().toLowerCase()).filter((d) => allowed.has(d)))];
|
|
306
|
+
return normalized;
|
|
307
|
+
}
|
|
290
308
|
function getStoredApiKey() {
|
|
291
309
|
if (process.env.CUTLINE_API_KEY) {
|
|
292
310
|
return {
|
|
@@ -294,15 +312,9 @@ function getStoredApiKey() {
|
|
|
294
312
|
environment: process.env.CUTLINE_ENV === "staging" ? "staging" : "production"
|
|
295
313
|
};
|
|
296
314
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
301
|
-
if (config.apiKey) {
|
|
302
|
-
return { apiKey: config.apiKey, environment: config.environment };
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
} catch {
|
|
315
|
+
const config = readLocalCutlineConfig();
|
|
316
|
+
if (config?.apiKey) {
|
|
317
|
+
return { apiKey: config.apiKey, environment: config.environment };
|
|
306
318
|
}
|
|
307
319
|
return null;
|
|
308
320
|
}
|
|
@@ -314,21 +326,13 @@ async function getStoredToken() {
|
|
|
314
326
|
environment: process.env.CUTLINE_ENV === "staging" ? "staging" : "production"
|
|
315
327
|
};
|
|
316
328
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
return {
|
|
325
|
-
refreshToken: config.refreshToken,
|
|
326
|
-
environment: config.environment
|
|
327
|
-
};
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
} catch (e) {
|
|
331
|
-
console.error("[MCP Auth] Failed to read config file:", e);
|
|
329
|
+
const config = readLocalCutlineConfig();
|
|
330
|
+
if (config?.refreshToken) {
|
|
331
|
+
console.error("[MCP Auth] Using token from ~/.cutline-mcp/config.json", config.environment ? `(environment: ${config.environment})` : "");
|
|
332
|
+
return {
|
|
333
|
+
refreshToken: config.refreshToken,
|
|
334
|
+
environment: config.environment
|
|
335
|
+
};
|
|
332
336
|
}
|
|
333
337
|
return null;
|
|
334
338
|
}
|
|
@@ -991,6 +995,7 @@ export {
|
|
|
991
995
|
mapErrorToMcp,
|
|
992
996
|
validateAuth,
|
|
993
997
|
resolveAuthContext,
|
|
998
|
+
getHiddenAuditDimensions,
|
|
994
999
|
requirePremiumWithAutoAuth,
|
|
995
1000
|
resolveAuthContextFree,
|
|
996
1001
|
getPublicSiteUrlForCurrentAuth,
|
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
getAllNodesLight,
|
|
44
44
|
getEntitiesWithEmbeddings,
|
|
45
45
|
getGraphMetadata,
|
|
46
|
+
getHiddenAuditDimensions,
|
|
46
47
|
getIdeaReport,
|
|
47
48
|
getNodesByCategories,
|
|
48
49
|
getNodesMissingEmbeddings,
|
|
@@ -74,7 +75,7 @@ import {
|
|
|
74
75
|
upsertEntities,
|
|
75
76
|
upsertNodes,
|
|
76
77
|
validateRequestSize
|
|
77
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-LI4AZPSJ.js";
|
|
78
79
|
import {
|
|
79
80
|
GraphTraverser,
|
|
80
81
|
computeGenericGraphMetrics,
|
|
@@ -6966,10 +6967,22 @@ function deltaStr(current, previous) {
|
|
|
6966
6967
|
return " (no change)";
|
|
6967
6968
|
return diff > 0 ? ` (**+${diff}** since last scan)` : ` (**${diff}** since last scan)`;
|
|
6968
6969
|
}
|
|
6969
|
-
function formatAuditOutput(result, reportId, publicSiteUrl = "https://thecutline.ai") {
|
|
6970
|
+
function formatAuditOutput(result, reportId, publicSiteUrl = "https://thecutline.ai", hiddenAuditDimensions = []) {
|
|
6970
6971
|
const m = result.metrics;
|
|
6971
6972
|
const p = result.previousMetrics;
|
|
6972
6973
|
const isRescan = !!p;
|
|
6974
|
+
const hiddenSet = new Set(hiddenAuditDimensions.map((d) => String(d).trim().toLowerCase()));
|
|
6975
|
+
const securityVisible = !hiddenSet.has("security");
|
|
6976
|
+
const inferFindingDimension = (category) => {
|
|
6977
|
+
const c = (category ?? "").toLowerCase();
|
|
6978
|
+
if (["reliability"].includes(c))
|
|
6979
|
+
return "reliability";
|
|
6980
|
+
if (["scalability", "performance"].includes(c))
|
|
6981
|
+
return "scalability";
|
|
6982
|
+
if (["code_quality", "general"].includes(c))
|
|
6983
|
+
return "engineering";
|
|
6984
|
+
return "security";
|
|
6985
|
+
};
|
|
6973
6986
|
const lines = [
|
|
6974
6987
|
`# Cutline Code Audit`,
|
|
6975
6988
|
``,
|
|
@@ -6979,8 +6992,43 @@ function formatAuditOutput(result, reportId, publicSiteUrl = "https://thecutline
|
|
|
6979
6992
|
if (result.frameworksLoaded.length > 0) {
|
|
6980
6993
|
lines.push(`**Compliance frameworks:** ${result.frameworksLoaded.join(", ")}`);
|
|
6981
6994
|
}
|
|
6982
|
-
|
|
6983
|
-
|
|
6995
|
+
const scoreRows = [
|
|
6996
|
+
{
|
|
6997
|
+
key: "engineering",
|
|
6998
|
+
label: "Engineering",
|
|
6999
|
+
current: m.engineering_readiness_pct ?? 0,
|
|
7000
|
+
previous: p?.engineering_readiness_pct
|
|
7001
|
+
},
|
|
7002
|
+
{
|
|
7003
|
+
key: "security",
|
|
7004
|
+
label: "Security",
|
|
7005
|
+
current: m.security_readiness_pct ?? 0,
|
|
7006
|
+
previous: p?.security_readiness_pct
|
|
7007
|
+
},
|
|
7008
|
+
{
|
|
7009
|
+
key: "reliability",
|
|
7010
|
+
label: "Reliability",
|
|
7011
|
+
current: m.reliability_readiness_pct ?? 0,
|
|
7012
|
+
previous: p?.reliability_readiness_pct
|
|
7013
|
+
},
|
|
7014
|
+
{
|
|
7015
|
+
key: "scalability",
|
|
7016
|
+
label: "Scalability",
|
|
7017
|
+
current: m.scalability_readiness_pct ?? 0,
|
|
7018
|
+
previous: p?.scalability_readiness_pct
|
|
7019
|
+
}
|
|
7020
|
+
].filter((row) => !hiddenSet.has(row.key));
|
|
7021
|
+
lines.push(``, `## Readiness Scores`, ``, `| Pillar | Score |${isRescan ? " Change |" : ""}`, `|--------|-------|${isRescan ? "--------|" : ""}`);
|
|
7022
|
+
if (scoreRows.length > 0) {
|
|
7023
|
+
for (const row of scoreRows) {
|
|
7024
|
+
lines.push(`| ${row.label} | ${row.current}% |${isRescan ? deltaStr(row.current, row.previous) + " |" : ""}`);
|
|
7025
|
+
}
|
|
7026
|
+
lines.push(``);
|
|
7027
|
+
} else {
|
|
7028
|
+
lines.push(`| _Hidden by local audit visibility settings_ | - |${isRescan ? " - |" : ""}`, ``);
|
|
7029
|
+
}
|
|
7030
|
+
lines.push(`**Constraints mapped:** ${m.complexity_factors?.nfr_count ?? 0} (${m.complexity_factors?.critical_nfr_count ?? 0} critical)`, `**Binding coverage:** ${result.bindingHealth.coverage_pct}%`);
|
|
7031
|
+
if (securityVisible && result.scaFindings && result.scaFindings.total > 0) {
|
|
6984
7032
|
const sca = result.scaFindings;
|
|
6985
7033
|
lines.push(``, `## Dependency Vulnerabilities (SCA)`, ``, `**${sca.total} known vulnerabilities** found (${sca.critical} critical, ${sca.high} high)`, ``);
|
|
6986
7034
|
for (const v of sca.top) {
|
|
@@ -6991,12 +7039,13 @@ function formatAuditOutput(result, reportId, publicSiteUrl = "https://thecutline
|
|
|
6991
7039
|
lines.push(`- ...and ${sca.total - sca.top.length} more`);
|
|
6992
7040
|
}
|
|
6993
7041
|
}
|
|
6994
|
-
const
|
|
6995
|
-
const
|
|
7042
|
+
const visibleFindings = result.gatedGapDetails.filter((g) => !hiddenSet.has(inferFindingDimension(g.category)));
|
|
7043
|
+
const totalFindings = visibleFindings.length;
|
|
7044
|
+
const criticalCount = visibleFindings.filter((g) => g.severity === "critical" || g.severity === "high").length;
|
|
6996
7045
|
if (totalFindings > 0) {
|
|
6997
|
-
const topFinding =
|
|
7046
|
+
const topFinding = visibleFindings[0];
|
|
6998
7047
|
lines.push(``, `## #1 Finding \u2014 Fix This Now`, ``, `**[${topFinding.severity.toUpperCase()}] ${topFinding.title}**`, `*Category: ${topFinding.category}*`, ``, topFinding.description || "Address this finding to improve your readiness scores.", ``, `> Fix this issue, then re-run \`code_audit\` to see your scores improve.`);
|
|
6999
|
-
const remaining =
|
|
7048
|
+
const remaining = visibleFindings.slice(1);
|
|
7000
7049
|
if (remaining.length > 0) {
|
|
7001
7050
|
lines.push(``, `## ${remaining.length} More Finding${remaining.length > 1 ? "s" : ""} Detected`);
|
|
7002
7051
|
const teaserLimit = Math.min(remaining.length, 5);
|
|
@@ -8222,6 +8271,18 @@ Why AI: ${idea.whyAI}`
|
|
|
8222
8271
|
}
|
|
8223
8272
|
const freeAuth = await resolveAuthContextFree(scanArgs.auth_token);
|
|
8224
8273
|
const uid = freeAuth.effectiveUid;
|
|
8274
|
+
const hiddenAuditDimensions = getHiddenAuditDimensions();
|
|
8275
|
+
const hiddenSet = new Set(hiddenAuditDimensions);
|
|
8276
|
+
const inferFindingDimension = (category) => {
|
|
8277
|
+
const c = (category ?? "").toLowerCase();
|
|
8278
|
+
if (["reliability"].includes(c))
|
|
8279
|
+
return "reliability";
|
|
8280
|
+
if (["scalability", "performance"].includes(c))
|
|
8281
|
+
return "scalability";
|
|
8282
|
+
if (["code_quality", "general"].includes(c))
|
|
8283
|
+
return "engineering";
|
|
8284
|
+
return "security";
|
|
8285
|
+
};
|
|
8225
8286
|
{
|
|
8226
8287
|
const rateInfo = await getScanRateLimit();
|
|
8227
8288
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -8258,24 +8319,33 @@ Why AI: ${idea.whyAI}`
|
|
|
8258
8319
|
let reportId;
|
|
8259
8320
|
let reportSiteUrl = "https://thecutline.ai";
|
|
8260
8321
|
try {
|
|
8322
|
+
const reportMetrics = {};
|
|
8323
|
+
if (!hiddenSet.has("engineering")) {
|
|
8324
|
+
reportMetrics.engineering_readiness_pct = result.metrics.engineering_readiness_pct ?? 0;
|
|
8325
|
+
}
|
|
8326
|
+
if (!hiddenSet.has("security")) {
|
|
8327
|
+
reportMetrics.security_readiness_pct = result.metrics.security_readiness_pct ?? 0;
|
|
8328
|
+
}
|
|
8329
|
+
if (!hiddenSet.has("reliability")) {
|
|
8330
|
+
reportMetrics.reliability_readiness_pct = result.metrics.reliability_readiness_pct ?? 0;
|
|
8331
|
+
}
|
|
8332
|
+
if (!hiddenSet.has("scalability")) {
|
|
8333
|
+
reportMetrics.scalability_readiness_pct = result.metrics.scalability_readiness_pct ?? 0;
|
|
8334
|
+
}
|
|
8335
|
+
const visibleFindings = result.gatedGapDetails.filter((f) => !hiddenSet.has(inferFindingDimension(f.category)));
|
|
8261
8336
|
const saved = await saveScanReport({
|
|
8262
|
-
metrics:
|
|
8263
|
-
engineering_readiness_pct: result.metrics.engineering_readiness_pct ?? 0,
|
|
8264
|
-
security_readiness_pct: result.metrics.security_readiness_pct ?? 0,
|
|
8265
|
-
reliability_readiness_pct: result.metrics.reliability_readiness_pct ?? 0,
|
|
8266
|
-
scalability_readiness_pct: result.metrics.scalability_readiness_pct ?? 0
|
|
8267
|
-
},
|
|
8337
|
+
metrics: reportMetrics,
|
|
8268
8338
|
ecosystem: result.ecosystem,
|
|
8269
8339
|
binding_coverage_pct: result.bindingHealth.coverage_pct,
|
|
8270
8340
|
frameworks_loaded: result.frameworksLoaded,
|
|
8271
8341
|
sensitive_data_count: result.sensitiveDataCount,
|
|
8272
|
-
findings:
|
|
8342
|
+
findings: visibleFindings.map((f) => ({
|
|
8273
8343
|
title: f.title,
|
|
8274
8344
|
severity: f.severity,
|
|
8275
8345
|
category: f.category,
|
|
8276
8346
|
description: f.description
|
|
8277
8347
|
})),
|
|
8278
|
-
sca_summary: result.scaFindings ? {
|
|
8348
|
+
sca_summary: !hiddenSet.has("security") && result.scaFindings ? {
|
|
8279
8349
|
total: result.scaFindings.total,
|
|
8280
8350
|
critical: result.scaFindings.critical,
|
|
8281
8351
|
high: result.scaFindings.high
|
|
@@ -8287,7 +8357,7 @@ Why AI: ${idea.whyAI}`
|
|
|
8287
8357
|
console.error("[code_audit] Report persistence failed (non-fatal):", e);
|
|
8288
8358
|
}
|
|
8289
8359
|
return {
|
|
8290
|
-
content: [{ type: "text", text: formatAuditOutput(result, reportId, reportSiteUrl) }]
|
|
8360
|
+
content: [{ type: "text", text: formatAuditOutput(result, reportId, reportSiteUrl, hiddenAuditDimensions) }]
|
|
8291
8361
|
};
|
|
8292
8362
|
}
|
|
8293
8363
|
const authCtx = await resolveAuthContext(args.auth_token);
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
requirePremiumWithAutoAuth,
|
|
15
15
|
updateExplorationSession,
|
|
16
16
|
validateRequestSize
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-LI4AZPSJ.js";
|
|
18
18
|
|
|
19
19
|
// ../mcp/dist/mcp/src/exploration-server.js
|
|
20
20
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
requirePremiumWithAutoAuth,
|
|
14
14
|
validateAuth,
|
|
15
15
|
validateRequestSize
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-LI4AZPSJ.js";
|
|
17
17
|
|
|
18
18
|
// ../mcp/dist/mcp/src/integrations-server.js
|
|
19
19
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
mapErrorToMcp,
|
|
14
14
|
requirePremiumWithAutoAuth,
|
|
15
15
|
validateRequestSize
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-LI4AZPSJ.js";
|
|
17
17
|
|
|
18
18
|
// ../mcp/dist/mcp/src/output-server.js
|
|
19
19
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
requirePremiumWithAutoAuth,
|
|
22
22
|
validateAuth,
|
|
23
23
|
validateRequestSize
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-LI4AZPSJ.js";
|
|
25
25
|
|
|
26
26
|
// ../mcp/dist/mcp/src/tools-server.js
|
|
27
27
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
package/package.json
CHANGED