kirograph 0.27.1 → 0.28.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/README.md +35 -2
- package/dist/bin/commands/annotations.js +56 -0
- package/dist/bin/commands/annotations.js.map +7 -0
- package/dist/bin/commands/ast-rewrite.js +55 -0
- package/dist/bin/commands/ast-rewrite.js.map +7 -0
- package/dist/bin/commands/bench.js +103 -0
- package/dist/bin/commands/bench.js.map +7 -0
- package/dist/bin/commands/branch.js +133 -0
- package/dist/bin/commands/branch.js.map +7 -0
- package/dist/bin/commands/callees.js +76 -0
- package/dist/bin/commands/callees.js.map +7 -0
- package/dist/bin/commands/callers.js +76 -0
- package/dist/bin/commands/callers.js.map +7 -0
- package/dist/bin/commands/changelog.js +55 -0
- package/dist/bin/commands/changelog.js.map +7 -0
- package/dist/bin/commands/circular-deps.js +68 -0
- package/dist/bin/commands/circular-deps.js.map +7 -0
- package/dist/bin/commands/commit-context.js +55 -0
- package/dist/bin/commands/commit-context.js.map +7 -0
- package/dist/bin/commands/complexity.js +60 -0
- package/dist/bin/commands/complexity.js.map +7 -0
- package/dist/bin/commands/cost.js +146 -0
- package/dist/bin/commands/cost.js.map +7 -0
- package/dist/bin/commands/dependency-depth.js +55 -0
- package/dist/bin/commands/dependency-depth.js.map +7 -0
- package/dist/bin/commands/diff-context.js +55 -0
- package/dist/bin/commands/diff-context.js.map +7 -0
- package/dist/bin/commands/distribution.js +56 -0
- package/dist/bin/commands/distribution.js.map +7 -0
- package/dist/bin/commands/doc-coverage.js +56 -0
- package/dist/bin/commands/doc-coverage.js.map +7 -0
- package/dist/bin/commands/doctor.js +202 -0
- package/dist/bin/commands/doctor.js.map +7 -0
- package/dist/bin/commands/dsm.js +56 -0
- package/dist/bin/commands/dsm.js.map +7 -0
- package/dist/bin/commands/gini.js +55 -0
- package/dist/bin/commands/gini.js.map +7 -0
- package/dist/bin/commands/god-class.js +56 -0
- package/dist/bin/commands/god-class.js.map +7 -0
- package/dist/bin/commands/health.js +55 -0
- package/dist/bin/commands/health.js.map +7 -0
- package/dist/bin/commands/help.js +224 -45
- package/dist/bin/commands/help.js.map +2 -2
- package/dist/bin/commands/impact.js +76 -0
- package/dist/bin/commands/impact.js.map +7 -0
- package/dist/bin/commands/inheritance-depth.js +56 -0
- package/dist/bin/commands/inheritance-depth.js.map +7 -0
- package/dist/bin/commands/insert-at.js +55 -0
- package/dist/bin/commands/insert-at.js.map +7 -0
- package/dist/bin/commands/largest.js +56 -0
- package/dist/bin/commands/largest.js.map +7 -0
- package/dist/bin/commands/manifest.js +158 -0
- package/dist/bin/commands/manifest.js.map +7 -0
- package/dist/bin/commands/module-api.js +57 -0
- package/dist/bin/commands/module-api.js.map +7 -0
- package/dist/bin/commands/monitor.js +91 -0
- package/dist/bin/commands/monitor.js.map +7 -0
- package/dist/bin/commands/multi-replace.js +66 -0
- package/dist/bin/commands/multi-replace.js.map +7 -0
- package/dist/bin/commands/pr-context.js +55 -0
- package/dist/bin/commands/pr-context.js.map +7 -0
- package/dist/bin/commands/query.js +19 -1
- package/dist/bin/commands/query.js.map +3 -3
- package/dist/bin/commands/rank.js +56 -0
- package/dist/bin/commands/rank.js.map +7 -0
- package/dist/bin/commands/read.js +1 -1
- package/dist/bin/commands/read.js.map +2 -2
- package/dist/bin/commands/recursion.js +56 -0
- package/dist/bin/commands/recursion.js.map +7 -0
- package/dist/bin/commands/rename-preview.js +56 -0
- package/dist/bin/commands/rename-preview.js.map +7 -0
- package/dist/bin/commands/session.js +60 -0
- package/dist/bin/commands/session.js.map +7 -0
- package/dist/bin/commands/simplify-scan.js +56 -0
- package/dist/bin/commands/simplify-scan.js.map +7 -0
- package/dist/bin/commands/str-replace.js +55 -0
- package/dist/bin/commands/str-replace.js.map +7 -0
- package/dist/bin/commands/test-coverage.js +59 -0
- package/dist/bin/commands/test-coverage.js.map +7 -0
- package/dist/bin/commands/test-map.js +56 -0
- package/dist/bin/commands/test-map.js.map +7 -0
- package/dist/bin/commands/test-risk.js +59 -0
- package/dist/bin/commands/test-risk.js.map +7 -0
- package/dist/bin/commands/type-hierarchy.js +76 -0
- package/dist/bin/commands/type-hierarchy.js.map +7 -0
- package/dist/bin/commands/unused-imports.js +55 -0
- package/dist/bin/commands/unused-imports.js.map +7 -0
- package/dist/bin/commands/upgrade.js +78 -0
- package/dist/bin/commands/upgrade.js.map +7 -0
- package/dist/bin/installer/common.js +19 -9
- package/dist/bin/installer/common.js.map +2 -2
- package/dist/bin/installer/config-prompt.js +147 -12
- package/dist/bin/installer/config-prompt.js.map +3 -3
- package/dist/bin/installer/index.js +62 -6
- package/dist/bin/installer/index.js.map +2 -2
- package/dist/bin/installer/instructions.js +14 -25
- package/dist/bin/installer/instructions.js.map +2 -2
- package/dist/bin/installer/mcp.js.map +2 -2
- package/dist/bin/installer/steering.js +569 -100
- package/dist/bin/installer/steering.js.map +2 -2
- package/dist/bin/installer/targets/aider.js +3 -3
- package/dist/bin/installer/targets/aider.js.map +2 -2
- package/dist/bin/installer/targets/amp.js +3 -3
- package/dist/bin/installer/targets/amp.js.map +2 -2
- package/dist/bin/installer/targets/antigravity.js +4 -4
- package/dist/bin/installer/targets/antigravity.js.map +2 -2
- package/dist/bin/installer/targets/augment.js +3 -3
- package/dist/bin/installer/targets/augment.js.map +2 -2
- package/dist/bin/installer/targets/claude.js +3 -3
- package/dist/bin/installer/targets/claude.js.map +2 -2
- package/dist/bin/installer/targets/cline.js +4 -4
- package/dist/bin/installer/targets/cline.js.map +2 -2
- package/dist/bin/installer/targets/codex.js +4 -4
- package/dist/bin/installer/targets/codex.js.map +2 -2
- package/dist/bin/installer/targets/continue.js +4 -4
- package/dist/bin/installer/targets/continue.js.map +2 -2
- package/dist/bin/installer/targets/copilot-cli.js +4 -4
- package/dist/bin/installer/targets/copilot-cli.js.map +2 -2
- package/dist/bin/installer/targets/copilot.js +4 -4
- package/dist/bin/installer/targets/copilot.js.map +2 -2
- package/dist/bin/installer/targets/cursor.js +5 -5
- package/dist/bin/installer/targets/cursor.js.map +2 -2
- package/dist/bin/installer/targets/devin.js +4 -4
- package/dist/bin/installer/targets/devin.js.map +2 -2
- package/dist/bin/installer/targets/gemini-cli.js +4 -4
- package/dist/bin/installer/targets/gemini-cli.js.map +2 -2
- package/dist/bin/installer/targets/generic.js +2 -2
- package/dist/bin/installer/targets/generic.js.map +2 -2
- package/dist/bin/installer/targets/goose.js +3 -4
- package/dist/bin/installer/targets/goose.js.map +3 -3
- package/dist/bin/installer/targets/index.js.map +1 -1
- package/dist/bin/installer/targets/junie.js +4 -4
- package/dist/bin/installer/targets/junie.js.map +2 -2
- package/dist/bin/installer/targets/kilo.js +4 -4
- package/dist/bin/installer/targets/kilo.js.map +2 -2
- package/dist/bin/installer/targets/kiro.js +27 -3
- package/dist/bin/installer/targets/kiro.js.map +2 -2
- package/dist/bin/installer/targets/opencode.js +3 -3
- package/dist/bin/installer/targets/opencode.js.map +2 -2
- package/dist/bin/installer/targets/openhands.js +3 -3
- package/dist/bin/installer/targets/openhands.js.map +2 -2
- package/dist/bin/installer/targets/qoder.js +2 -2
- package/dist/bin/installer/targets/qoder.js.map +2 -2
- package/dist/bin/installer/targets/qwen.js +2 -2
- package/dist/bin/installer/targets/qwen.js.map +2 -2
- package/dist/bin/installer/targets/replit.js +3 -3
- package/dist/bin/installer/targets/replit.js.map +2 -2
- package/dist/bin/installer/targets/roo.js +4 -4
- package/dist/bin/installer/targets/roo.js.map +2 -2
- package/dist/bin/installer/targets/tabnine.js +3 -3
- package/dist/bin/installer/targets/tabnine.js.map +2 -2
- package/dist/bin/installer/targets/trae.js +3 -3
- package/dist/bin/installer/targets/trae.js.map +2 -2
- package/dist/bin/installer/targets/warp.js +4 -4
- package/dist/bin/installer/targets/warp.js.map +2 -2
- package/dist/bin/installer/targets/windsurf.js +4 -4
- package/dist/bin/installer/targets/windsurf.js.map +2 -2
- package/dist/bin/kirograph.js +83 -1
- package/dist/bin/kirograph.js.map +3 -3
- package/dist/config.js +30 -8
- package/dist/config.js.map +2 -2
- package/dist/core/branch-manager.js +111 -0
- package/dist/core/branch-manager.js.map +7 -0
- package/dist/core/pipeline.js +3 -3
- package/dist/core/pipeline.js.map +2 -2
- package/dist/data/pixelrag-bridge.js +93 -0
- package/dist/data/pixelrag-bridge.js.map +7 -0
- package/dist/data/pixelrag-manager.js +416 -0
- package/dist/data/pixelrag-manager.js.map +7 -0
- package/dist/db/database.js +34 -7
- package/dist/db/database.js.map +2 -2
- package/dist/db/schema.sql +7 -1
- package/dist/extraction/complexity.js +116 -0
- package/dist/extraction/complexity.js.map +7 -0
- package/dist/extraction/extractor.js +52 -1
- package/dist/extraction/extractor.js.map +2 -2
- package/dist/graph/git-context.js +229 -0
- package/dist/graph/git-context.js.map +7 -0
- package/dist/index.js +4 -2
- package/dist/index.js.map +2 -2
- package/dist/mcp/cache.js +1 -1
- package/dist/mcp/cache.js.map +2 -2
- package/dist/mcp/handler.js +446 -0
- package/dist/mcp/handler.js.map +7 -0
- package/dist/mcp/handlers/architecture.js +297 -0
- package/dist/mcp/handlers/architecture.js.map +7 -0
- package/dist/mcp/handlers/branch.js +175 -0
- package/dist/mcp/handlers/branch.js.map +7 -0
- package/dist/mcp/handlers/code-health.js +563 -0
- package/dist/mcp/handlers/code-health.js.map +7 -0
- package/dist/mcp/handlers/complexity.js +267 -0
- package/dist/mcp/handlers/complexity.js.map +7 -0
- package/dist/mcp/handlers/core.js +611 -0
- package/dist/mcp/handlers/core.js.map +7 -0
- package/dist/mcp/handlers/data.js +337 -0
- package/dist/mcp/handlers/data.js.map +7 -0
- package/dist/mcp/handlers/docs.js +159 -0
- package/dist/mcp/handlers/docs.js.map +7 -0
- package/dist/mcp/handlers/edit-primitives.js +200 -0
- package/dist/mcp/handlers/edit-primitives.js.map +7 -0
- package/dist/mcp/handlers/git-context.js +286 -0
- package/dist/mcp/handlers/git-context.js.map +7 -0
- package/dist/mcp/handlers/memory.js +363 -0
- package/dist/mcp/handlers/memory.js.map +7 -0
- package/dist/mcp/handlers/patterns.js +310 -0
- package/dist/mcp/handlers/patterns.js.map +7 -0
- package/dist/mcp/handlers/security.js +699 -0
- package/dist/mcp/handlers/security.js.map +7 -0
- package/dist/mcp/handlers/utils.js +97 -0
- package/dist/mcp/handlers/utils.js.map +7 -0
- package/dist/mcp/handlers/watchmen.js +104 -0
- package/dist/mcp/handlers/watchmen.js.map +7 -0
- package/dist/mcp/handlers/wiki.js +242 -0
- package/dist/mcp/handlers/wiki.js.map +7 -0
- package/dist/mcp/server.js +72 -3
- package/dist/mcp/server.js.map +2 -2
- package/dist/mcp/tool-names.js +136 -10
- package/dist/mcp/tool-names.js.map +2 -2
- package/dist/mcp/tools.js +846 -3019
- package/dist/mcp/tools.js.map +3 -3
- package/dist/types.js.map +2 -2
- package/package.json +36 -10
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/handlers/core.ts"],
|
|
4
|
+
"sourcesContent": ["import KiroGraph from '../../index';\nimport type { NodeKind } from '../../types';\nimport { estimateTokens } from '../../compression/index';\nimport { clampLimit, mapKind, formatAge, estimateFileTokens } from './utils';\n\nexport async function handleCore(toolName: string, args: Record<string, unknown>, cg: KiroGraph): Promise<string> {\n switch (toolName) {\n case 'kirograph_search': {\n const limit = clampLimit(args.limit as number | undefined, 10);\n const mode = (args.mode as string | undefined) ?? 'name';\n let nodes: Array<{ kind: string; name: string; filePath: string; startLine: number; qualifiedName: string }>;\n if (mode === 'similar') {\n nodes = cg.getDatabase().searchNodesByName(\n args.query as string,\n { kinds: args.kind ? [args.kind as NodeKind] : undefined, limit }\n );\n } else {\n nodes = cg.searchNodes(args.query as string, args.kind as NodeKind | undefined, limit).map(r => r.node);\n }\n if (nodes.length === 0) return `No symbols found matching \"${args.query}\".`;\n return nodes.map(n =>\n `${mapKind(n.kind as NodeKind)} ${n.name}\\n File: ${n.filePath}:${n.startLine}\\n Qualified: ${n.qualifiedName}`\n ).join('\\n\\n');\n }\n\n case 'kirograph_context': {\n const detail = (args.detail as string) ?? ((args.includeCode === false) ? 'summary' : 'full');\n const ctx = await cg.buildContext(args.task as string, {\n maxNodes: (args.maxNodes as number) ?? 20,\n includeCode: detail === 'full',\n });\n const lines: string[] = [ctx.summary, ''];\n if (ctx.entryPoints.length === 0) {\n lines.push('No matching symbols found. If this is a new feature, consider using kirograph_files to explore the codebase structure.');\n } else {\n lines.push('## Entry Points');\n for (const n of ctx.entryPoints) {\n lines.push(`- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`);\n if (detail === 'full' && ctx.codeSnippets.has(n.id)) {\n lines.push('```', ctx.codeSnippets.get(n.id)!, '```');\n } else if (detail === 'signatures') {\n if ((n as any).signature) lines.push(` Signature: ${(n as any).signature}`);\n if ((n as any).docstring) lines.push(` Docs: ${(n as any).docstring}`);\n }\n }\n if (ctx.relatedNodes.length > 0) {\n lines.push('', '## Related Symbols');\n for (const n of ctx.relatedNodes.slice(0, 10)) {\n lines.push(`- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`);\n }\n }\n }\n\n // Memory integration: surface relevant observations if memory is enabled\n try {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (config.enableMemory) {\n const { MemoryManager } = await Promise.resolve().then(() => require('../../memory/index.js'));\n const db = cg.getDatabase();\n db.applyMemorySchema();\n const mem = new MemoryManager(config, db.getRawDb());\n mem.initialize();\n\n // Collect qualified names from entry points and related nodes\n const qualifiedNames = [\n ...ctx.entryPoints.map((n: any) => n.qualifiedName),\n ...ctx.relatedNodes.slice(0, 5).map((n: any) => n.qualifiedName),\n ].filter(Boolean);\n\n const contextLimit = config.memoryContextLimit ?? 3;\n const contextThreshold = config.memoryContextThreshold ?? 0.3;\n\n // Try linked observations first, fall back to search\n let memResults = mem.getLinkedObservations(qualifiedNames, contextLimit, contextThreshold);\n if (memResults.length === 0) {\n // Fall back to searching by task description\n memResults = (await mem.search(args.task as string, { limit: contextLimit }))\n .filter(r => r.score >= contextThreshold);\n }\n\n if (memResults.length > 0) {\n lines.push('', '## Related Memory');\n for (const r of memResults.slice(0, contextLimit)) {\n lines.push(`- [${r.observation.kind}] ${r.observation.content}`);\n }\n }\n }\n } catch { /* memory is non-critical \u2014 don't fail context on memory errors */ }\n\n // Docs integration: surface relevant doc sections if enabled and docsContextLimit > 0\n try {\n const projectRoot2 = cg.getProjectRoot();\n const config2 = await (await Promise.resolve().then(() => require('../../config.js'))).loadConfig(projectRoot2);\n if (config2.enableDocs && config2.docsContextLimit > 0) {\n const db2 = cg.getDatabase();\n db2.applyDocsSchema();\n const { DocsQueries } = await Promise.resolve().then(() => require('../../docs/queries.js'));\n const docsQueries = new DocsQueries(db2.getRawDb(), projectRoot2);\n\n // Collect qualified names from entry points\n const qNames = ctx.entryPoints.map((n: any) => n.qualifiedName).filter(Boolean);\n\n if (qNames.length > 0) {\n // Find doc sections that reference these symbols\n const docRefs = docsQueries.getRefs({ qualifiedName: qNames[0] });\n const additionalRefs = qNames.slice(1, 5).flatMap(qn => docsQueries.getRefs({ qualifiedName: qn }));\n const allDocRefs = [...docRefs, ...additionalRefs];\n\n // Deduplicate by section ID and take top N\n const seenSections = new Set<string>();\n const uniqueRefs = allDocRefs.filter(r => {\n if (seenSections.has(r.sectionId)) return false;\n seenSections.add(r.sectionId);\n return r.confidence >= config2.docsContextThreshold;\n }).slice(0, config2.docsContextLimit);\n\n if (uniqueRefs.length > 0) {\n lines.push('', '## Related Documentation');\n for (const ref of uniqueRefs) {\n const section = docsQueries.getSection(ref.sectionId);\n if (section) {\n const summary = section.section.summary ?? section.section.title;\n lines.push(`- [${ref.refType}] ${summary} \u2014 ${section.section.filePath} (ID: ${ref.sectionId})`);\n }\n }\n }\n }\n }\n } catch { /* docs is non-critical */ }\n\n // Data integration: surface relevant dataset schemas if enabled and dataContextLimit > 0\n try {\n const projectRoot3 = cg.getProjectRoot();\n const config3 = await (await Promise.resolve().then(() => require('../../config.js'))).loadConfig(projectRoot3);\n if (config3.enableData && config3.dataContextLimit > 0) {\n const db3 = cg.getDatabase();\n db3.applyDataSchema();\n\n // Find datasets referenced by the entry point files\n const entryFiles = ctx.entryPoints.map((n: any) => n.filePath).filter(Boolean);\n if (entryFiles.length > 0) {\n const placeholders = entryFiles.map(() => '?').join(', ');\n const dataRefs = db3.getRawDb().all(\n `SELECT DISTINCT d.id, d.file_path, d.row_count, d.column_count\n FROM data_code_refs r JOIN data_datasets d ON r.dataset_id = d.id\n WHERE r.qualified_name IN (${placeholders})`,\n entryFiles,\n ) as any[];\n\n if (dataRefs.length > 0) {\n const { DataQueries } = await Promise.resolve().then(() => require('../../data/queries.js'));\n const dq = new DataQueries(db3.getRawDb());\n const limit = config3.dataContextLimit;\n\n lines.push('', '## Related Data');\n for (const ref of dataRefs.slice(0, limit)) {\n const info = dq.describeDataset(ref.id);\n if (info) {\n const colSummary = info.columns.map(c => `${c.name}:${c.inferredType}`).join(', ');\n lines.push(`- **${ref.id}** (${ref.file_path}) \u2014 ${ref.row_count} rows, ${ref.column_count} cols`);\n lines.push(` Schema: ${colSummary}`);\n }\n }\n }\n }\n }\n } catch { /* data is non-critical */ }\n\n // Security integration: surface vulnerability warnings if enableSecurity is true\n try {\n const projectRootSec = cg.getProjectRoot();\n const configSec = await (await Promise.resolve().then(() => require('../../config.js'))).loadConfig(projectRootSec);\n if (configSec.enableSecurity) {\n const dbSec = cg.getDatabase();\n dbSec.applySecuritySchema();\n const rawDbSec = dbSec.getRawDb();\n\n // Collect node IDs from entry points and related nodes\n const contextNodeIds = [\n ...ctx.entryPoints.map((n: any) => n.id),\n ...ctx.relatedNodes.map((n: any) => n.id),\n ].filter(Boolean);\n\n if (contextNodeIds.length > 0) {\n const { getSecurityWarningsForNodes, formatSecurityWarnings } = await Promise.resolve().then(() => require('../../security/context-warnings.js'));\n const warnings = getSecurityWarningsForNodes(rawDbSec, contextNodeIds);\n\n if (warnings.length > 0) {\n // Build a name map for entry points\n const nodeNames = new Map<string, string>();\n for (const n of ctx.entryPoints) {\n nodeNames.set(n.id, n.name);\n }\n for (const n of ctx.relatedNodes) {\n nodeNames.set(n.id, n.name);\n }\n\n const secSection = formatSecurityWarnings(warnings, nodeNames);\n if (secSection) {\n lines.push(secSection);\n }\n }\n }\n }\n } catch { /* security is non-critical */ }\n\n // Pattern matches warning (when enablePatterns: true and pattern_matches table exists)\n try {\n const projectRootPat = cg.getProjectRoot();\n const configPat = await (await Promise.resolve().then(() => require('../../config.js'))).loadConfig(projectRootPat);\n if ((configPat as any).enablePatterns) {\n const dbPat = cg.getDatabase();\n dbPat.applyPatternsSchema();\n const rawDbPat = dbPat.getRawDb();\n const tableExists = rawDbPat.get(\"SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'\");\n if (tableExists) {\n // Collect file paths from context nodes\n const contextFiles = [\n ...ctx.entryPoints.map((n: any) => n.filePath),\n ...ctx.relatedNodes.map((n: any) => n.filePath),\n ].filter(Boolean) as string[];\n const uniqueContextFiles = [...new Set(contextFiles)];\n\n if (uniqueContextFiles.length > 0) {\n const placeholders = uniqueContextFiles.map(() => '?').join(',');\n const patternRows: Array<{ file_path: string; pattern_id: string; severity: string; owasp_category: string; line: number }> =\n rawDbPat.all(\n `SELECT file_path, pattern_id, severity, owasp_category, line FROM pattern_matches WHERE file_path IN (${placeholders}) ORDER BY severity DESC LIMIT 5`,\n uniqueContextFiles\n );\n if (patternRows.length > 0) {\n const patternWarnings = patternRows.map(p =>\n `- **${p.pattern_id}** [${p.severity.toUpperCase()}/${p.owasp_category}]: ${p.file_path}:${p.line}`\n ).join('\\n');\n lines.push('', '## \u26A0 Pattern Findings', '', patternWarnings);\n if (patternRows.length === 5) lines.push('', 'More findings \u2014 run `kirograph pattern --list` to see all rules.');\n }\n }\n }\n }\n } catch { /* non-critical */ }\n\n // Context savings estimation\n const graphTokens = lines.join('\\n').length / 4; // rough token estimate\n const uniqueFiles = new Set([\n ...ctx.entryPoints.map((n: any) => n.filePath),\n ...ctx.relatedNodes.map((n: any) => n.filePath),\n ]);\n if (uniqueFiles.size > 0) {\n const naiveTokens = estimateFileTokens(cg.getProjectRoot(), [...uniqueFiles]);\n if (naiveTokens > 0) {\n const savingsPct = Math.round((1 - graphTokens / naiveTokens) * 100);\n if (savingsPct > 0) {\n lines.push('', `---`, `Context savings: ~${Math.round(graphTokens)} tokens (graph) vs ~${naiveTokens} tokens (full files) \u2014 ${savingsPct}% reduction`);\n }\n }\n }\n\n return lines.join('\\n');\n }\n\n case 'kirograph_callers': {\n const limit = clampLimit(args.limit as number | undefined, 20);\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const callers = await cg.getCallers(node.id, limit);\n if (callers.length === 0) return `No callers found for \\`${node.name}\\`.`;\n return `Callers of \\`${node.name}\\`:\\n` + callers.map(n =>\n `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`\n ).join('\\n');\n }\n\n case 'kirograph_callees': {\n const limit = clampLimit(args.limit as number | undefined, 20);\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const callees = await cg.getCallees(node.id, limit);\n if (callees.length === 0) return `\\`${node.name}\\` doesn't call any indexed symbols.`;\n return `\\`${node.name}\\` calls:\\n` + callees.map(n =>\n `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`\n ).join('\\n');\n }\n\n case 'kirograph_impact': {\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const affected = await cg.getImpactRadius(node.id, (args.depth as number) ?? 2);\n if (affected.length === 0) return `No dependents found for \\`${node.name}\\`.`;\n\n let output = `Changing \\`${node.name}\\` may affect ${affected.length} symbol(s):\\n` +\n affected.map(n => `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`).join('\\n');\n\n // Memory integration: surface observations linked to the target symbol\n try {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (config.enableMemory) {\n const { MemoryManager } = await Promise.resolve().then(() => require('../../memory/index.js'));\n const db = cg.getDatabase();\n db.applyMemorySchema();\n const mem = new MemoryManager(config, db.getRawDb());\n mem.initialize();\n\n const contextLimit = config.memoryContextLimit ?? 3;\n const contextThreshold = config.memoryContextThreshold ?? 0.3;\n const memResults = mem.getLinkedObservations(\n [node.qualifiedName],\n contextLimit,\n contextThreshold\n );\n\n if (memResults.length > 0) {\n output += '\\n\\nRelated Memory:';\n for (const r of memResults) {\n const age = formatAge(r.observation.createdAt);\n output += `\\n- [${r.observation.kind}] ${r.observation.content} (${age})`;\n }\n }\n }\n } catch { /* memory is non-critical */ }\n\n // Check if symbol has pattern matches\n try {\n const rawDbImp = cg.getDatabase().getRawDb();\n const tableExistsImp = rawDbImp.get(\"SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'\");\n if (tableExistsImp) {\n const symNode = rawDbImp.get('SELECT id FROM nodes WHERE name = ? LIMIT 1', [args.symbol]);\n if (symNode) {\n const patternMatches = rawDbImp.all(\n 'SELECT pattern_id, severity, line FROM pattern_matches WHERE symbol_node_id = ?',\n [(symNode as { id: string }).id]\n ) as Array<{ pattern_id: string; severity: string; line: number }>;\n if (patternMatches.length > 0) {\n output += '\\n\\n\u26A0 This symbol has pattern matches:';\n for (const pm of patternMatches) {\n output += `\\n [${pm.severity.toUpperCase()}] ${pm.pattern_id} at line ${pm.line}`;\n }\n }\n }\n }\n } catch { /* non-critical */ }\n\n return output;\n }\n\n case 'kirograph_node': {\n let node: import('../../types').Node | null = null;\n if (args.qualified) {\n const row = cg.getDatabase().getRawDb().get(\n `SELECT * FROM nodes WHERE qualified_name = ? LIMIT 1`,\n [args.symbol as string]\n );\n if (row) {\n // Map DB row to Node shape (fields used below)\n node = {\n id: row.id, kind: row.kind, name: row.name, qualifiedName: row.qualified_name,\n filePath: row.file_path, language: row.language,\n startLine: row.start_line, endLine: row.end_line,\n startColumn: row.start_column, endColumn: row.end_column,\n docstring: row.docstring ?? undefined, signature: row.signature ?? undefined,\n visibility: row.visibility ?? undefined,\n isExported: row.is_exported === 1, isAsync: row.is_async === 1,\n isStatic: row.is_static === 1, isAbstract: row.is_abstract === 1,\n } as import('../../types').Node;\n }\n } else {\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length > 0) node = results[0].node;\n }\n if (!node) return `Symbol \"${args.symbol}\" not found in index.`;\n const nodeDetail = (args.detail as string) ?? (args.includeCode ? 'full' : 'summary');\n const lines = [\n `${mapKind(node.kind)} \\`${node.name}\\``,\n `File: ${node.filePath}:${node.startLine}-${node.endLine}`,\n `Qualified: ${node.qualifiedName}`,\n ];\n if (nodeDetail === 'signatures' || nodeDetail === 'full') {\n if (node.signature) lines.push(`Signature: ${node.signature}`);\n if (node.docstring) lines.push(`Docs: ${node.docstring}`);\n }\n if (nodeDetail === 'full') {\n const src = cg.getNodeSource(node);\n if (src) lines.push('', '```', src, '```');\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_status': {\n const stats = await cg.getStats();\n const langLine = Object.entries(stats.filesByLanguage)\n .sort((a, b) => b[1] - a[1])\n .map(([k, v]) => `${k}=${v}`)\n .join(', ');\n const dbMb = (stats.dbSizeBytes / 1024 / 1024).toFixed(2);\n const semanticLines = stats.embeddingsEnabled\n ? [\n ` Semantic search: enabled`,\n ` Semantic model: ${stats.embeddingModel}`,\n ` Semantic engine: ${\n stats.semanticEngine === 'turboquant' ? `turboquant (${stats.vecIndexCount} entries \u00B7 ANN)` :\n stats.semanticEngine === 'turbovec' ? `turbovec (${stats.vecIndexCount} entries \u00B7 ${stats.turbovecBits ?? 4} bits \u00B7 Rust/SIMD)` :\n stats.semanticEngine === 'sqlite-vec' ? `sqlite-vec (${stats.vecIndexCount} entries in ANN index)` :\n stats.semanticEngine === 'orama' ? `orama hybrid (${stats.vecIndexCount} docs in index)` :\n stats.semanticEngine === 'pglite' ? `pglite+pgvector (${stats.vecIndexCount} rows in DB)` :\n stats.semanticEngine === 'lancedb' ? `lancedb (${stats.vecIndexCount} entries in ANN index)` :\n stats.semanticEngine === 'qdrant' ? `qdrant (${stats.vecIndexCount} points in collection)` :\n stats.semanticEngine === 'typesense' ? `typesense (${stats.vecIndexCount} documents in collection)` :\n 'in-process cosine'\n }`,\n ` Embeddings: ${stats.embeddingCount} / ${stats.embeddableNodeCount || stats.nodes} embeddable symbols`,\n ...(stats.engineFallback ? [` \u26A0 Engine fallback: ${stats.engineFallback}`] : []),\n ]\n : [` Semantic search: disabled`];\n const frameworkLine = stats.frameworks.length > 0\n ? ` Frameworks: ${stats.frameworks.join(', ')}`\n : ` Frameworks: none detected`;\n const archLine = stats.architectureEnabled\n ? stats.architectureStats\n ? ` Architecture: enabled \u2014 ${stats.architectureStats.packages} packages, ${stats.architectureStats.layers} layers, ${stats.architectureStats.packageDeps} deps`\n : ` Architecture: enabled (not yet analyzed \u2014 run kirograph index)`\n : ` Architecture: disabled`;\n\n // Docs stats\n let docsLine = ' Documentation: disabled';\n try {\n const { loadConfig: loadCfg } = await Promise.resolve().then(() => require('../../config.js'));\n const cfg = await loadCfg(cg.getProjectRoot());\n if (cfg.enableDocs) {\n const db = cg.getDatabase();\n db.applyDocsSchema();\n const rawDb = db.getRawDb();\n const docFiles = rawDb.get('SELECT COUNT(DISTINCT file_path) as cnt FROM doc_sections')?.cnt ?? 0;\n const docSections = rawDb.get('SELECT COUNT(*) as cnt FROM doc_sections')?.cnt ?? 0;\n const docRefs = rawDb.get('SELECT COUNT(*) as cnt FROM doc_code_refs')?.cnt ?? 0;\n docsLine = ` Documentation: enabled \u2014 ${docFiles} files, ${docSections} sections, ${docRefs} code refs`;\n }\n } catch { /* non-critical */ }\n\n // Data stats\n let dataLine = ' Data: disabled';\n try {\n const { loadConfig: loadCfg2 } = await Promise.resolve().then(() => require('../../config.js'));\n const cfg2 = await loadCfg2(cg.getProjectRoot());\n if (cfg2.enableData) {\n const rawDb2 = cg.getDatabase().getRawDb();\n cg.getDatabase().applyDataSchema();\n const datasetCount = rawDb2.get('SELECT COUNT(*) as cnt FROM data_datasets')?.cnt ?? 0;\n if (datasetCount > 0) {\n const totalRows = rawDb2.get('SELECT SUM(row_count) as total FROM data_datasets')?.total ?? 0;\n const totalCols = rawDb2.get('SELECT SUM(column_count) as total FROM data_datasets')?.total ?? 0;\n const totalSize = rawDb2.get('SELECT SUM(file_size) as total FROM data_datasets')?.total ?? 0;\n const sizeMb = (totalSize / 1024 / 1024).toFixed(2);\n dataLine = ` Data: enabled \u2014 ${datasetCount} datasets, ${totalRows.toLocaleString()} rows, ${totalCols} columns (${sizeMb} MB source)`;\n } else {\n dataLine = ` Data: enabled (no datasets indexed yet \u2014 run kirograph index)`;\n }\n }\n } catch { /* non-critical */ }\n\n // Security stats\n let securityLine = ' Security: disabled';\n try {\n const { loadConfig: loadCfgSec } = await Promise.resolve().then(() => require('../../config.js'));\n const cfgSec = await loadCfgSec(cg.getProjectRoot());\n if (cfgSec.enableSecurity) {\n const db = cg.getDatabase();\n db.applySecuritySchema();\n const rawDb = db.getRawDb();\n const depCount = rawDb.get('SELECT COUNT(*) as cnt FROM sec_dependencies')?.cnt ?? 0;\n const vulnCount = rawDb.get('SELECT COUNT(*) as cnt FROM sec_vulnerabilities')?.cnt ?? 0;\n const affectedCount = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'affected'\")?.cnt ?? 0;\n const staleCount = rawDb.get('SELECT COUNT(*) as cnt FROM sec_dependencies WHERE vuln_data_stale = 1')?.cnt ?? 0;\n const staleNote = staleCount > 0 ? ` \u26A0 ${staleCount} stale` : '';\n securityLine = ` Security: enabled \u2014 ${depCount} deps, ${vulnCount} vulns (${affectedCount} affected)${staleNote}`;\n }\n } catch { /* non-critical */ }\n\n // Patterns stats\n let patternsLine = ' Patterns: disabled';\n try {\n const { loadConfig: loadCfgPat } = await Promise.resolve().then(() => require('../../config.js'));\n const cfgP = await loadCfgPat(cg.getProjectRoot());\n if ((cfgP as any).enablePatterns) {\n const rawDbP = cg.getDatabase().getRawDb();\n const tableExistsP = rawDbP.get(\"SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'\");\n if (tableExistsP) {\n const matchCount = rawDbP.get('SELECT COUNT(*) as cnt FROM pattern_matches')?.cnt ?? 0;\n const fileCount = rawDbP.get('SELECT COUNT(DISTINCT file_path) as cnt FROM pattern_matches')?.cnt ?? 0;\n const ruleCount = rawDbP.get('SELECT COUNT(DISTINCT pattern_id) as cnt FROM pattern_matches')?.cnt ?? 0;\n patternsLine = ` Patterns: enabled \u2014 ${matchCount} matches, ${ruleCount} rules triggered, ${fileCount} files`;\n } else {\n patternsLine = ` Patterns: enabled (no data yet \u2014 run kirograph index)`;\n }\n }\n } catch { /* non-critical */ }\n\n // Sync state warning\n const threshold = stats.syncWarningThreshold ?? 10;\n const pendingFiles: number = stats.pendingFiles ?? 0;\n const syncRunning: boolean = stats.syncRunning ?? false;\n const syncLines: string[] = [];\n if (syncRunning) {\n syncLines.push(` \u26A0 Sync is currently running in the background.`);\n }\n if (threshold > 0 && pendingFiles >= threshold) {\n syncLines.push(\n ` \u26A0 Index may be incomplete \u2014 ${pendingFiles} file${pendingFiles !== 1 ? 's' : ''} pending sync.` +\n (syncRunning ? ' Sync is running in background.' : ' Run `kirograph sync` to update.') +\n ` Would you like to wait before proceeding?`\n );\n }\n\n // Token savings summary\n const { TokenTracker } = await Promise.resolve().then(() => require('../../compression/tracker.js'));\n const tracker = new TokenTracker(cg.getProjectRoot());\n const gainStats = tracker.getStats('session');\n const gainLines: string[] = [];\n if (gainStats.totalCommands > 0) {\n gainLines.push(` Compression: ${gainStats.totalCommands} commands, ${gainStats.savingsPercent}% avg savings (${gainStats.totalSaved.toLocaleString()} tokens saved this session)`);\n }\n\n return [\n `KiroGraph Status`,\n ` Project: ${cg.getProjectRoot()}`,\n ` Files indexed: ${stats.files}`,\n ` Symbols: ${stats.nodes}`,\n ` Relationships: ${stats.edges}`,\n ` By kind: ${Object.entries(stats.nodesByKind).map(([k, v]) => `${k}=${v}`).join(', ')}`,\n langLine ? ` By language: ${langLine}` : '',\n frameworkLine,\n archLine,\n docsLine,\n dataLine,\n securityLine,\n patternsLine,\n ` DB size: ${dbMb} MB`,\n ...semanticLines,\n ...syncLines,\n ...gainLines,\n ].filter(Boolean).join('\\n');\n }\n\n case 'kirograph_files': {\n const format = (args.format as string) ?? 'tree';\n const includeMetadata = args.includeMetadata !== false;\n const tree = cg.getFiles({\n filterPath: args.filterPath as string | undefined,\n pattern: args.pattern as string | undefined,\n maxDepth: args.maxDepth as number | undefined,\n });\n\n if (format === 'flat') {\n const flat: string[] = [];\n function flattenTree(nodes: import('../../index').FileTreeNode[]): void {\n for (const node of nodes) {\n if (node.type === 'file') {\n const meta = includeMetadata && node.language ? ` [${node.language}${node.symbolCount ? ` \u00B7 ${node.symbolCount}` : ''}]` : '';\n flat.push(`${node.path}${meta}`);\n }\n if (node.children?.length) flattenTree(node.children);\n }\n }\n flattenTree(tree);\n return flat.length > 0 ? flat.join('\\n') : 'No indexed files found.';\n }\n\n if (format === 'grouped') {\n const groups = new Map<string, import('../../index').FileTreeNode[]>();\n function groupTree(nodes: import('../../index').FileTreeNode[]): void {\n for (const node of nodes) {\n if (node.type === 'file') {\n const dir = node.path.includes('/') ? node.path.slice(0, node.path.lastIndexOf('/')) : '.';\n if (!groups.has(dir)) groups.set(dir, []);\n groups.get(dir)!.push(node);\n }\n if (node.children?.length) groupTree(node.children);\n }\n }\n groupTree(tree);\n const lines: string[] = [];\n for (const [dir, files] of [...groups.entries()].sort()) {\n lines.push(`${dir}/`);\n for (const f of files) {\n const meta = includeMetadata && f.language ? ` [${f.language}${f.symbolCount ? ` \u00B7 ${f.symbolCount}` : ''}]` : '';\n lines.push(` ${f.name}${meta}`);\n }\n }\n return lines.length > 0 ? lines.join('\\n') : 'No indexed files found.';\n }\n\n if (format === 'compact') {\n // rtk-style compact: directory summary with file counts and language breakdown\n const dirStats = new Map<string, { files: number; symbols: number; langs: Map<string, number> }>();\n function compactTree(nodes: import('../../index').FileTreeNode[]): void {\n for (const node of nodes) {\n if (node.type === 'file') {\n const dir = node.path.includes('/') ? node.path.slice(0, node.path.lastIndexOf('/')) : '.';\n const stat = dirStats.get(dir) || { files: 0, symbols: 0, langs: new Map() };\n stat.files++;\n stat.symbols += node.symbolCount || 0;\n if (node.language) stat.langs.set(node.language, (stat.langs.get(node.language) || 0) + 1);\n dirStats.set(dir, stat);\n }\n if (node.children?.length) compactTree(node.children);\n }\n }\n compactTree(tree);\n const totalFiles = [...dirStats.values()].reduce((s, d) => s + d.files, 0);\n const totalSymbols = [...dirStats.values()].reduce((s, d) => s + d.symbols, 0);\n const lines: string[] = [`${totalFiles} files, ${totalSymbols} symbols in ${dirStats.size} directories:\\n`];\n for (const [dir, stat] of [...dirStats.entries()].sort()) {\n const langSummary = [...stat.langs.entries()].map(([l, c]) => `${l}:${c}`).join(' ');\n lines.push(`${dir}/ (${stat.files} files, ${stat.symbols} symbols) ${langSummary}`);\n }\n return lines.join('\\n');\n }\n\n // Default: tree format\n const lines: string[] = [];\n function renderTree(nodes: import('../../index').FileTreeNode[], prefix: string): void {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n const isLast = i === nodes.length - 1;\n const connector = isLast ? '\u2514\u2500\u2500 ' : '\u251C\u2500\u2500 ';\n const childPrefix = prefix + (isLast ? ' ' : '\u2502 ');\n const meta = includeMetadata && node.type === 'file' && node.language\n ? ` [${node.language}${node.symbolCount ? ` \u00B7 ${node.symbolCount} symbols` : ''}]`\n : '';\n lines.push(`${prefix}${connector}${node.name}${meta}`);\n if (node.children?.length) renderTree(node.children, childPrefix);\n }\n }\n renderTree(tree, '');\n return lines.length > 0 ? lines.join('\\n') : 'No indexed files found.';\n }\n\n case 'kirograph_affected': {\n const files = (args.files as string[]) ?? [];\n if (files.length === 0) return 'No files provided. Pass file paths in the \"files\" array.';\n\n const affected = cg.getAffectedTests(files, {\n depth: (args.depth as number) ?? 5,\n testPattern: args.testPattern as string | undefined,\n });\n\n if (affected.length === 0) return `No affected test files found for the provided ${files.length} changed file(s).`;\n return `Affected test files (${affected.length}) for ${files.length} changed file(s):\\n\\n` +\n affected.map(f => `- ${f}`).join('\\n');\n }\n\n default:\n return `Unknown tool: ${toolName}`;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["renderTree", "flattenTree", "groupTree", "lines", "compactTree"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var data_exports = {};
|
|
20
|
+
__export(data_exports, {
|
|
21
|
+
handleData: () => handleData
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(data_exports);
|
|
24
|
+
const queryTracker = /* @__PURE__ */ new Map();
|
|
25
|
+
function checkPaginationLoop(dataset, offset, response) {
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
const key = dataset;
|
|
28
|
+
const currentOffset = offset ?? 0;
|
|
29
|
+
for (const [k, v] of queryTracker) {
|
|
30
|
+
if (now - v.lastCall > 6e4) queryTracker.delete(k);
|
|
31
|
+
}
|
|
32
|
+
const entry = queryTracker.get(key) ?? { offsets: [], lastCall: 0 };
|
|
33
|
+
entry.offsets.push(currentOffset);
|
|
34
|
+
entry.lastCall = now;
|
|
35
|
+
if (entry.offsets.length > 10) entry.offsets = entry.offsets.slice(-10);
|
|
36
|
+
queryTracker.set(key, entry);
|
|
37
|
+
if (entry.offsets.length > 5) {
|
|
38
|
+
const recent = entry.offsets.slice(-6);
|
|
39
|
+
let isIncrementing = true;
|
|
40
|
+
for (let i = 1; i < recent.length; i++) {
|
|
41
|
+
if (recent[i] <= recent[i - 1]) {
|
|
42
|
+
isIncrementing = false;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (isIncrementing) {
|
|
47
|
+
return response + "\n\n\u26A0 Pagination detected. Consider using kirograph_data_aggregate for summary statistics instead of paginating through all rows.";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return response;
|
|
51
|
+
}
|
|
52
|
+
async function handleData(toolName, args, cg) {
|
|
53
|
+
switch (toolName) {
|
|
54
|
+
case "kirograph_data_list": {
|
|
55
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
|
|
56
|
+
const projectRoot = cg.getProjectRoot();
|
|
57
|
+
const config = await loadConfig(projectRoot);
|
|
58
|
+
if (!config.enableData) return "Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.";
|
|
59
|
+
const { DataQueries } = await Promise.resolve().then(() => require("../../data/queries.js"));
|
|
60
|
+
const db = cg.getDatabase();
|
|
61
|
+
db.applyDataSchema();
|
|
62
|
+
const dq = new DataQueries(db.getRawDb());
|
|
63
|
+
const datasets = dq.listDatasets();
|
|
64
|
+
if (datasets.length === 0) return "No datasets indexed. Run kirograph index or kirograph data reindex.";
|
|
65
|
+
return datasets.map((ds) => {
|
|
66
|
+
const sizeMb = (ds.fileSize / 1024 / 1024).toFixed(2);
|
|
67
|
+
return `${ds.id} (${ds.format})
|
|
68
|
+
File: ${ds.filePath}
|
|
69
|
+
Rows: ${ds.rowCount.toLocaleString()} | Columns: ${ds.columnCount} | Size: ${sizeMb} MB`;
|
|
70
|
+
}).join("\n\n");
|
|
71
|
+
}
|
|
72
|
+
case "kirograph_data_describe": {
|
|
73
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
|
|
74
|
+
const projectRoot = cg.getProjectRoot();
|
|
75
|
+
const config = await loadConfig(projectRoot);
|
|
76
|
+
if (!config.enableData) return "Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.";
|
|
77
|
+
const { DataQueries } = await Promise.resolve().then(() => require("../../data/queries.js"));
|
|
78
|
+
const db = cg.getDatabase();
|
|
79
|
+
db.applyDataSchema();
|
|
80
|
+
const dq = new DataQueries(db.getRawDb());
|
|
81
|
+
if (args.column) {
|
|
82
|
+
const col = dq.describeColumn(args.dataset, args.column);
|
|
83
|
+
if (!col) return `Column "${args.column}" not found in dataset "${args.dataset}".`;
|
|
84
|
+
return [
|
|
85
|
+
`Column: ${col.name}`,
|
|
86
|
+
`Type: ${col.inferredType}`,
|
|
87
|
+
`Nullable: ${col.nullable} (${(col.nullPct * 100).toFixed(1)}% null)`,
|
|
88
|
+
`Cardinality: ${col.cardinality}`,
|
|
89
|
+
col.minValue ? `Min: ${col.minValue}` : "",
|
|
90
|
+
col.maxValue ? `Max: ${col.maxValue}` : "",
|
|
91
|
+
col.meanValue !== null ? `Mean: ${col.meanValue.toFixed(2)}` : "",
|
|
92
|
+
`Samples: ${col.sampleValues.join(", ")}`
|
|
93
|
+
].filter(Boolean).join("\n");
|
|
94
|
+
}
|
|
95
|
+
const result = dq.describeDataset(args.dataset);
|
|
96
|
+
if (!result) return `Dataset "${args.dataset}" not found. Use kirograph_data_list to see available datasets.`;
|
|
97
|
+
const lines = [
|
|
98
|
+
`Dataset: ${result.dataset.id} (${result.dataset.format})`,
|
|
99
|
+
`File: ${result.dataset.filePath}`,
|
|
100
|
+
`Rows: ${result.dataset.rowCount.toLocaleString()} | Columns: ${result.dataset.columnCount}`,
|
|
101
|
+
"",
|
|
102
|
+
"Columns:"
|
|
103
|
+
];
|
|
104
|
+
for (const col of result.columns) {
|
|
105
|
+
const nullInfo = col.nullable ? ` (${(col.nullPct * 100).toFixed(0)}% null)` : "";
|
|
106
|
+
const samples = col.sampleValues.length > 0 ? ` \u2014 samples: ${col.sampleValues.slice(0, 3).join(", ")}` : "";
|
|
107
|
+
const summary = col.summary ? ` [${col.summary}]` : "";
|
|
108
|
+
lines.push(` ${col.name}: ${col.inferredType}${nullInfo} [${col.cardinality} distinct]${samples}${summary}`);
|
|
109
|
+
}
|
|
110
|
+
const rules = dq.validationRules(args.dataset);
|
|
111
|
+
if (rules && rules.length > 0) {
|
|
112
|
+
lines.push("", "Validation rules:");
|
|
113
|
+
for (const r of rules.slice(0, 10)) {
|
|
114
|
+
lines.push(` ${r.column}: ${r.rules.join("; ")}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const hints = dq.sampleHints(args.dataset);
|
|
118
|
+
if (hints && hints.length > 0) {
|
|
119
|
+
lines.push("", "Sample data hints:");
|
|
120
|
+
for (const h of hints.slice(0, 10)) {
|
|
121
|
+
lines.push(` ${h.column}: ${h.hint}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return lines.join("\n");
|
|
125
|
+
}
|
|
126
|
+
case "kirograph_data_query": {
|
|
127
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
|
|
128
|
+
const projectRoot = cg.getProjectRoot();
|
|
129
|
+
const config = await loadConfig(projectRoot);
|
|
130
|
+
if (!config.enableData) return "Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.";
|
|
131
|
+
const { DataQueries } = await Promise.resolve().then(() => require("../../data/queries.js"));
|
|
132
|
+
const db = cg.getDatabase();
|
|
133
|
+
db.applyDataSchema();
|
|
134
|
+
const dq = new DataQueries(db.getRawDb());
|
|
135
|
+
const result = dq.queryRows(args.dataset, {
|
|
136
|
+
filters: args.filters,
|
|
137
|
+
columns: args.columns,
|
|
138
|
+
limit: args.limit ?? 100,
|
|
139
|
+
offset: args.offset ?? 0
|
|
140
|
+
});
|
|
141
|
+
if (!result) return `Dataset "${args.dataset}" not found.`;
|
|
142
|
+
if (result.rows.length === 0) return `No rows match the given filters (${result.totalMatching} total in dataset).`;
|
|
143
|
+
const header = `${result.rows.length} rows returned (${result.totalMatching} total matching):
|
|
144
|
+
`;
|
|
145
|
+
const rowStrs = result.rows.slice(0, 50).map((row, i) => {
|
|
146
|
+
const vals = Object.entries(row).map(([k, v]) => `${k}=${v ?? "null"}`).join(", ");
|
|
147
|
+
return ` ${i + 1}. ${vals}`;
|
|
148
|
+
});
|
|
149
|
+
if (result.rows.length > 50) rowStrs.push(` \u2026and ${result.rows.length - 50} more rows`);
|
|
150
|
+
let response = header + rowStrs.join("\n");
|
|
151
|
+
const maxChars = config.dataMaxResponseTokens * 4;
|
|
152
|
+
if (response.length > maxChars) {
|
|
153
|
+
response = response.slice(0, maxChars) + "\n\n[truncated: response exceeded token budget]";
|
|
154
|
+
}
|
|
155
|
+
response = checkPaginationLoop(args.dataset, args.offset, response);
|
|
156
|
+
return response;
|
|
157
|
+
}
|
|
158
|
+
case "kirograph_data_aggregate": {
|
|
159
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
|
|
160
|
+
const projectRoot = cg.getProjectRoot();
|
|
161
|
+
const config = await loadConfig(projectRoot);
|
|
162
|
+
if (!config.enableData) return "Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.";
|
|
163
|
+
const { DataQueries } = await Promise.resolve().then(() => require("../../data/queries.js"));
|
|
164
|
+
const db = cg.getDatabase();
|
|
165
|
+
db.applyDataSchema();
|
|
166
|
+
const dq = new DataQueries(db.getRawDb());
|
|
167
|
+
const result = dq.aggregate(args.dataset, {
|
|
168
|
+
groupBy: args.groupBy ?? [],
|
|
169
|
+
metrics: args.metrics ?? [],
|
|
170
|
+
filters: args.filters
|
|
171
|
+
});
|
|
172
|
+
if (!result) return `Dataset "${args.dataset}" not found.`;
|
|
173
|
+
if (result.rows.length === 0) return "No results (empty dataset or all rows filtered out).";
|
|
174
|
+
const keys = Object.keys(result.rows[0]);
|
|
175
|
+
const header = keys.join(" | ");
|
|
176
|
+
const separator = keys.map(() => "---").join(" | ");
|
|
177
|
+
const rows = result.rows.slice(0, 100).map((row) => keys.map((k) => row[k] ?? "null").join(" | "));
|
|
178
|
+
let response = `${header}
|
|
179
|
+
${separator}
|
|
180
|
+
${rows.join("\n")}${result.rows.length > 100 ? `
|
|
181
|
+
\u2026and ${result.rows.length - 100} more groups` : ""}`;
|
|
182
|
+
const maxChars = config.dataMaxResponseTokens * 4;
|
|
183
|
+
if (response.length > maxChars) {
|
|
184
|
+
response = response.slice(0, maxChars) + "\n\n[truncated: response exceeded token budget]";
|
|
185
|
+
}
|
|
186
|
+
return response;
|
|
187
|
+
}
|
|
188
|
+
case "kirograph_data_search": {
|
|
189
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
|
|
190
|
+
const projectRoot = cg.getProjectRoot();
|
|
191
|
+
const config = await loadConfig(projectRoot);
|
|
192
|
+
if (!config.enableData) return "Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.";
|
|
193
|
+
const { DataQueries } = await Promise.resolve().then(() => require("../../data/queries.js"));
|
|
194
|
+
const db = cg.getDatabase();
|
|
195
|
+
db.applyDataSchema();
|
|
196
|
+
const dq = new DataQueries(db.getRawDb());
|
|
197
|
+
const cols = dq.searchColumns(args.dataset, args.query);
|
|
198
|
+
if (cols.length === 0) return `No columns matching "${args.query}" in dataset "${args.dataset}".`;
|
|
199
|
+
return cols.map((c) => {
|
|
200
|
+
const samples = c.sampleValues.length > 0 ? ` \u2014 samples: ${c.sampleValues.slice(0, 3).join(", ")}` : "";
|
|
201
|
+
return `${c.name}: ${c.inferredType} [${c.cardinality} distinct]${samples}`;
|
|
202
|
+
}).join("\n");
|
|
203
|
+
}
|
|
204
|
+
case "kirograph_data_join": {
|
|
205
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
|
|
206
|
+
const projectRoot = cg.getProjectRoot();
|
|
207
|
+
const config = await loadConfig(projectRoot);
|
|
208
|
+
if (!config.enableData) return "Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.";
|
|
209
|
+
const { DataQueries } = await Promise.resolve().then(() => require("../../data/queries.js"));
|
|
210
|
+
const db = cg.getDatabase();
|
|
211
|
+
db.applyDataSchema();
|
|
212
|
+
const dq = new DataQueries(db.getRawDb());
|
|
213
|
+
try {
|
|
214
|
+
const result = dq.join({
|
|
215
|
+
left: args.left,
|
|
216
|
+
right: args.right,
|
|
217
|
+
leftColumn: args.leftColumn,
|
|
218
|
+
rightColumn: args.rightColumn,
|
|
219
|
+
type: args.type ?? "inner",
|
|
220
|
+
columns: args.columns,
|
|
221
|
+
limit: args.limit
|
|
222
|
+
});
|
|
223
|
+
if (!result) return `Dataset not found. Verify both dataset IDs with kirograph_data_list.`;
|
|
224
|
+
const joinTypeStr = String(args.type ?? "inner").toUpperCase();
|
|
225
|
+
const header = `Join: ${args.left}.${args.leftColumn} ${joinTypeStr} JOIN ${args.right}.${args.rightColumn}
|
|
226
|
+
Matching rows: ${result.totalMatching} (showing ${result.rows.length})`;
|
|
227
|
+
if (result.rows.length === 0) return `${header}
|
|
228
|
+
|
|
229
|
+
No matching rows.`;
|
|
230
|
+
const lines = result.rows.map((r) => JSON.stringify(r));
|
|
231
|
+
let response = `${header}
|
|
232
|
+
|
|
233
|
+
${lines.join("\n")}`;
|
|
234
|
+
const maxChars = config.dataMaxResponseTokens * 4;
|
|
235
|
+
if (response.length > maxChars) {
|
|
236
|
+
response = response.slice(0, maxChars) + "\n\n[truncated: response exceeded token budget]";
|
|
237
|
+
}
|
|
238
|
+
return response;
|
|
239
|
+
} catch (err) {
|
|
240
|
+
return `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
case "kirograph_data_correlations": {
|
|
244
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
|
|
245
|
+
const projectRoot = cg.getProjectRoot();
|
|
246
|
+
const config = await loadConfig(projectRoot);
|
|
247
|
+
if (!config.enableData) return "Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.";
|
|
248
|
+
const { DataQueries } = await Promise.resolve().then(() => require("../../data/queries.js"));
|
|
249
|
+
const db = cg.getDatabase();
|
|
250
|
+
db.applyDataSchema();
|
|
251
|
+
const dq = new DataQueries(db.getRawDb());
|
|
252
|
+
const pairs = dq.correlations(args.dataset, args.threshold);
|
|
253
|
+
if (pairs === null) return `Dataset "${args.dataset}" not found.`;
|
|
254
|
+
if (pairs.length === 0) return `No correlations above threshold ${args.threshold ?? 0.3} found. The dataset may have fewer than 2 numeric columns or no significant correlations.`;
|
|
255
|
+
const lines = pairs.map(
|
|
256
|
+
(p) => `${p.column1} \u2194 ${p.column2}: ${p.correlation > 0 ? "+" : ""}${p.correlation.toFixed(4)} (${p.strength})`
|
|
257
|
+
);
|
|
258
|
+
return `Correlations for "${args.dataset}" (threshold: ${args.threshold ?? 0.3}):
|
|
259
|
+
|
|
260
|
+
${lines.join("\n")}`;
|
|
261
|
+
}
|
|
262
|
+
case "kirograph_data_quality": {
|
|
263
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
|
|
264
|
+
const projectRoot = cg.getProjectRoot();
|
|
265
|
+
const config = await loadConfig(projectRoot);
|
|
266
|
+
if (!config.enableData) return "Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.";
|
|
267
|
+
const { DataQueries } = await Promise.resolve().then(() => require("../../data/queries.js"));
|
|
268
|
+
const db = cg.getDatabase();
|
|
269
|
+
db.applyDataSchema();
|
|
270
|
+
const dq = new DataQueries(db.getRawDb());
|
|
271
|
+
const quality = dq.quality(args.dataset);
|
|
272
|
+
if (quality === null) return `Dataset "${args.dataset}" not found.`;
|
|
273
|
+
if (quality.length === 0) return `No quality issues detected in "${args.dataset}". All columns look healthy.`;
|
|
274
|
+
const lines = quality.map(
|
|
275
|
+
(q) => `${q.column} (risk: ${(q.riskScore * 100).toFixed(0)}%): ${q.issues.join("; ")}`
|
|
276
|
+
);
|
|
277
|
+
return `Quality report for "${args.dataset}" (${quality.length} columns with issues):
|
|
278
|
+
|
|
279
|
+
${lines.join("\n")}`;
|
|
280
|
+
}
|
|
281
|
+
case "kirograph_data_drift": {
|
|
282
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
|
|
283
|
+
const projectRoot = cg.getProjectRoot();
|
|
284
|
+
const config = await loadConfig(projectRoot);
|
|
285
|
+
if (!config.enableData) return "Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.";
|
|
286
|
+
const { DataQueries } = await Promise.resolve().then(() => require("../../data/queries.js"));
|
|
287
|
+
const db = cg.getDatabase();
|
|
288
|
+
db.applyDataSchema();
|
|
289
|
+
const dq = new DataQueries(db.getRawDb());
|
|
290
|
+
const drift = dq.detectDrift(args.dataset);
|
|
291
|
+
if (drift === null) return `Dataset "${args.dataset}" not found.`;
|
|
292
|
+
if (!drift.hasDrift) {
|
|
293
|
+
const rowDelta = drift.rowCountDelta !== 0 ? ` (rows: ${drift.rowCountDelta > 0 ? "+" : ""}${drift.rowCountDelta})` : "";
|
|
294
|
+
return `No schema drift detected for "${args.dataset}".${rowDelta}`;
|
|
295
|
+
}
|
|
296
|
+
const driftLines = [`Schema drift detected for "${args.dataset}":`];
|
|
297
|
+
if (drift.addedColumns?.length) driftLines.push(` Added columns: ${drift.addedColumns.join(", ")}`);
|
|
298
|
+
if (drift.removedColumns?.length) driftLines.push(` Removed columns: ${drift.removedColumns.join(", ")}`);
|
|
299
|
+
if (drift.typeChanges?.length) {
|
|
300
|
+
for (const tc of drift.typeChanges) {
|
|
301
|
+
driftLines.push(` Type change: ${tc.column} ${tc.from} \u2192 ${tc.to}`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (drift.rowCountDelta !== 0) driftLines.push(` Row count delta: ${drift.rowCountDelta > 0 ? "+" : ""}${drift.rowCountDelta}`);
|
|
305
|
+
return driftLines.join("\n");
|
|
306
|
+
}
|
|
307
|
+
case "kirograph_data_history": {
|
|
308
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
|
|
309
|
+
const projectRoot = cg.getProjectRoot();
|
|
310
|
+
const config = await loadConfig(projectRoot);
|
|
311
|
+
if (!config.enableData) return "Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.";
|
|
312
|
+
const { DataQueries } = await Promise.resolve().then(() => require("../../data/queries.js"));
|
|
313
|
+
const db = cg.getDatabase();
|
|
314
|
+
db.applyDataSchema();
|
|
315
|
+
const dq = new DataQueries(db.getRawDb());
|
|
316
|
+
const limit = Math.min(Number(args.limit ?? 10), 50);
|
|
317
|
+
const history = dq.getHistory(args.dataset, limit);
|
|
318
|
+
if (history === null) return `Dataset "${args.dataset}" not found.`;
|
|
319
|
+
if (history.length === 0) return `No history snapshots for "${args.dataset}".`;
|
|
320
|
+
const histLines = [`Schema history for "${args.dataset}" (${history.length} snapshot(s)):
|
|
321
|
+
`];
|
|
322
|
+
for (const snap of history) {
|
|
323
|
+
const date = new Date(snap.snapshotAt).toISOString().replace("T", " ").slice(0, 19);
|
|
324
|
+
const colNames = snap.columns.map((c) => c.name).join(", ");
|
|
325
|
+
histLines.push(`${date} rows: ${snap.rowCount.toLocaleString()} cols: ${snap.columnCount} schema: ${colNames}`);
|
|
326
|
+
}
|
|
327
|
+
return histLines.join("\n");
|
|
328
|
+
}
|
|
329
|
+
default:
|
|
330
|
+
return `Unknown tool: ${toolName}`;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
334
|
+
0 && (module.exports = {
|
|
335
|
+
handleData
|
|
336
|
+
});
|
|
337
|
+
//# sourceMappingURL=data.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/handlers/data.ts"],
|
|
4
|
+
"sourcesContent": ["import KiroGraph from '../../index';\n\nconst queryTracker = new Map<string, { offsets: number[]; lastCall: number }>();\n\nfunction checkPaginationLoop(dataset: string, offset: number | undefined, response: string): string {\n const now = Date.now();\n const key = dataset;\n const currentOffset = offset ?? 0;\n\n // Clean stale entries (older than 60s)\n for (const [k, v] of queryTracker) {\n if (now - v.lastCall > 60_000) queryTracker.delete(k);\n }\n\n const entry = queryTracker.get(key) ?? { offsets: [], lastCall: 0 };\n entry.offsets.push(currentOffset);\n entry.lastCall = now;\n\n // Keep only last 10 offsets\n if (entry.offsets.length > 10) entry.offsets = entry.offsets.slice(-10);\n queryTracker.set(key, entry);\n\n // Check for pagination pattern: >5 calls with incrementing offsets\n if (entry.offsets.length > 5) {\n const recent = entry.offsets.slice(-6);\n let isIncrementing = true;\n for (let i = 1; i < recent.length; i++) {\n if (recent[i]! <= recent[i - 1]!) { isIncrementing = false; break; }\n }\n if (isIncrementing) {\n return response + '\\n\\n\u26A0 Pagination detected. Consider using kirograph_data_aggregate for summary statistics instead of paginating through all rows.';\n }\n }\n\n return response;\n}\n\nexport async function handleData(toolName: string, args: Record<string, unknown>, cg: KiroGraph): Promise<string> {\n switch (toolName) {\n case 'kirograph_data_list': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableData) return 'Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.';\n\n const { DataQueries } = await Promise.resolve().then(() => require('../../data/queries.js'));\n const db = cg.getDatabase();\n db.applyDataSchema();\n const dq = new DataQueries(db.getRawDb());\n const datasets = dq.listDatasets();\n\n if (datasets.length === 0) return 'No datasets indexed. Run kirograph index or kirograph data reindex.';\n\n return datasets.map(ds => {\n const sizeMb = (ds.fileSize / 1024 / 1024).toFixed(2);\n return `${ds.id} (${ds.format})\\n File: ${ds.filePath}\\n Rows: ${ds.rowCount.toLocaleString()} | Columns: ${ds.columnCount} | Size: ${sizeMb} MB`;\n }).join('\\n\\n');\n }\n\n case 'kirograph_data_describe': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableData) return 'Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.';\n\n const { DataQueries } = await Promise.resolve().then(() => require('../../data/queries.js'));\n const db = cg.getDatabase();\n db.applyDataSchema();\n const dq = new DataQueries(db.getRawDb());\n\n if (args.column) {\n const col = dq.describeColumn(args.dataset as string, args.column as string);\n if (!col) return `Column \"${args.column}\" not found in dataset \"${args.dataset}\".`;\n return [\n `Column: ${col.name}`,\n `Type: ${col.inferredType}`,\n `Nullable: ${col.nullable} (${(col.nullPct * 100).toFixed(1)}% null)`,\n `Cardinality: ${col.cardinality}`,\n col.minValue ? `Min: ${col.minValue}` : '',\n col.maxValue ? `Max: ${col.maxValue}` : '',\n col.meanValue !== null ? `Mean: ${col.meanValue.toFixed(2)}` : '',\n `Samples: ${col.sampleValues.join(', ')}`,\n ].filter(Boolean).join('\\n');\n }\n\n const result = dq.describeDataset(args.dataset as string);\n if (!result) return `Dataset \"${args.dataset}\" not found. Use kirograph_data_list to see available datasets.`;\n\n const lines = [\n `Dataset: ${result.dataset.id} (${result.dataset.format})`,\n `File: ${result.dataset.filePath}`,\n `Rows: ${result.dataset.rowCount.toLocaleString()} | Columns: ${result.dataset.columnCount}`,\n '',\n 'Columns:',\n ];\n for (const col of result.columns) {\n const nullInfo = col.nullable ? ` (${(col.nullPct * 100).toFixed(0)}% null)` : '';\n const samples = col.sampleValues.length > 0 ? ` \u2014 samples: ${col.sampleValues.slice(0, 3).join(', ')}` : '';\n const summary = col.summary ? ` [${col.summary}]` : '';\n lines.push(` ${col.name}: ${col.inferredType}${nullInfo} [${col.cardinality} distinct]${samples}${summary}`);\n }\n\n // Validation rules\n const rules = dq.validationRules(args.dataset as string);\n if (rules && rules.length > 0) {\n lines.push('', 'Validation rules:');\n for (const r of rules.slice(0, 10)) {\n lines.push(` ${r.column}: ${r.rules.join('; ')}`);\n }\n }\n\n // Sample data hints\n const hints = dq.sampleHints(args.dataset as string);\n if (hints && hints.length > 0) {\n lines.push('', 'Sample data hints:');\n for (const h of hints.slice(0, 10)) {\n lines.push(` ${h.column}: ${h.hint}`);\n }\n }\n\n return lines.join('\\n');\n }\n\n case 'kirograph_data_query': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableData) return 'Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.';\n\n const { DataQueries } = await Promise.resolve().then(() => require('../../data/queries.js'));\n const db = cg.getDatabase();\n db.applyDataSchema();\n const dq = new DataQueries(db.getRawDb());\n\n const result = dq.queryRows(args.dataset as string, {\n filters: args.filters as any[],\n columns: args.columns as string[],\n limit: (args.limit as number) ?? 100,\n offset: (args.offset as number) ?? 0,\n });\n\n if (!result) return `Dataset \"${args.dataset}\" not found.`;\n if (result.rows.length === 0) return `No rows match the given filters (${result.totalMatching} total in dataset).`;\n\n const header = `${result.rows.length} rows returned (${result.totalMatching} total matching):\\n`;\n const rowStrs = result.rows.slice(0, 50).map((row, i) => {\n const vals = Object.entries(row).map(([k, v]) => `${k}=${v ?? 'null'}`).join(', ');\n return ` ${i + 1}. ${vals}`;\n });\n if (result.rows.length > 50) rowStrs.push(` \u2026and ${result.rows.length - 50} more rows`);\n let response = header + rowStrs.join('\\n');\n\n // Token budget enforcement\n const maxChars = config.dataMaxResponseTokens * 4;\n if (response.length > maxChars) {\n response = response.slice(0, maxChars) + '\\n\\n[truncated: response exceeded token budget]';\n }\n\n // Anti-loop detection\n response = checkPaginationLoop(args.dataset as string, args.offset as number | undefined, response);\n\n return response;\n }\n\n case 'kirograph_data_aggregate': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableData) return 'Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.';\n\n const { DataQueries } = await Promise.resolve().then(() => require('../../data/queries.js'));\n const db = cg.getDatabase();\n db.applyDataSchema();\n const dq = new DataQueries(db.getRawDb());\n\n const result = dq.aggregate(args.dataset as string, {\n groupBy: (args.groupBy as string[]) ?? [],\n metrics: (args.metrics as any[]) ?? [],\n filters: args.filters as any[],\n });\n\n if (!result) return `Dataset \"${args.dataset}\" not found.`;\n if (result.rows.length === 0) return 'No results (empty dataset or all rows filtered out).';\n\n const keys = Object.keys(result.rows[0]);\n const header = keys.join(' | ');\n const separator = keys.map(() => '---').join(' | ');\n const rows = result.rows.slice(0, 100).map(row => keys.map(k => row[k] ?? 'null').join(' | '));\n\n let response = `${header}\\n${separator}\\n${rows.join('\\n')}${result.rows.length > 100 ? `\\n\u2026and ${result.rows.length - 100} more groups` : ''}`;\n\n // Token budget enforcement\n const maxChars = config.dataMaxResponseTokens * 4;\n if (response.length > maxChars) {\n response = response.slice(0, maxChars) + '\\n\\n[truncated: response exceeded token budget]';\n }\n\n return response;\n }\n\n case 'kirograph_data_search': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableData) return 'Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.';\n\n const { DataQueries } = await Promise.resolve().then(() => require('../../data/queries.js'));\n const db = cg.getDatabase();\n db.applyDataSchema();\n const dq = new DataQueries(db.getRawDb());\n\n const cols = dq.searchColumns(args.dataset as string, args.query as string);\n if (cols.length === 0) return `No columns matching \"${args.query}\" in dataset \"${args.dataset}\".`;\n\n return cols.map(c => {\n const samples = c.sampleValues.length > 0 ? ` \u2014 samples: ${c.sampleValues.slice(0, 3).join(', ')}` : '';\n return `${c.name}: ${c.inferredType} [${c.cardinality} distinct]${samples}`;\n }).join('\\n');\n }\n\n case 'kirograph_data_join': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableData) return 'Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.';\n\n const { DataQueries } = await Promise.resolve().then(() => require('../../data/queries.js'));\n const db = cg.getDatabase();\n db.applyDataSchema();\n const dq = new DataQueries(db.getRawDb());\n\n try {\n const result = dq.join({\n left: args.left as string,\n right: args.right as string,\n leftColumn: args.leftColumn as string,\n rightColumn: args.rightColumn as string,\n type: (args.type as any) ?? 'inner',\n columns: args.columns as string[] | undefined,\n limit: args.limit as number | undefined,\n });\n\n if (!result) return `Dataset not found. Verify both dataset IDs with kirograph_data_list.`;\n\n const joinTypeStr = String(args.type ?? 'inner').toUpperCase();\n const header = `Join: ${args.left}.${args.leftColumn} ${joinTypeStr} JOIN ${args.right}.${args.rightColumn}\\nMatching rows: ${result.totalMatching} (showing ${result.rows.length})`;\n if (result.rows.length === 0) return `${header}\\n\\nNo matching rows.`;\n\n const lines = result.rows.map(r => JSON.stringify(r));\n let response = `${header}\\n\\n${lines.join('\\n')}`;\n\n // Token budget enforcement\n const maxChars = config.dataMaxResponseTokens * 4;\n if (response.length > maxChars) {\n response = response.slice(0, maxChars) + '\\n\\n[truncated: response exceeded token budget]';\n }\n\n return response;\n } catch (err) {\n return `Error: ${err instanceof Error ? err.message : String(err)}`;\n }\n }\n\n case 'kirograph_data_correlations': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableData) return 'Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.';\n\n const { DataQueries } = await Promise.resolve().then(() => require('../../data/queries.js'));\n const db = cg.getDatabase();\n db.applyDataSchema();\n const dq = new DataQueries(db.getRawDb());\n\n const pairs = dq.correlations(args.dataset as string, args.threshold as number | undefined);\n if (pairs === null) return `Dataset \"${args.dataset}\" not found.`;\n if (pairs.length === 0) return `No correlations above threshold ${args.threshold ?? 0.3} found. The dataset may have fewer than 2 numeric columns or no significant correlations.`;\n\n const lines = pairs.map(p =>\n `${p.column1} \u2194 ${p.column2}: ${p.correlation > 0 ? '+' : ''}${p.correlation.toFixed(4)} (${p.strength})`\n );\n return `Correlations for \"${args.dataset}\" (threshold: ${args.threshold ?? 0.3}):\\n\\n${lines.join('\\n')}`;\n }\n\n case 'kirograph_data_quality': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableData) return 'Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.';\n\n const { DataQueries } = await Promise.resolve().then(() => require('../../data/queries.js'));\n const db = cg.getDatabase();\n db.applyDataSchema();\n const dq = new DataQueries(db.getRawDb());\n\n const quality = dq.quality(args.dataset as string);\n if (quality === null) return `Dataset \"${args.dataset}\" not found.`;\n if (quality.length === 0) return `No quality issues detected in \"${args.dataset}\". All columns look healthy.`;\n\n const lines = quality.map(q =>\n `${q.column} (risk: ${(q.riskScore * 100).toFixed(0)}%): ${q.issues.join('; ')}`\n );\n return `Quality report for \"${args.dataset}\" (${quality.length} columns with issues):\\n\\n${lines.join('\\n')}`;\n }\n\n case 'kirograph_data_drift': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableData) return 'Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.';\n\n const { DataQueries } = await Promise.resolve().then(() => require('../../data/queries.js'));\n const db = cg.getDatabase();\n db.applyDataSchema();\n const dq = new DataQueries(db.getRawDb());\n\n const drift = dq.detectDrift(args.dataset as string);\n if (drift === null) return `Dataset \"${args.dataset}\" not found.`;\n if (!drift.hasDrift) {\n const rowDelta = drift.rowCountDelta !== 0\n ? ` (rows: ${drift.rowCountDelta > 0 ? '+' : ''}${drift.rowCountDelta})`\n : '';\n return `No schema drift detected for \"${args.dataset}\".${rowDelta}`;\n }\n const driftLines = [`Schema drift detected for \"${args.dataset}\":`];\n if (drift.addedColumns?.length) driftLines.push(` Added columns: ${drift.addedColumns.join(', ')}`);\n if (drift.removedColumns?.length) driftLines.push(` Removed columns: ${drift.removedColumns.join(', ')}`);\n if ((drift as any).typeChanges?.length) {\n for (const tc of (drift as any).typeChanges) {\n driftLines.push(` Type change: ${tc.column} ${tc.from} \u2192 ${tc.to}`);\n }\n }\n if (drift.rowCountDelta !== 0) driftLines.push(` Row count delta: ${drift.rowCountDelta > 0 ? '+' : ''}${drift.rowCountDelta}`);\n return driftLines.join('\\n');\n }\n\n case 'kirograph_data_history': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableData) return 'Data indexing is not enabled. Set enableData: true in .kirograph/config.json and run kirograph index.';\n\n const { DataQueries } = await Promise.resolve().then(() => require('../../data/queries.js'));\n const db = cg.getDatabase();\n db.applyDataSchema();\n const dq = new DataQueries(db.getRawDb());\n\n const limit = Math.min(Number(args.limit ?? 10), 50);\n const history = dq.getHistory(args.dataset as string, limit);\n if (history === null) return `Dataset \"${args.dataset}\" not found.`;\n if (history.length === 0) return `No history snapshots for \"${args.dataset}\".`;\n\n const histLines = [`Schema history for \"${args.dataset}\" (${history.length} snapshot(s)):\\n`];\n for (const snap of history) {\n const date = new Date(snap.snapshotAt).toISOString().replace('T', ' ').slice(0, 19);\n const colNames = snap.columns.map((c: any) => c.name).join(', ');\n histLines.push(`${date} rows: ${snap.rowCount.toLocaleString()} cols: ${snap.columnCount} schema: ${colNames}`);\n }\n return histLines.join('\\n');\n }\n\n default:\n return `Unknown tool: ${toolName}`;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|