openkrak-mcp 1.1.2 → 1.1.4
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 +111 -39
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -242962,7 +242962,7 @@ async function runDeepStrike(store, opts) {
|
|
|
242962
242962
|
remote_url: null,
|
|
242963
242963
|
primary_language: detectPrimaryLanguage(fileIndexEntries.map((e) => e.path)),
|
|
242964
242964
|
languages: computeLanguageBreakdown(fileIndexEntries.map((e) => e.path)),
|
|
242965
|
-
framework: topology.framework
|
|
242965
|
+
framework: typeof topology.framework === "string" ? topology.framework : null,
|
|
242966
242966
|
total_files: relFiles.length,
|
|
242967
242967
|
total_loc: fileIndexEntries.reduce((s, e) => s + e.loc, 0),
|
|
242968
242968
|
git: { current_branch: null, last_commit_hash: null, last_commit_at: null, is_dirty: false }
|
|
@@ -245241,74 +245241,146 @@ async function handleAnalyzeRepo(args) {
|
|
|
245241
245241
|
});
|
|
245242
245242
|
} catch (e) {
|
|
245243
245243
|
return {
|
|
245244
|
-
content: [{ type: "text", text: `OpenKrak
|
|
245245
|
-
|
|
245244
|
+
content: [{ type: "text", text: `OpenKrak unavailable: ${e instanceof Error ? e.message : String(e)}
|
|
245245
|
+
Proceed with direct file analysis.` }],
|
|
245246
245246
|
isError: false
|
|
245247
245247
|
};
|
|
245248
245248
|
}
|
|
245249
245249
|
if (result.status === "failed") {
|
|
245250
245250
|
return {
|
|
245251
|
-
content: [{ type: "text", text: `
|
|
245252
|
-
|
|
245251
|
+
content: [{ type: "text", text: `Dorchester pipeline failed: ${result.error ?? "unknown"}
|
|
245252
|
+
Proceed without brief.` }],
|
|
245253
245253
|
isError: false
|
|
245254
245254
|
};
|
|
245255
245255
|
}
|
|
245256
245256
|
const m = result.mahadata;
|
|
245257
245257
|
const meta = m.meta;
|
|
245258
245258
|
const repo = m.repository;
|
|
245259
|
+
const topo = m.project_topology;
|
|
245260
|
+
const brief = m.execution_brief;
|
|
245261
|
+
const threat = m.threat_matrix;
|
|
245259
245262
|
const hotspots = m.hotspots ?? [];
|
|
245260
245263
|
const blastRadius = m.blast_radius ?? [];
|
|
245261
245264
|
const findings = m.findings ?? [];
|
|
245262
|
-
const brief = m.execution_brief;
|
|
245263
|
-
const threat = m.threat_matrix;
|
|
245264
|
-
const topology = m.project_topology;
|
|
245265
|
-
const totalFiles = Number(repo?.total_files ?? 0);
|
|
245266
|
-
const hotspotLimit = totalFiles < 50 ? 5 : totalFiles < 200 ? 8 : 12;
|
|
245267
245265
|
const ep = brief?.recommended_entry_points ?? [];
|
|
245268
245266
|
const ctx = brief?.critical_context ?? [];
|
|
245269
245267
|
const constraints = brief?.constraints ?? [];
|
|
245270
245268
|
const blockers = threat?.blockers ?? [];
|
|
245271
245269
|
const warnings = threat?.warnings ?? [];
|
|
245270
|
+
const modules = topo?.modules ?? [];
|
|
245271
|
+
const layers = topo?.layers ?? [];
|
|
245272
|
+
const langs = repo?.languages ?? [];
|
|
245273
|
+
const totalFiles = Number(repo?.total_files ?? 0);
|
|
245274
|
+
const totalLoc = Number(repo?.total_loc ?? 0);
|
|
245275
|
+
const critical = findings.filter((f) => f.severity === "critical");
|
|
245276
|
+
const high = findings.filter((f) => f.severity === "high");
|
|
245277
|
+
const medium = findings.filter((f) => f.severity === "medium");
|
|
245278
|
+
const deadCode = findings.filter((f) => f.type === "dead_code" && !f.noise_suppressed);
|
|
245279
|
+
const unresolved = findings.filter((f) => f.type === "missing_symbol" && !f.noise_suppressed);
|
|
245280
|
+
const cycles = findings.filter((f) => f.type === "circular_dependency");
|
|
245281
|
+
const riskScore = Number(threat?.overall_risk_score ?? 0);
|
|
245282
|
+
const riskBar = "\u2588".repeat(Math.round(riskScore * 20)) + "\u2591".repeat(20 - Math.round(riskScore * 20));
|
|
245272
245283
|
const lines = [
|
|
245273
|
-
`\u2554\u2550\u2550
|
|
245274
|
-
`\u2551
|
|
245275
|
-
`\
|
|
245276
|
-
`\u2551
|
|
245277
|
-
`\u2551
|
|
245278
|
-
`\
|
|
245284
|
+
`\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557`,
|
|
245285
|
+
`\u2551 D O R C H E S T E R E N G I N E \u2014 S C A N \u2551`,
|
|
245286
|
+
`\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563`,
|
|
245287
|
+
`\u2551 Repo ${(repo?.name ?? args.path).toString().padEnd(59)}\u2551`,
|
|
245288
|
+
`\u2551 Scan ID ${(meta?.scan_id ?? "?").slice(0, 8).padEnd(59)}\u2551`,
|
|
245289
|
+
`\u2551 Duration ${String(result.durationMs + "ms").padEnd(59)}\u2551`,
|
|
245290
|
+
`\u2560\u2550\u2550 REPOSITORY \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563`,
|
|
245291
|
+
`\u2551 Files : ${totalFiles}`,
|
|
245292
|
+
`\u2551 LOC : ${totalLoc.toLocaleString()}`,
|
|
245293
|
+
`\u2551 Language : ${repo?.primary_language ?? "?"}${langs.length > 1 ? " [" + langs.map((l) => `${l.name} ${l.percentage}%`).join(", ") + "]" : ""}`,
|
|
245294
|
+
`\u2551 Framework : ${repo?.framework ?? "none detected"}`,
|
|
245295
|
+
`\u2551 Topology : ${topo?.type ?? "?"} \u2014 ${modules.length} modules`,
|
|
245296
|
+
...modules.length > 0 ? modules.map((mod) => `\u2551 \u2022 ${mod.name.padEnd(22)} ${mod.responsibility}`) : [],
|
|
245297
|
+
...layers.length > 0 ? [
|
|
245298
|
+
`\u2551 Layers :`,
|
|
245299
|
+
...layers.map((l) => `\u2551 \u2022 ${l.name.padEnd(18)} ${l.paths.length} files`)
|
|
245300
|
+
] : [],
|
|
245301
|
+
`\u2560\u2550\u2550 OBJECTIVE \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563`,
|
|
245279
245302
|
`\u2551 ${brief?.objective ?? args.objective ?? "\u2014"}`,
|
|
245280
245303
|
`\u2551 ${brief?.repository_summary ?? ""}`,
|
|
245281
|
-
`\u2560\u2550\u2550 ENTRY POINTS \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\
|
|
245282
|
-
...ep.length > 0 ? ep.map((e) => `\u2551
|
|
245283
|
-
`\u2560\u2550\u2550 CRITICAL CONTEXT \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550`,
|
|
245284
|
-
...ctx.length > 0 ? ctx.map((c) => `\u2551
|
|
245285
|
-
|
|
245286
|
-
|
|
245304
|
+
`\u2560\u2550\u2550 ENTRY POINTS (${ep.length}) \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563`,
|
|
245305
|
+
...ep.length > 0 ? ep.map((e) => `\u2551 \u2192 ${e.path}${e.symbol ? `::${e.symbol}` : ""}${e.reason ? ` [${e.reason}]` : ""}`) : [`\u2551 none detected`],
|
|
245306
|
+
`\u2560\u2550\u2550 CRITICAL CONTEXT \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563`,
|
|
245307
|
+
...ctx.length > 0 ? ctx.map((c) => `\u2551 ${c.key}: ${c.value}`) : [`\u2551 \u2014`],
|
|
245308
|
+
...constraints.length > 0 ? [`\u2551 Constraints: ${constraints.join(" | ")}`] : [],
|
|
245309
|
+
`\u2560\u2550\u2550 HOTSPOT REGISTRY (${hotspots.length} files ranked) \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563`,
|
|
245310
|
+
...hotspots.map((h, i) => {
|
|
245287
245311
|
const hs = h;
|
|
245288
245312
|
const reasons = hs.reasons ?? [];
|
|
245289
|
-
const
|
|
245290
|
-
|
|
245291
|
-
|
|
245313
|
+
const score = Number(hs.score);
|
|
245314
|
+
const bar = "\u2588".repeat(Math.round(score * 10)) + "\u2591".repeat(10 - Math.round(score * 10));
|
|
245315
|
+
const level = String(hs.risk_level).toUpperCase();
|
|
245316
|
+
const freq = hs.change_frequency !== void 0 ? ` git-chg:${hs.change_frequency}` : "";
|
|
245317
|
+
return [
|
|
245318
|
+
`\u2551 ${String(i + 1).padStart(2)}. [${level.padEnd(8)}] ${hs.path}`,
|
|
245319
|
+
`\u2551 ${bar} ${score.toFixed(3)}${freq}`,
|
|
245320
|
+
`\u2551 flags: ${reasons.map((r) => r.type).join(", ")}`
|
|
245321
|
+
].join("\n");
|
|
245292
245322
|
}),
|
|
245293
|
-
`\u2560\u2550\u2550 BLAST RADIUS (top ${Math.min(
|
|
245294
|
-
...blastRadius.slice(0,
|
|
245323
|
+
`\u2560\u2550\u2550 BLAST RADIUS (top ${Math.min(blastRadius.length, 8)}) \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563`,
|
|
245324
|
+
...blastRadius.slice(0, 8).map((b) => {
|
|
245295
245325
|
const br = b;
|
|
245296
|
-
|
|
245297
|
-
|
|
245326
|
+
const affected = br.affected_files ?? [];
|
|
245327
|
+
const preview = affected.slice(0, 3).join(", ") + (affected.length > 3 ? ` +${affected.length - 3} more` : "");
|
|
245328
|
+
return [
|
|
245329
|
+
`\u2551 \u26A1 ${br.trigger_file}`,
|
|
245330
|
+
`\u2551 \u2192 ${br.total_affected_files} files ${br.total_affected_modules} modules risk:${Number(br.risk_score).toFixed(3)}`,
|
|
245331
|
+
...preview ? [`\u2551 cascades: ${preview}`] : []
|
|
245332
|
+
].join("\n");
|
|
245298
245333
|
}),
|
|
245299
|
-
`\u2560\u2550\u2550 THREAT MATRIX \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550`,
|
|
245300
|
-
`\u2551
|
|
245301
|
-
`\u2551
|
|
245302
|
-
`\u2551
|
|
245303
|
-
`\u2551
|
|
245304
|
-
`\
|
|
245305
|
-
|
|
245306
|
-
|
|
245334
|
+
`\u2560\u2550\u2550 THREAT MATRIX \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563`,
|
|
245335
|
+
`\u2551 Overall Risk : ${riskScore.toFixed(3)} [${riskBar}]`,
|
|
245336
|
+
`\u2551 Architecture : ${threat?.architecture_risk ?? "\u2014"}`,
|
|
245337
|
+
`\u2551 Reliability : ${threat?.reliability_risk ?? "\u2014"}`,
|
|
245338
|
+
`\u2551 Maintainability: ${threat?.maintainability_risk ?? "\u2014"}`,
|
|
245339
|
+
`\u2551 Summary : ${threat?.risk_summary ?? "\u2014"}`,
|
|
245340
|
+
...blockers.length > 0 ? [
|
|
245341
|
+
`\u2551 \u2500\u2500 Blockers (${blockers.length}) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`,
|
|
245342
|
+
...blockers.map((b) => `\u2551 \u2716 ${b.description ?? b.type ?? JSON.stringify(b)}`)
|
|
245343
|
+
] : [`\u2551 Blockers: none`],
|
|
245344
|
+
...warnings.length > 0 ? [
|
|
245345
|
+
`\u2551 \u2500\u2500 Warnings (${warnings.length}) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`,
|
|
245346
|
+
...warnings.map((w) => `\u2551 \u25B2 ${w.description ?? w.type ?? JSON.stringify(w)}`)
|
|
245347
|
+
] : [`\u2551 Warnings: none`],
|
|
245348
|
+
`\u2560\u2550\u2550 FINDINGS BREAKDOWN (${findings.length} total) \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563`,
|
|
245349
|
+
`\u2551 Critical : ${critical.length}`,
|
|
245350
|
+
`\u2551 High : ${high.length}`,
|
|
245351
|
+
`\u2551 Medium : ${medium.length}`,
|
|
245352
|
+
`\u2551 Cycles : ${cycles.length}${cycles.length > 0 ? " \u2190 fix before refactor" : ""}`,
|
|
245353
|
+
`\u2551 Unresolved imports : ${unresolved.length}${unresolved.length > 0 ? " \u2014 " + unresolved.slice(0, 5).map((f) => f.file ?? "?").join(", ") : ""}`,
|
|
245354
|
+
`\u2551 Dead code (genuine): ${deadCode.length}${deadCode.length > 0 ? " \u2014 " + deadCode.slice(0, 5).map((f) => f.symbol ?? f.file ?? "?").join(", ") : ""}`,
|
|
245355
|
+
...critical.length > 0 ? [
|
|
245356
|
+
`\u2551 \u2500\u2500 Critical findings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`,
|
|
245357
|
+
...critical.slice(0, 10).map((f) => {
|
|
245358
|
+
const fi = f;
|
|
245359
|
+
return `\u2551 \u2716 [${String(fi.type ?? "").padEnd(20)}] ${fi.file ?? "?"}:${fi.line_start ?? "?"} ${fi.message ?? ""}`;
|
|
245360
|
+
})
|
|
245361
|
+
] : [],
|
|
245362
|
+
...high.length > 0 ? [
|
|
245363
|
+
`\u2551 \u2500\u2500 High findings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`,
|
|
245364
|
+
...high.slice(0, 8).map((f) => {
|
|
245365
|
+
const fi = f;
|
|
245366
|
+
return `\u2551 \u25B2 [${String(fi.type ?? "").padEnd(20)}] ${fi.file ?? "?"}:${fi.line_start ?? "?"} ${fi.message ?? ""}`;
|
|
245367
|
+
})
|
|
245368
|
+
] : [],
|
|
245369
|
+
`\u2560\u2550\u2550 WHAT TO DO \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563`,
|
|
245370
|
+
...blockers.length > 0 ? [`\u2551 1. Resolve blockers before anything else.`] : [],
|
|
245371
|
+
...cycles.length > 0 ? [`\u2551 ${blockers.length > 0 ? "2" : "1"}. Break ${cycles.length} circular import cycle(s) \u2014 replace barrel imports with direct file paths.`] : [],
|
|
245372
|
+
...hotspots.filter((h) => h.risk_level === "critical").length > 0 ? [
|
|
245373
|
+
`\u2551 ${(blockers.length > 0 ? 1 : 0) + (cycles.length > 0 ? 1 : 0) + 1}. Refactor critical hotspots:`,
|
|
245374
|
+
...hotspots.filter((h) => h.risk_level === "critical").slice(0, 3).map(
|
|
245375
|
+
(h) => `\u2551 \u2192 ${h.path}`
|
|
245376
|
+
)
|
|
245377
|
+
] : [],
|
|
245378
|
+
`\u2551 Audit lib/utils or shared utilities with 5+ dependents before touching.`,
|
|
245379
|
+
`\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D`,
|
|
245307
245380
|
``,
|
|
245308
|
-
`Dorchester
|
|
245381
|
+
`Dorchester pre-mapped this repository in ${result.durationMs}ms. Proceed from this brief. Do not read source files unless specific line-level detail is required by the user.`
|
|
245309
245382
|
];
|
|
245310
245383
|
const output = lines.join("\n");
|
|
245311
|
-
const totalLoc = Number(repo?.total_loc ?? 0);
|
|
245312
245384
|
const saved = estimateTokensSaved(totalLoc, totalFiles, output);
|
|
245313
245385
|
trackTokens(saved, "analyze_repo");
|
|
245314
245386
|
return { content: [{ type: "text", text: output }] };
|