/** * Command: Inspect Chains (Current Section) */ import type { App, Editor } from "obsidian"; import { resolveSectionContext } from "../analysis/sectionContext"; import { inspectChains } from "../analysis/chainInspector"; import type { ChainRolesConfig } from "../dictionary/types"; export interface InspectChainsOptions { includeNoteLinks?: boolean; includeCandidates?: boolean; maxDepth?: number; direction?: "forward" | "backward" | "both"; } /** * Format report as pretty-printed string. */ function formatReport(report: Awaited>): string { const lines: string[] = []; lines.push("=== Chain Inspector Report ==="); lines.push(""); lines.push(`Context: ${report.context.file}`); if (report.context.heading) { lines.push(`Section: ${report.context.heading}`); } lines.push(`Zone: ${report.context.zoneKind}`); lines.push(""); lines.push("Settings:"); lines.push(` - Include Note Links: ${report.settings.includeNoteLinks}`); lines.push(` - Include Candidates: ${report.settings.includeCandidates}`); lines.push(` - Max Depth: ${report.settings.maxDepth}`); lines.push(` - Direction: ${report.settings.direction}`); lines.push(""); lines.push(`Neighbors:`); lines.push(` Incoming: ${report.neighbors.incoming.length}`); for (const edge of report.neighbors.incoming.slice(0, 5)) { const targetStr = edge.target.heading ? `${edge.target.file}#${edge.target.heading}` : edge.target.file; lines.push(` - ${edge.rawEdgeType} -> ${targetStr} [${edge.scope}]`); } if (report.neighbors.incoming.length > 5) { lines.push(` ... and ${report.neighbors.incoming.length - 5} more`); } lines.push(` Outgoing: ${report.neighbors.outgoing.length}`); for (const edge of report.neighbors.outgoing.slice(0, 5)) { const targetStr = edge.target.heading ? `${edge.target.file}#${edge.target.heading}` : edge.target.file; lines.push(` - ${edge.rawEdgeType} -> ${targetStr} [${edge.scope}]`); } if (report.neighbors.outgoing.length > 5) { lines.push(` ... and ${report.neighbors.outgoing.length - 5} more`); } lines.push(""); lines.push(`Paths:`); lines.push(` Forward: ${report.paths.forward.length}`); for (const path of report.paths.forward.slice(0, 3)) { const pathStr = path.nodes .map((n) => (n.heading ? `${n.file}#${n.heading}` : n.file)) .join(" -> "); lines.push(` - ${pathStr} (${path.edges.length} edges)`); } if (report.paths.forward.length > 3) { lines.push(` ... and ${report.paths.forward.length - 3} more`); } lines.push(` Backward: ${report.paths.backward.length}`); for (const path of report.paths.backward.slice(0, 3)) { const pathStr = path.nodes .map((n) => (n.heading ? `${n.file}#${n.heading}` : n.file)) .join(" -> "); lines.push(` - ${pathStr} (${path.edges.length} edges)`); } if (report.paths.backward.length > 3) { lines.push(` ... and ${report.paths.backward.length - 3} more`); } lines.push(""); lines.push(`Gap Heuristics (Findings): ${report.findings.length}`); if (report.findings.length === 0) { lines.push(` ✓ No issues detected`); } else { for (const finding of report.findings) { const severityIcon = finding.severity === "error" ? "❌" : finding.severity === "warn" ? "⚠️" : "ℹ️"; lines.push( ` ${severityIcon} [${finding.severity.toUpperCase()}] ${finding.code}: ${finding.message}` ); } } return lines.join("\n"); } /** * Execute inspect chains command. */ export async function executeInspectChains( app: App, editor: Editor, filePath: string, chainRoles: ChainRolesConfig | null, options: InspectChainsOptions = {} ): Promise { // Resolve section context const context = resolveSectionContext(editor, filePath); // Build options with defaults const inspectorOptions = { includeNoteLinks: options.includeNoteLinks ?? true, includeCandidates: options.includeCandidates ?? false, maxDepth: options.maxDepth ?? 3, direction: options.direction ?? "both", }; // Inspect chains const report = await inspectChains(app, context, inspectorOptions, chainRoles); // Log report as JSON console.log("=== Chain Inspector Report (JSON) ==="); console.log(JSON.stringify(report, null, 2)); // Log pretty-printed summary console.log("\n=== Chain Inspector Report (Summary) ==="); console.log(formatReport(report)); }