kirograph 0.20.1 → 0.22.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 +4 -3
- package/dist/bin/commands/data.js +52 -0
- package/dist/bin/commands/data.js.map +2 -2
- package/dist/bin/commands/docs.js +2 -1
- package/dist/bin/commands/docs.js.map +2 -2
- package/dist/bin/commands/gain.js +21 -1
- package/dist/bin/commands/gain.js.map +2 -2
- package/dist/bin/commands/status.js +23 -1
- package/dist/bin/commands/status.js.map +2 -2
- package/dist/bin/installer/config-prompt.js +30 -1
- package/dist/bin/installer/config-prompt.js.map +2 -2
- package/dist/bin/installer/index.js +108 -0
- package/dist/bin/installer/index.js.map +2 -2
- package/dist/bin/kirograph.js +1 -1
- package/dist/config.js +19 -2
- package/dist/config.js.map +2 -2
- package/dist/core/pipeline.js +3 -1
- package/dist/core/pipeline.js.map +2 -2
- package/dist/data/indexer.js +4 -4
- package/dist/data/indexer.js.map +2 -2
- package/dist/data/linker.js +9 -5
- package/dist/data/linker.js.map +2 -2
- package/dist/data/linker.test.js +60 -0
- package/dist/data/linker.test.js.map +7 -0
- package/dist/data/parsers/__fixtures__/pdf-inspector-stub.js +41 -0
- package/dist/data/parsers/__fixtures__/pdf-inspector-stub.js.map +7 -0
- package/dist/data/parsers/index.js +3 -1
- package/dist/data/parsers/index.js.map +2 -2
- package/dist/data/parsers/pdf.js +95 -0
- package/dist/data/parsers/pdf.js.map +7 -0
- package/dist/data/parsers/pdf.test.js +125 -0
- package/dist/data/parsers/pdf.test.js.map +7 -0
- package/dist/data/queries.js +39 -2
- package/dist/data/queries.js.map +2 -2
- package/dist/data/types.js.map +1 -1
- package/dist/db/data-schema.sql +2 -1
- package/dist/db/database.js +7 -0
- package/dist/db/database.js.map +2 -2
- package/dist/docs/indexer.js +2 -1
- package/dist/docs/indexer.js.map +2 -2
- package/dist/docs/queries.js +2 -1
- package/dist/docs/queries.js.map +2 -2
- package/dist/docs/vectors.js +46 -5
- package/dist/docs/vectors.js.map +2 -2
- package/dist/index.js +1 -0
- package/dist/index.js.map +2 -2
- package/dist/mcp/tools.js +1 -1
- package/dist/mcp/tools.js.map +2 -2
- package/dist/memory/index.js +2 -1
- package/dist/memory/index.js.map +2 -2
- package/dist/memory/vectors.js +52 -8
- package/dist/memory/vectors.js.map +3 -3
- package/dist/types.js.map +2 -2
- package/dist/vectors/index.js +66 -3
- package/dist/vectors/index.js.map +2 -2
- package/dist/vectors/turbovec-index.js +189 -0
- package/dist/vectors/turbovec-index.js.map +7 -0
- package/package.json +7 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,12 +17,21 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
var gain_exports = {};
|
|
20
30
|
__export(gain_exports, {
|
|
21
31
|
register: () => register
|
|
22
32
|
});
|
|
23
33
|
module.exports = __toCommonJS(gain_exports);
|
|
34
|
+
var path = __toESM(require("path"));
|
|
24
35
|
function register(program) {
|
|
25
36
|
program.command("gain").description("Show token savings from kirograph_exec compression").option("--graph", "Show ASCII graph of daily savings").option("--history", "Show recent command history").option("--daily", "Show day-by-day breakdown").option("--period <period>", "Time period: session, today, week, all", "all").option("--json", "Output as JSON").action(async (opts) => {
|
|
26
37
|
const { TokenTracker } = await Promise.resolve().then(() => require("../../compression/tracker.js"));
|
|
@@ -91,7 +102,9 @@ function register(program) {
|
|
|
91
102
|
console.log(` Tokens without KiroGraph: ~${stats.totalOriginal.toLocaleString()}`);
|
|
92
103
|
console.log(` Tokens with KiroGraph: ~${stats.totalCompressed.toLocaleString()}`);
|
|
93
104
|
console.log(` Saved: ~${stats.totalSaved.toLocaleString()} (${stats.savingsPercent}%)`);
|
|
94
|
-
|
|
105
|
+
const { readTurboQuantStats } = await Promise.resolve().then(() => require("../../vectors/turboquant-index.js"));
|
|
106
|
+
const tqStats = readTurboQuantStats(path.join(process.cwd(), ".kirograph"));
|
|
107
|
+
if (stats.bySource.exec.count > 0 || stats.bySource.graph.count > 0 || tqStats) {
|
|
95
108
|
console.log(`
|
|
96
109
|
By source:`);
|
|
97
110
|
if (stats.bySource.graph.count > 0) {
|
|
@@ -100,6 +113,13 @@ function register(program) {
|
|
|
100
113
|
if (stats.bySource.exec.count > 0) {
|
|
101
114
|
console.log(` \u26A1 Compression: ${String(stats.bySource.exec.count).padStart(4)} calls ~${stats.bySource.exec.saved.toLocaleString()} tokens saved (vs raw output)`);
|
|
102
115
|
}
|
|
116
|
+
if (tqStats) {
|
|
117
|
+
const totalEmbeddings = tqStats.count + tqStats.memCount + tqStats.docsCount;
|
|
118
|
+
const totalSavedBytes = tqStats.savedBytes + (tqStats.memRawBytes - tqStats.memActualBytes) + (tqStats.docsRawBytes - tqStats.docsActualBytes);
|
|
119
|
+
const totalSavedMB = (totalSavedBytes / 1048576).toFixed(1);
|
|
120
|
+
const avgRatio = tqStats.compressionRatio.toFixed(1);
|
|
121
|
+
console.log(` \u{1F5DC}\uFE0F TurboQuant: ${String(totalEmbeddings).padStart(5)} embeddings \u2014 ${totalSavedMB} MB saved (${avgRatio}\xD7 avg compression)`);
|
|
122
|
+
}
|
|
103
123
|
}
|
|
104
124
|
if (Object.keys(stats.byFamily).length > 0) {
|
|
105
125
|
console.log(`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/bin/commands/gain.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * kirograph gain \u2014 Token savings analytics CLI command\n */\n\nimport { Command } from 'commander';\n\nexport function register(program: Command): void {\n program\n .command('gain')\n .description('Show token savings from kirograph_exec compression')\n .option('--graph', 'Show ASCII graph of daily savings')\n .option('--history', 'Show recent command history')\n .option('--daily', 'Show day-by-day breakdown')\n .option('--period <period>', 'Time period: session, today, week, all', 'all')\n .option('--json', 'Output as JSON')\n .action(async (opts: { graph?: boolean; history?: boolean; daily?: boolean; period: string; json?: boolean }) => {\n const { TokenTracker } = await Promise.resolve().then(() => require('../../compression/tracker.js'));\n const tracker = new TokenTracker(process.cwd());\n\n if (opts.history) {\n const history = tracker.getHistory(20);\n if (history.length === 0) {\n console.log(' No commands recorded yet. Use kirograph_exec to run commands with compression.');\n return;\n }\n\n if (opts.json) {\n console.log(JSON.stringify(history, null, 2));\n return;\n }\n\n console.log(' Recent compressed commands:\\n');\n for (const r of history) {\n const date = new Date(r.timestamp).toLocaleString();\n const savings = r.originalTokens > 0\n ? Math.round(((r.originalTokens - r.compressedTokens) / r.originalTokens) * 100)\n : 0;\n const cmd = r.command.length > 50 ? r.command.slice(0, 47) + '...' : r.command;\n console.log(` ${date} ${cmd.padEnd(50)} ${savings}% saved (${r.strategy})`);\n }\n return;\n }\n\n if (opts.daily || opts.graph) {\n const daily = tracker.getDailyBreakdown(30);\n if (daily.length === 0) {\n console.log(' No data yet.');\n return;\n }\n\n if (opts.json) {\n console.log(JSON.stringify(daily, null, 2));\n return;\n }\n\n if (opts.graph) {\n console.log(' Token savings (last 30 days):\\n');\n const maxSaved = Math.max(...daily.map(d => d.saved), 1);\n const barWidth = 40;\n\n for (const day of daily) {\n const bar = '\u2588'.repeat(Math.round((day.saved / maxSaved) * barWidth));\n const label = day.date.slice(5); // MM-DD\n console.log(` ${label} ${bar} ${day.saved.toLocaleString()} tokens (${day.commands} cmds)`);\n }\n return;\n }\n\n console.log(' Daily breakdown:\\n');\n console.log(' Date Commands Tokens Saved');\n console.log(' ' + '\u2500'.repeat(40));\n for (const day of daily) {\n console.log(` ${day.date} ${String(day.commands).padStart(8)} ${day.saved.toLocaleString().padStart(12)}`);\n }\n return;\n }\n\n // Default: summary stats\n const period = opts.period as 'session' | 'today' | 'week' | 'all';\n const stats = tracker.getStats(period);\n\n if (stats.totalCommands === 0) {\n console.log(' No savings recorded yet.');\n console.log(' Use kirograph tools and kirograph exec . Savings are tracked automatically.');\n return;\n }\n\n if (opts.json) {\n console.log(JSON.stringify(stats, null, 2));\n return;\n }\n\n console.log(`\\n Token Savings (${period}):`);\n console.log(` ${'\u2500'.repeat(50)}`);\n console.log(` Total calls: ${stats.totalCommands}`);\n console.log(` Tokens without KiroGraph: ~${stats.totalOriginal.toLocaleString()}`);\n console.log(` Tokens with KiroGraph: ~${stats.totalCompressed.toLocaleString()}`);\n console.log(` Saved: ~${stats.totalSaved.toLocaleString()} (${stats.savingsPercent}%)`);\n\n // Source breakdown\n if (stats.bySource.exec.count > 0 || stats.bySource.graph.count > 0) {\n console.log(`\\n By source:`);\n if (stats.bySource.graph.count > 0) {\n console.log(` \uD83D\uDCCA Graph tools: ${String(stats.bySource.graph.count).padStart(4)} calls ~${stats.bySource.graph.saved.toLocaleString()} tokens saved (vs file reads/grep)`);\n }\n if (stats.bySource.exec.count > 0) {\n console.log(` \u26A1 Compression: ${String(stats.bySource.exec.count).padStart(4)} calls ~${stats.bySource.exec.saved.toLocaleString()} tokens saved (vs raw output)`);\n }\n }\n\n if (Object.keys(stats.byFamily).length > 0) {\n console.log(`\\n By family:`);\n for (const [family, data] of Object.entries(stats.byFamily)) {\n const icon = family.startsWith('graph') ? '\uD83D\uDCCA' : '\u26A1';\n console.log(` ${icon} ${family.padEnd(20)} ${String(data.count).padStart(4)} calls ${data.savings}% avg savings`);\n }\n }\n\n console.log();\n });\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/**\n * kirograph gain \u2014 Token savings analytics CLI command\n */\n\nimport { Command } from 'commander';\nimport * as path from 'path';\n\nexport function register(program: Command): void {\n program\n .command('gain')\n .description('Show token savings from kirograph_exec compression')\n .option('--graph', 'Show ASCII graph of daily savings')\n .option('--history', 'Show recent command history')\n .option('--daily', 'Show day-by-day breakdown')\n .option('--period <period>', 'Time period: session, today, week, all', 'all')\n .option('--json', 'Output as JSON')\n .action(async (opts: { graph?: boolean; history?: boolean; daily?: boolean; period: string; json?: boolean }) => {\n const { TokenTracker } = await Promise.resolve().then(() => require('../../compression/tracker.js'));\n const tracker = new TokenTracker(process.cwd());\n\n if (opts.history) {\n const history = tracker.getHistory(20);\n if (history.length === 0) {\n console.log(' No commands recorded yet. Use kirograph_exec to run commands with compression.');\n return;\n }\n\n if (opts.json) {\n console.log(JSON.stringify(history, null, 2));\n return;\n }\n\n console.log(' Recent compressed commands:\\n');\n for (const r of history) {\n const date = new Date(r.timestamp).toLocaleString();\n const savings = r.originalTokens > 0\n ? Math.round(((r.originalTokens - r.compressedTokens) / r.originalTokens) * 100)\n : 0;\n const cmd = r.command.length > 50 ? r.command.slice(0, 47) + '...' : r.command;\n console.log(` ${date} ${cmd.padEnd(50)} ${savings}% saved (${r.strategy})`);\n }\n return;\n }\n\n if (opts.daily || opts.graph) {\n const daily = tracker.getDailyBreakdown(30);\n if (daily.length === 0) {\n console.log(' No data yet.');\n return;\n }\n\n if (opts.json) {\n console.log(JSON.stringify(daily, null, 2));\n return;\n }\n\n if (opts.graph) {\n console.log(' Token savings (last 30 days):\\n');\n const maxSaved = Math.max(...daily.map(d => d.saved), 1);\n const barWidth = 40;\n\n for (const day of daily) {\n const bar = '\u2588'.repeat(Math.round((day.saved / maxSaved) * barWidth));\n const label = day.date.slice(5); // MM-DD\n console.log(` ${label} ${bar} ${day.saved.toLocaleString()} tokens (${day.commands} cmds)`);\n }\n return;\n }\n\n console.log(' Daily breakdown:\\n');\n console.log(' Date Commands Tokens Saved');\n console.log(' ' + '\u2500'.repeat(40));\n for (const day of daily) {\n console.log(` ${day.date} ${String(day.commands).padStart(8)} ${day.saved.toLocaleString().padStart(12)}`);\n }\n return;\n }\n\n // Default: summary stats\n const period = opts.period as 'session' | 'today' | 'week' | 'all';\n const stats = tracker.getStats(period);\n\n if (stats.totalCommands === 0) {\n console.log(' No savings recorded yet.');\n console.log(' Use kirograph tools and kirograph exec . Savings are tracked automatically.');\n return;\n }\n\n if (opts.json) {\n console.log(JSON.stringify(stats, null, 2));\n return;\n }\n\n console.log(`\\n Token Savings (${period}):`);\n console.log(` ${'\u2500'.repeat(50)}`);\n console.log(` Total calls: ${stats.totalCommands}`);\n console.log(` Tokens without KiroGraph: ~${stats.totalOriginal.toLocaleString()}`);\n console.log(` Tokens with KiroGraph: ~${stats.totalCompressed.toLocaleString()}`);\n console.log(` Saved: ~${stats.totalSaved.toLocaleString()} (${stats.savingsPercent}%)`);\n\n // Source breakdown\n const { readTurboQuantStats } = await Promise.resolve().then(() => require('../../vectors/turboquant-index.js'));\n const tqStats = readTurboQuantStats(path.join(process.cwd(), '.kirograph'));\n\n if (stats.bySource.exec.count > 0 || stats.bySource.graph.count > 0 || tqStats) {\n console.log(`\\n By source:`);\n if (stats.bySource.graph.count > 0) {\n console.log(` \uD83D\uDCCA Graph tools: ${String(stats.bySource.graph.count).padStart(4)} calls ~${stats.bySource.graph.saved.toLocaleString()} tokens saved (vs file reads/grep)`);\n }\n if (stats.bySource.exec.count > 0) {\n console.log(` \u26A1 Compression: ${String(stats.bySource.exec.count).padStart(4)} calls ~${stats.bySource.exec.saved.toLocaleString()} tokens saved (vs raw output)`);\n }\n if (tqStats) {\n const totalEmbeddings = tqStats.count + tqStats.memCount + tqStats.docsCount;\n const totalSavedBytes = tqStats.savedBytes + (tqStats.memRawBytes - tqStats.memActualBytes) + (tqStats.docsRawBytes - tqStats.docsActualBytes);\n const totalSavedMB = (totalSavedBytes / 1_048_576).toFixed(1);\n const avgRatio = tqStats.compressionRatio.toFixed(1);\n console.log(` \uD83D\uDDDC\uFE0F TurboQuant: ${String(totalEmbeddings).padStart(5)} embeddings \u2014 ${totalSavedMB} MB saved (${avgRatio}\u00D7 avg compression)`);\n }\n }\n\n if (Object.keys(stats.byFamily).length > 0) {\n console.log(`\\n By family:`);\n for (const [family, data] of Object.entries(stats.byFamily)) {\n const icon = family.startsWith('graph') ? '\uD83D\uDCCA' : '\u26A1';\n console.log(` ${icon} ${family.padEnd(20)} ${String(data.count).padStart(4)} calls ${data.savings}% avg savings`);\n }\n }\n\n console.log();\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -34,6 +34,7 @@ module.exports = __toCommonJS(status_exports);
|
|
|
34
34
|
var path = __toESM(require("path"));
|
|
35
35
|
var import_ui = require("../ui");
|
|
36
36
|
var import_config = require("../../config");
|
|
37
|
+
var import_turboquant_index = require("../../vectors/turboquant-index");
|
|
37
38
|
function register(program) {
|
|
38
39
|
program.command("status [projectPath]").description("Show index statistics").option("--integrations", "Show detected and configured platforms").action(async (projectPath, opts) => {
|
|
39
40
|
const target = path.resolve(projectPath ?? process.cwd());
|
|
@@ -87,7 +88,8 @@ function register(program) {
|
|
|
87
88
|
console.log();
|
|
88
89
|
console.log((0, import_ui.section)(" Semantic Search"));
|
|
89
90
|
if (stats.embeddingsEnabled) {
|
|
90
|
-
const
|
|
91
|
+
const tqStats = stats.semanticEngine === "turboquant" ? (0, import_turboquant_index.readTurboQuantStats)(path.join(target, ".kirograph")) : null;
|
|
92
|
+
const engineLabel = stats.semanticEngine === "turboquant" ? `turboquant ${import_ui.dim}(${stats.vecIndexCount} entries \xB7 ${tqStats ? `${tqStats.bits} bits \xB7 ${tqStats.compressionRatio.toFixed(1)}\xD7 compression` : "not yet indexed"})${import_ui.reset}` : stats.semanticEngine === "sqlite-vec" ? `sqlite-vec ${import_ui.dim}(${stats.vecIndexCount} entries in ANN index)${import_ui.reset}` : stats.semanticEngine === "orama" ? `orama ${import_ui.dim}(hybrid \u2014 ${stats.vecIndexCount} docs in index)${import_ui.reset}` : stats.semanticEngine === "pglite" ? `pglite+pgvector ${import_ui.dim}(hybrid \u2014 ${stats.vecIndexCount} rows in DB)${import_ui.reset}` : stats.semanticEngine === "lancedb" ? `lancedb ${import_ui.dim}(${stats.vecIndexCount} entries in ANN index)${import_ui.reset}` : stats.semanticEngine === "qdrant" ? `qdrant ${import_ui.dim}(${stats.vecIndexCount} points in collection)${import_ui.reset}` : stats.semanticEngine === "typesense" ? `typesense ${import_ui.dim}(${stats.vecIndexCount} documents in collection)${import_ui.reset}` : stats.semanticEngine === "turbovec" ? `turbovec ${import_ui.dim}(${stats.vecIndexCount} entries \xB7 ${stats.turbovecBits ?? 4} bits \xB7 Rust/SIMD)${import_ui.reset}` : `in-process cosine`;
|
|
91
93
|
const total = stats.embeddableNodeCount > 0 ? stats.embeddableNodeCount : stats.nodes;
|
|
92
94
|
const displayed = Math.min(stats.embeddingCount, total);
|
|
93
95
|
const coverage = total > 0 ? Math.min(100, Math.round(stats.embeddingCount / total * 100)) : 0;
|
|
@@ -98,6 +100,26 @@ function register(program) {
|
|
|
98
100
|
console.log(` ${"\x1B[33m"}\u26A0 engine fallback: ${stats.engineFallback}${import_ui.reset}`);
|
|
99
101
|
}
|
|
100
102
|
console.log(` ${(0, import_ui.label)("Indexed")} ${(0, import_ui.value)(`${displayed} / ${total}`)} ${import_ui.dim}(${coverage}%)${import_ui.reset}`);
|
|
103
|
+
if (tqStats) {
|
|
104
|
+
const rawMB = (tqStats.rawBytes / 1048576).toFixed(1);
|
|
105
|
+
const compMB = (tqStats.actualBytes / 1048576).toFixed(1);
|
|
106
|
+
const savedMB = (tqStats.savedBytes / 1048576).toFixed(1);
|
|
107
|
+
console.log(` ${(0, import_ui.label)("Raw size")} ${import_ui.dim}${rawMB} MB \u2192 compressed ${compMB} MB (${savedMB} MB saved)${import_ui.reset}`);
|
|
108
|
+
if (tqStats.memEnabled && tqStats.memCount > 0) {
|
|
109
|
+
const mRawMB = (tqStats.memRawBytes / 1048576).toFixed(1);
|
|
110
|
+
const mCompMB = (tqStats.memActualBytes / 1048576).toFixed(1);
|
|
111
|
+
console.log(` ${(0, import_ui.label)("Memory")} ${import_ui.dim}${tqStats.memCount} observations \u2192 ${mRawMB} MB \u2192 ${mCompMB} MB${import_ui.reset}`);
|
|
112
|
+
}
|
|
113
|
+
if (tqStats.docsEnabled && tqStats.docsCount > 0) {
|
|
114
|
+
const dRawMB = (tqStats.docsRawBytes / 1048576).toFixed(1);
|
|
115
|
+
const dCompMB = (tqStats.docsActualBytes / 1048576).toFixed(1);
|
|
116
|
+
console.log(` ${(0, import_ui.label)("Docs")} ${import_ui.dim}${tqStats.docsCount} sections \u2192 ${dRawMB} MB \u2192 ${dCompMB} MB${import_ui.reset}`);
|
|
117
|
+
}
|
|
118
|
+
const totalSaved = tqStats.savedBytes + (tqStats.memRawBytes - tqStats.memActualBytes) + (tqStats.docsRawBytes - tqStats.docsActualBytes);
|
|
119
|
+
if (totalSaved > 0) {
|
|
120
|
+
console.log(` ${(0, import_ui.label)("Total RAM")} ${import_ui.green}${(totalSaved / 1048576).toFixed(1)} MB saved${import_ui.reset} ${import_ui.dim}(TurboQuant compression)${import_ui.reset}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
101
123
|
} else {
|
|
102
124
|
console.log(` ${(0, import_ui.label)("Status")} ${import_ui.dim}disabled${import_ui.reset}`);
|
|
103
125
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/bin/commands/status.ts"],
|
|
4
|
-
"sourcesContent": ["import { Command } from 'commander';\nimport * as path from 'path';\nimport { dim, reset, violet, bold, green, label, value, section, renderTable } from '../ui';\nimport { loadConfig } from '../../config';\n\nexport function register(program: Command): void {\n program\n .command('status [projectPath]')\n .description('Show index statistics')\n .option('--integrations', 'Show detected and configured platforms')\n .action(async (projectPath: string | undefined, opts: { integrations?: boolean }) => {\n const target = path.resolve(projectPath ?? process.cwd());\n\n if (opts.integrations) {\n await showIntegrations(target);\n return;\n }\n\n const KiroGraph = (await Promise.resolve().then(() => require('../../index.js'))).default;\n const cg = await KiroGraph.open(target);\n const stats = await cg.getStats();\n\n console.log();\n console.log(section(' Graph'));\n console.log(` ${label('Files')} ${value(String(stats.files))}`);\n console.log(` ${label('Symbols')} ${value(String(stats.nodes))}`);\n console.log(` ${label('Edges')} ${value(String(stats.edges))}`);\n\n if (stats.frameworks.length > 0) {\n console.log(` ${label('Frameworks')} ${value(stats.frameworks.join(', '))}`);\n }\n\n const kindEntries = Object.entries(stats.nodesByKind).sort((a, b) => b[1] - a[1]);\n if (kindEntries.length > 0) {\n console.log(`\\n ${label('By kind')}`);\n console.log(renderTable(kindEntries.map(([k, v]) => [k, String(v)])));\n }\n\n const langEntries = Object.entries(stats.filesByLanguage ?? {}).sort((a, b) => b[1] - a[1]);\n if (langEntries.length > 0) {\n console.log(`\\n ${label('By language')}`);\n console.log(renderTable(langEntries.map(([k, v]) => [k, String(v)])));\n }\n\n // Sync state\n const threshold = stats.syncWarningThreshold ?? 10;\n const pendingFiles: number = stats.pendingFiles ?? 0;\n const syncRunning: boolean = stats.syncRunning ?? false;\n console.log();\n console.log(section(' Sync'));\n if (syncRunning) {\n console.log(` ${'\\x1b[33m'}\u26A0 Sync is currently running in the background.${reset}`);\n } else {\n console.log(` ${label('Status')} ${dim}idle${reset}`);\n }\n if (pendingFiles > 0) {\n const warn = threshold > 0 && pendingFiles >= threshold;\n const pendingLabel = warn ? `${'\\x1b[33m'}${pendingFiles} files pending${reset}` : `${dim}${pendingFiles} files pending${reset}`;\n console.log(` ${label('Pending')} ${pendingLabel}`);\n if (warn) {\n console.log(` ${'\\x1b[33m'}\u26A0 Index may be stale. Run \\`kirograph sync\\` to update.${reset}`);\n }\n } else {\n console.log(` ${label('Pending')} ${green}up to date${reset}`);\n }\n\n console.log();\n console.log(section(' Semantic Search'));\n if (stats.embeddingsEnabled) {\n const engineLabel =\n stats.semanticEngine === 'sqlite-vec' ? `sqlite-vec ${dim}(${stats.vecIndexCount} entries in ANN index)${reset}` :\n stats.semanticEngine === 'orama' ? `orama ${dim}(hybrid \u2014 ${stats.vecIndexCount} docs in index)${reset}` :\n stats.semanticEngine === 'pglite' ? `pglite+pgvector ${dim}(hybrid \u2014 ${stats.vecIndexCount} rows in DB)${reset}` :\n stats.semanticEngine === 'lancedb' ? `lancedb ${dim}(${stats.vecIndexCount} entries in ANN index)${reset}` :\n stats.semanticEngine === 'qdrant' ? `qdrant ${dim}(${stats.vecIndexCount} points in collection)${reset}` :\n stats.semanticEngine === 'typesense' ? `typesense ${dim}(${stats.vecIndexCount} documents in collection)${reset}` :\n `in-process cosine`;\n const total = stats.embeddableNodeCount > 0 ? stats.embeddableNodeCount : stats.nodes;\n const displayed = Math.min(stats.embeddingCount, total);\n const coverage = total > 0 ? Math.min(100, Math.round((stats.embeddingCount / total) * 100)) : 0;\n console.log(` ${label('Status')} ${green}${bold}enabled${reset}`);\n console.log(` ${label('Model')} ${value(stats.embeddingModel)}`);\n console.log(` ${label('Engine')} ${violet}${engineLabel}${reset}`);\n if (stats.engineFallback) {\n console.log(` ${'\\x1b[33m'}\u26A0 engine fallback: ${stats.engineFallback}${reset}`);\n }\n console.log(` ${label('Indexed')} ${value(`${displayed} / ${total}`)} ${dim}(${coverage}%)${reset}`);\n } else {\n console.log(` ${label('Status')} ${dim}disabled${reset}`);\n }\n\n // Pattern SAST section\n try {\n const patConfig = await loadConfig(target);\n if (patConfig.enablePatterns) {\n const db2 = cg.getDatabase();\n (db2 as any).applyPatternsSchema?.();\n const rawDb2 = db2.getRawDb();\n const tableExists = rawDb2.get(\"SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'\");\n if (tableExists) {\n const matchCount = (rawDb2.get('SELECT COUNT(*) as cnt FROM pattern_matches') as any)?.cnt ?? 0;\n const fileCount = (rawDb2.get('SELECT COUNT(DISTINCT file_path) as cnt FROM pattern_matches') as any)?.cnt ?? 0;\n const ruleCount = (rawDb2.get('SELECT COUNT(DISTINCT pattern_id) as cnt FROM pattern_matches') as any)?.cnt ?? 0;\n console.log();\n console.log(section(' Patterns'));\n console.log(` ${label('Status')} ${green}${bold}enabled${reset}`);\n if (matchCount > 0) {\n console.log(` ${label('Matches')} ${value(String(matchCount))} ${dim}across ${fileCount} files, ${ruleCount} rules triggered${reset}`);\n } else {\n console.log(` ${label('Matches')} ${dim}none yet \u2014 run kirograph index${reset}`);\n }\n } else {\n console.log();\n console.log(section(' Patterns'));\n console.log(` ${label('Status')} ${green}${bold}enabled${reset} ${dim}(not yet indexed \u2014 run kirograph index)${reset}`);\n }\n }\n } catch { /* non-critical */ }\n\n // Security stats (conditional on enableSecurity)\n try {\n const config = await loadConfig(target);\n if (config.enableSecurity) {\n const db = cg.getDatabase();\n db.applySecuritySchema();\n const rawDb = db.getRawDb();\n\n const depCount: number = rawDb.get('SELECT COUNT(*) as cnt FROM sec_dependencies')?.cnt ?? 0;\n const vulnCount: number = rawDb.get('SELECT COUNT(*) as cnt FROM sec_vulnerabilities')?.cnt ?? 0;\n const affectedCount: number = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'affected'\")?.cnt ?? 0;\n const notAffectedCount: number = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'not_affected'\")?.cnt ?? 0;\n const investigatingCount: number = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'under_investigation'\")?.cnt ?? 0;\n const staleCount: number = rawDb.get('SELECT COUNT(*) as cnt FROM sec_dependencies WHERE vuln_data_stale = 1')?.cnt ?? 0;\n\n console.log();\n console.log(section(' \uD83D\uDD12 Security'));\n console.log(` ${label('Dependencies')} ${value(String(depCount))}`);\n console.log(` ${label('Vulnerabilities')} ${value(String(vulnCount))}`);\n\n if (vulnCount > 0) {\n const affectedLabel = affectedCount > 0\n ? `${'\\x1b[31m'}${affectedCount} affected${reset}`\n : `${dim}0 affected${reset}`;\n console.log(` ${label('Affected')} ${affectedLabel}`);\n console.log(` ${label('Not Affected')} ${dim}${notAffectedCount}${reset}`);\n console.log(` ${label('Investigating')} ${dim}${investigatingCount}${reset}`);\n }\n\n if (staleCount > 0) {\n console.log(` ${'\\x1b[33m'}\u26A0 ${staleCount} dependenc${staleCount === 1 ? 'y has' : 'ies have'} stale vulnerability data. Run \\`kirograph vulns --refresh\\` to update.${reset}`);\n }\n }\n } catch { /* non-critical */ }\n\n console.log();\n cg.close();\n });\n}\n\nasync function showIntegrations(projectRoot: string): Promise<void> {\n const fs = await import('fs');\n const { detectPlatforms } = await Promise.resolve().then(() => require('../installer/detect.js'));\n const { readJson, KIROGRAPH_SERVER_NAME } = await Promise.resolve().then(() => require('../installer/common.js'));\n\n const detected = detectPlatforms(projectRoot);\n const home = process.env.HOME || process.env.USERPROFILE || '';\n\n // Map of target \u2192 config path to check if kirograph is configured\n const configChecks: Record<string, { path: string; key: string }> = {\n 'kiro': { path: path.join(projectRoot, '.kiro', 'settings', 'mcp.json'), key: 'mcpServers' },\n 'claude': { path: path.join(projectRoot, '.mcp.json'), key: 'mcpServers' },\n 'cursor': { path: path.join(projectRoot, '.cursor', 'mcp.json'), key: 'mcpServers' },\n 'windsurf': { path: path.join(home, '.codeium', 'windsurf', 'mcp_config.json'), key: 'mcpServers' },\n 'codex': { path: path.join(projectRoot, '.codex', 'hooks.json'), key: 'hooks' },\n 'copilot': { path: path.join(projectRoot, '.vscode', 'mcp.json'), key: 'servers' },\n 'copilot-cli': { path: path.join(home, '.copilot', 'mcp-config.json'), key: 'servers' },\n 'gemini-cli': { path: path.join(projectRoot, '.gemini', 'settings.json'), key: 'mcpServers' },\n 'continue': { path: path.join(projectRoot, '.continue', 'mcpServers', 'kirograph.json'), key: 'mcpServers' },\n 'opencode': { path: path.join(projectRoot, '.opencode.json'), key: 'mcp' },\n 'antigravity': { path: path.join(home, '.gemini', 'antigravity', 'mcp_config.json'), key: 'mcpServers' },\n 'roo': { path: path.join(projectRoot, '.roo', 'mcp.json'), key: 'mcpServers' },\n 'warp': { path: path.join(projectRoot, '.warp', '.mcp.json'), key: 'mcpServers' },\n 'trae': { path: path.join(projectRoot, '.trae', 'mcp.json'), key: 'mcpServers' },\n 'amp': { path: path.join(projectRoot, '.amp', 'config.json'), key: 'mcpServers' },\n 'cline': { path: path.join(projectRoot, '.cline', 'mcp_settings.json'), key: 'mcpServers' },\n 'qoder': { path: path.join(projectRoot, '.qoder', 'mcp.json'), key: 'mcpServers' },\n 'qwen': { path: path.join(home, '.qwen', 'settings.json'), key: 'mcpServers' },\n };\n\n function isConfigured(target: string): boolean {\n const check = configChecks[target];\n if (!check) return false;\n if (!fs.existsSync(check.path)) return false;\n const config = readJson(check.path);\n const container = config[check.key];\n if (!container) return false;\n if (typeof container === 'object' && !Array.isArray(container)) {\n return KIROGRAPH_SERVER_NAME in container;\n }\n return false;\n }\n\n const configured = detected.filter(d => isConfigured(d.target));\n const notConfigured = detected.filter(d => !isConfigured(d.target));\n\n console.log();\n console.log(section(' Integrations'));\n console.log();\n\n if (configured.length > 0) {\n console.log(` ${label('Configured:')}`);\n for (const d of configured) {\n const check = configChecks[d.target];\n const configPath = check ? check.path.replace(projectRoot, '.').replace(home, '~') : '';\n console.log(` ${green}\u2713${reset} ${d.label.padEnd(20)} ${dim}${configPath}${reset}`);\n }\n }\n\n if (notConfigured.length > 0) {\n if (configured.length > 0) console.log();\n console.log(` ${label('Detected but not configured:')}`);\n for (const d of notConfigured) {\n const check = configChecks[d.target];\n const configPath = check ? check.path.replace(projectRoot, '.').replace(home, '~') : '';\n console.log(` ${dim}\u25CB${reset} ${d.label.padEnd(20)} ${dim}${configPath}${reset}`);\n }\n console.log();\n console.log(` ${dim}Run \\`kirograph install\\` to configure detected platforms.${reset}`);\n }\n\n if (detected.length === 0) {\n console.log(` ${dim}No AI coding platforms detected.${reset}`);\n }\n\n console.log();\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,WAAsB;AACtB,gBAAoF;AACpF,oBAA2B;
|
|
4
|
+
"sourcesContent": ["import { Command } from 'commander';\nimport * as path from 'path';\nimport { dim, reset, violet, bold, green, label, value, section, renderTable } from '../ui';\nimport { loadConfig } from '../../config';\nimport { readTurboQuantStats } from '../../vectors/turboquant-index';\n\nexport function register(program: Command): void {\n program\n .command('status [projectPath]')\n .description('Show index statistics')\n .option('--integrations', 'Show detected and configured platforms')\n .action(async (projectPath: string | undefined, opts: { integrations?: boolean }) => {\n const target = path.resolve(projectPath ?? process.cwd());\n\n if (opts.integrations) {\n await showIntegrations(target);\n return;\n }\n\n const KiroGraph = (await Promise.resolve().then(() => require('../../index.js'))).default;\n const cg = await KiroGraph.open(target);\n const stats = await cg.getStats();\n\n console.log();\n console.log(section(' Graph'));\n console.log(` ${label('Files')} ${value(String(stats.files))}`);\n console.log(` ${label('Symbols')} ${value(String(stats.nodes))}`);\n console.log(` ${label('Edges')} ${value(String(stats.edges))}`);\n\n if (stats.frameworks.length > 0) {\n console.log(` ${label('Frameworks')} ${value(stats.frameworks.join(', '))}`);\n }\n\n const kindEntries = Object.entries(stats.nodesByKind).sort((a, b) => b[1] - a[1]);\n if (kindEntries.length > 0) {\n console.log(`\\n ${label('By kind')}`);\n console.log(renderTable(kindEntries.map(([k, v]) => [k, String(v)])));\n }\n\n const langEntries = Object.entries(stats.filesByLanguage ?? {}).sort((a, b) => b[1] - a[1]);\n if (langEntries.length > 0) {\n console.log(`\\n ${label('By language')}`);\n console.log(renderTable(langEntries.map(([k, v]) => [k, String(v)])));\n }\n\n // Sync state\n const threshold = stats.syncWarningThreshold ?? 10;\n const pendingFiles: number = stats.pendingFiles ?? 0;\n const syncRunning: boolean = stats.syncRunning ?? false;\n console.log();\n console.log(section(' Sync'));\n if (syncRunning) {\n console.log(` ${'\\x1b[33m'}\u26A0 Sync is currently running in the background.${reset}`);\n } else {\n console.log(` ${label('Status')} ${dim}idle${reset}`);\n }\n if (pendingFiles > 0) {\n const warn = threshold > 0 && pendingFiles >= threshold;\n const pendingLabel = warn ? `${'\\x1b[33m'}${pendingFiles} files pending${reset}` : `${dim}${pendingFiles} files pending${reset}`;\n console.log(` ${label('Pending')} ${pendingLabel}`);\n if (warn) {\n console.log(` ${'\\x1b[33m'}\u26A0 Index may be stale. Run \\`kirograph sync\\` to update.${reset}`);\n }\n } else {\n console.log(` ${label('Pending')} ${green}up to date${reset}`);\n }\n\n console.log();\n console.log(section(' Semantic Search'));\n if (stats.embeddingsEnabled) {\n const tqStats = stats.semanticEngine === 'turboquant'\n ? readTurboQuantStats(path.join(target, '.kirograph'))\n : null;\n const engineLabel =\n stats.semanticEngine === 'turboquant' ? `turboquant ${dim}(${stats.vecIndexCount} entries \u00B7 ${tqStats ? `${tqStats.bits} bits \u00B7 ${tqStats.compressionRatio.toFixed(1)}\u00D7 compression` : 'not yet indexed'})${reset}` :\n stats.semanticEngine === 'sqlite-vec' ? `sqlite-vec ${dim}(${stats.vecIndexCount} entries in ANN index)${reset}` :\n stats.semanticEngine === 'orama' ? `orama ${dim}(hybrid \u2014 ${stats.vecIndexCount} docs in index)${reset}` :\n stats.semanticEngine === 'pglite' ? `pglite+pgvector ${dim}(hybrid \u2014 ${stats.vecIndexCount} rows in DB)${reset}` :\n stats.semanticEngine === 'lancedb' ? `lancedb ${dim}(${stats.vecIndexCount} entries in ANN index)${reset}` :\n stats.semanticEngine === 'qdrant' ? `qdrant ${dim}(${stats.vecIndexCount} points in collection)${reset}` :\n stats.semanticEngine === 'typesense' ? `typesense ${dim}(${stats.vecIndexCount} documents in collection)${reset}` :\n stats.semanticEngine === 'turbovec' ? `turbovec ${dim}(${stats.vecIndexCount} entries \u00B7 ${stats.turbovecBits ?? 4} bits \u00B7 Rust/SIMD)${reset}` :\n `in-process cosine`;\n const total = stats.embeddableNodeCount > 0 ? stats.embeddableNodeCount : stats.nodes;\n const displayed = Math.min(stats.embeddingCount, total);\n const coverage = total > 0 ? Math.min(100, Math.round((stats.embeddingCount / total) * 100)) : 0;\n console.log(` ${label('Status')} ${green}${bold}enabled${reset}`);\n console.log(` ${label('Model')} ${value(stats.embeddingModel)}`);\n console.log(` ${label('Engine')} ${violet}${engineLabel}${reset}`);\n if (stats.engineFallback) {\n console.log(` ${'\\x1b[33m'}\u26A0 engine fallback: ${stats.engineFallback}${reset}`);\n }\n console.log(` ${label('Indexed')} ${value(`${displayed} / ${total}`)} ${dim}(${coverage}%)${reset}`);\n if (tqStats) {\n const rawMB = (tqStats.rawBytes / 1_048_576).toFixed(1);\n const compMB = (tqStats.actualBytes / 1_048_576).toFixed(1);\n const savedMB = (tqStats.savedBytes / 1_048_576).toFixed(1);\n console.log(` ${label('Raw size')} ${dim}${rawMB} MB \u2192 compressed ${compMB} MB (${savedMB} MB saved)${reset}`);\n if (tqStats.memEnabled && tqStats.memCount > 0) {\n const mRawMB = (tqStats.memRawBytes / 1_048_576).toFixed(1);\n const mCompMB = (tqStats.memActualBytes / 1_048_576).toFixed(1);\n console.log(` ${label('Memory')} ${dim}${tqStats.memCount} observations \u2192 ${mRawMB} MB \u2192 ${mCompMB} MB${reset}`);\n }\n if (tqStats.docsEnabled && tqStats.docsCount > 0) {\n const dRawMB = (tqStats.docsRawBytes / 1_048_576).toFixed(1);\n const dCompMB = (tqStats.docsActualBytes / 1_048_576).toFixed(1);\n console.log(` ${label('Docs')} ${dim}${tqStats.docsCount} sections \u2192 ${dRawMB} MB \u2192 ${dCompMB} MB${reset}`);\n }\n const totalSaved = tqStats.savedBytes + (tqStats.memRawBytes - tqStats.memActualBytes) + (tqStats.docsRawBytes - tqStats.docsActualBytes);\n if (totalSaved > 0) {\n console.log(` ${label('Total RAM')} ${green}${(totalSaved / 1_048_576).toFixed(1)} MB saved${reset} ${dim}(TurboQuant compression)${reset}`);\n }\n }\n } else {\n console.log(` ${label('Status')} ${dim}disabled${reset}`);\n }\n\n // Pattern SAST section\n try {\n const patConfig = await loadConfig(target);\n if (patConfig.enablePatterns) {\n const db2 = cg.getDatabase();\n (db2 as any).applyPatternsSchema?.();\n const rawDb2 = db2.getRawDb();\n const tableExists = rawDb2.get(\"SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'\");\n if (tableExists) {\n const matchCount = (rawDb2.get('SELECT COUNT(*) as cnt FROM pattern_matches') as any)?.cnt ?? 0;\n const fileCount = (rawDb2.get('SELECT COUNT(DISTINCT file_path) as cnt FROM pattern_matches') as any)?.cnt ?? 0;\n const ruleCount = (rawDb2.get('SELECT COUNT(DISTINCT pattern_id) as cnt FROM pattern_matches') as any)?.cnt ?? 0;\n console.log();\n console.log(section(' Patterns'));\n console.log(` ${label('Status')} ${green}${bold}enabled${reset}`);\n if (matchCount > 0) {\n console.log(` ${label('Matches')} ${value(String(matchCount))} ${dim}across ${fileCount} files, ${ruleCount} rules triggered${reset}`);\n } else {\n console.log(` ${label('Matches')} ${dim}none yet \u2014 run kirograph index${reset}`);\n }\n } else {\n console.log();\n console.log(section(' Patterns'));\n console.log(` ${label('Status')} ${green}${bold}enabled${reset} ${dim}(not yet indexed \u2014 run kirograph index)${reset}`);\n }\n }\n } catch { /* non-critical */ }\n\n // Security stats (conditional on enableSecurity)\n try {\n const config = await loadConfig(target);\n if (config.enableSecurity) {\n const db = cg.getDatabase();\n db.applySecuritySchema();\n const rawDb = db.getRawDb();\n\n const depCount: number = rawDb.get('SELECT COUNT(*) as cnt FROM sec_dependencies')?.cnt ?? 0;\n const vulnCount: number = rawDb.get('SELECT COUNT(*) as cnt FROM sec_vulnerabilities')?.cnt ?? 0;\n const affectedCount: number = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'affected'\")?.cnt ?? 0;\n const notAffectedCount: number = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'not_affected'\")?.cnt ?? 0;\n const investigatingCount: number = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'under_investigation'\")?.cnt ?? 0;\n const staleCount: number = rawDb.get('SELECT COUNT(*) as cnt FROM sec_dependencies WHERE vuln_data_stale = 1')?.cnt ?? 0;\n\n console.log();\n console.log(section(' \uD83D\uDD12 Security'));\n console.log(` ${label('Dependencies')} ${value(String(depCount))}`);\n console.log(` ${label('Vulnerabilities')} ${value(String(vulnCount))}`);\n\n if (vulnCount > 0) {\n const affectedLabel = affectedCount > 0\n ? `${'\\x1b[31m'}${affectedCount} affected${reset}`\n : `${dim}0 affected${reset}`;\n console.log(` ${label('Affected')} ${affectedLabel}`);\n console.log(` ${label('Not Affected')} ${dim}${notAffectedCount}${reset}`);\n console.log(` ${label('Investigating')} ${dim}${investigatingCount}${reset}`);\n }\n\n if (staleCount > 0) {\n console.log(` ${'\\x1b[33m'}\u26A0 ${staleCount} dependenc${staleCount === 1 ? 'y has' : 'ies have'} stale vulnerability data. Run \\`kirograph vulns --refresh\\` to update.${reset}`);\n }\n }\n } catch { /* non-critical */ }\n\n console.log();\n cg.close();\n });\n}\n\nasync function showIntegrations(projectRoot: string): Promise<void> {\n const fs = await import('fs');\n const { detectPlatforms } = await Promise.resolve().then(() => require('../installer/detect.js'));\n const { readJson, KIROGRAPH_SERVER_NAME } = await Promise.resolve().then(() => require('../installer/common.js'));\n\n const detected = detectPlatforms(projectRoot);\n const home = process.env.HOME || process.env.USERPROFILE || '';\n\n // Map of target \u2192 config path to check if kirograph is configured\n const configChecks: Record<string, { path: string; key: string }> = {\n 'kiro': { path: path.join(projectRoot, '.kiro', 'settings', 'mcp.json'), key: 'mcpServers' },\n 'claude': { path: path.join(projectRoot, '.mcp.json'), key: 'mcpServers' },\n 'cursor': { path: path.join(projectRoot, '.cursor', 'mcp.json'), key: 'mcpServers' },\n 'windsurf': { path: path.join(home, '.codeium', 'windsurf', 'mcp_config.json'), key: 'mcpServers' },\n 'codex': { path: path.join(projectRoot, '.codex', 'hooks.json'), key: 'hooks' },\n 'copilot': { path: path.join(projectRoot, '.vscode', 'mcp.json'), key: 'servers' },\n 'copilot-cli': { path: path.join(home, '.copilot', 'mcp-config.json'), key: 'servers' },\n 'gemini-cli': { path: path.join(projectRoot, '.gemini', 'settings.json'), key: 'mcpServers' },\n 'continue': { path: path.join(projectRoot, '.continue', 'mcpServers', 'kirograph.json'), key: 'mcpServers' },\n 'opencode': { path: path.join(projectRoot, '.opencode.json'), key: 'mcp' },\n 'antigravity': { path: path.join(home, '.gemini', 'antigravity', 'mcp_config.json'), key: 'mcpServers' },\n 'roo': { path: path.join(projectRoot, '.roo', 'mcp.json'), key: 'mcpServers' },\n 'warp': { path: path.join(projectRoot, '.warp', '.mcp.json'), key: 'mcpServers' },\n 'trae': { path: path.join(projectRoot, '.trae', 'mcp.json'), key: 'mcpServers' },\n 'amp': { path: path.join(projectRoot, '.amp', 'config.json'), key: 'mcpServers' },\n 'cline': { path: path.join(projectRoot, '.cline', 'mcp_settings.json'), key: 'mcpServers' },\n 'qoder': { path: path.join(projectRoot, '.qoder', 'mcp.json'), key: 'mcpServers' },\n 'qwen': { path: path.join(home, '.qwen', 'settings.json'), key: 'mcpServers' },\n };\n\n function isConfigured(target: string): boolean {\n const check = configChecks[target];\n if (!check) return false;\n if (!fs.existsSync(check.path)) return false;\n const config = readJson(check.path);\n const container = config[check.key];\n if (!container) return false;\n if (typeof container === 'object' && !Array.isArray(container)) {\n return KIROGRAPH_SERVER_NAME in container;\n }\n return false;\n }\n\n const configured = detected.filter(d => isConfigured(d.target));\n const notConfigured = detected.filter(d => !isConfigured(d.target));\n\n console.log();\n console.log(section(' Integrations'));\n console.log();\n\n if (configured.length > 0) {\n console.log(` ${label('Configured:')}`);\n for (const d of configured) {\n const check = configChecks[d.target];\n const configPath = check ? check.path.replace(projectRoot, '.').replace(home, '~') : '';\n console.log(` ${green}\u2713${reset} ${d.label.padEnd(20)} ${dim}${configPath}${reset}`);\n }\n }\n\n if (notConfigured.length > 0) {\n if (configured.length > 0) console.log();\n console.log(` ${label('Detected but not configured:')}`);\n for (const d of notConfigured) {\n const check = configChecks[d.target];\n const configPath = check ? check.path.replace(projectRoot, '.').replace(home, '~') : '';\n console.log(` ${dim}\u25CB${reset} ${d.label.padEnd(20)} ${dim}${configPath}${reset}`);\n }\n console.log();\n console.log(` ${dim}Run \\`kirograph install\\` to configure detected platforms.${reset}`);\n }\n\n if (detected.length === 0) {\n console.log(` ${dim}No AI coding platforms detected.${reset}`);\n }\n\n console.log();\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -63,7 +63,7 @@ async function promptConfigOptions(rl) {
|
|
|
63
63
|
"Semantic embeddings (similarity search):",
|
|
64
64
|
"Enables natural-language code search via vector embeddings. A local model (~130MB) is downloaded on first use."
|
|
65
65
|
);
|
|
66
|
-
const patch = { enableEmbeddings, useVecIndex: false, semanticEngine: "cosine", typesenseDashboard: false, qdrantDashboard: false, extractDocstrings: true, trackCallSites: true, enableArchitecture: false, cavemanMode: "off", shellCompressionLevel: "normal", enableMemory: false, enableWatchmen: false, watchmenThreshold: 5, watchmenSynthesisMode: "local", watchmenLocalModel: "onnx-community/gemma-4-E4B-it-ONNX", enableDocs: false, docsContextLimit: 0, enableData: false, dataContextLimit: 0, enableSecurity: false, enablePatterns: false };
|
|
66
|
+
const patch = { enableEmbeddings, useVecIndex: false, semanticEngine: "cosine", turboquantMemDocs: false, turboquantBits: 3, turbovecMemDocs: false, turbovecBits: 4, typesenseDashboard: false, qdrantDashboard: false, extractDocstrings: true, trackCallSites: true, enableArchitecture: false, cavemanMode: "off", shellCompressionLevel: "normal", enableMemory: false, enableWatchmen: false, watchmenThreshold: 5, watchmenSynthesisMode: "local", watchmenLocalModel: "onnx-community/gemma-4-E4B-it-ONNX", enableDocs: false, docsContextLimit: 0, enableData: false, dataContextLimit: 0, enableSecurity: false, enablePatterns: false };
|
|
67
67
|
if (enableEmbeddings) {
|
|
68
68
|
const modelChoice = await (0, import_prompts.arrowSelect)(
|
|
69
69
|
rl,
|
|
@@ -103,6 +103,8 @@ async function promptConfigOptions(rl) {
|
|
|
103
103
|
patch.embeddingDim = embeddingDim;
|
|
104
104
|
const semanticEngine = await (0, import_prompts.arrowSelect)(rl, "Vector search engine:", [
|
|
105
105
|
{ value: "cosine", label: "cosine", description: "In-process cosine similarity. No extra deps. Best for small/medium projects." },
|
|
106
|
+
{ value: "turboquant", label: "turboquant", description: "ANN index, zero native deps. Compresses embeddings 20\u201330\xD7 (Google TurboQuant). ANN without native binaries \u2014 ideal for CI, ARM, restricted envs. Optional: npm install turboquant-js." },
|
|
107
|
+
{ value: "turbovec", label: "turbovec", description: "ANN search via Rust/SIMD (napi-rs). Same TurboQuant algorithm but NEON on ARM and AVX-512BW on x86 \u2014 faster than turboquant-js at the cost of a one-time Rust build. Requires Rust toolchain. Build: cd native/turbovec-node && npm install && npm run build." },
|
|
106
108
|
{ value: "sqlite-vec", label: "sqlite-vec", description: "ANN index. Sub-linear search. Best for large codebases. Needs: better-sqlite3, sqlite-vec (native)." },
|
|
107
109
|
{ value: "orama", label: "orama", description: "Hybrid search (full-text + vector). Pure JS. Needs: @orama/orama, @orama/plugin-data-persistence." },
|
|
108
110
|
{ value: "pglite", label: "pglite", description: "Hybrid search via PostgreSQL + pgvector. Exact results. Pure WASM. Needs: @electric-sql/pglite." },
|
|
@@ -112,6 +114,27 @@ async function promptConfigOptions(rl) {
|
|
|
112
114
|
]);
|
|
113
115
|
patch.semanticEngine = semanticEngine;
|
|
114
116
|
patch.useVecIndex = semanticEngine === "sqlite-vec";
|
|
117
|
+
if (semanticEngine === "cosine" || semanticEngine === "turboquant") {
|
|
118
|
+
patch.turboquantMemDocs = await (0, import_prompts.askToggle)(
|
|
119
|
+
rl,
|
|
120
|
+
"TurboQuant for memory & docs search (optional):",
|
|
121
|
+
"Replaces the default linear cosine scan in memory observations and doc sections with a compressed ANN index \u2014 no native deps required. Most useful when you accumulate many observations or large doc sets (1 000+ entries).",
|
|
122
|
+
false
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
if (semanticEngine === "turbovec") {
|
|
126
|
+
patch.turbovecBits = await (0, import_prompts.arrowSelect)(rl, "TurboVec bits per coordinate:", [
|
|
127
|
+
{ value: 4, label: "4 bits (recommended)", description: "Best quality, ~19\xD7 compression vs raw Float32. Default." },
|
|
128
|
+
{ value: 3, label: "3 bits", description: "Balanced \u2014 ~25\xD7 compression, slight quality drop." },
|
|
129
|
+
{ value: 2, label: "2 bits", description: "Highest compression (~38\xD7), lowest accuracy." }
|
|
130
|
+
]);
|
|
131
|
+
patch.turbovecMemDocs = await (0, import_prompts.askToggle)(
|
|
132
|
+
rl,
|
|
133
|
+
"TurboVec for memory & docs search (optional):",
|
|
134
|
+
"Replaces the default linear cosine scan in memory observations and doc sections with the TurboVec ANN index. Requires the addon to be built.",
|
|
135
|
+
false
|
|
136
|
+
);
|
|
137
|
+
}
|
|
115
138
|
if (semanticEngine === "typesense") {
|
|
116
139
|
patch.typesenseDashboard = await (0, import_prompts.askToggle)(
|
|
117
140
|
rl,
|
|
@@ -200,6 +223,12 @@ async function promptConfigOptions(rl) {
|
|
|
200
223
|
"Required for .parquet files. CSV/TSV/JSONL/JSON are always supported without extra deps.",
|
|
201
224
|
false
|
|
202
225
|
);
|
|
226
|
+
patch.dataInstallPdf = await (0, import_prompts.askToggle)(
|
|
227
|
+
rl,
|
|
228
|
+
"Install PDF support (@firecrawl/pdf-inspector package)?",
|
|
229
|
+
"Required for .pdf files. Rust/NAPI binary \u2014 prebuilts for linux-x64 and macOS ARM64.",
|
|
230
|
+
false
|
|
231
|
+
);
|
|
203
232
|
const contextChoice = await (0, import_prompts.arrowSelect)(rl, "Include dataset schemas in kirograph_context results?", [
|
|
204
233
|
{ value: 0, label: "0 (disabled)", description: "Data stays separate \u2014 use kirograph_data_* tools explicitly (recommended)" },
|
|
205
234
|
{ value: 2, label: "2 datasets", description: "Include up to 2 relevant dataset schemas in context results" },
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/bin/installer/config-prompt.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * KiroGraph Installer \u2014 configuration prompting\n */\n\nimport * as readline from 'readline';\nimport { KiroGraphConfig } from '../../config';\ntype CavemanMode = 'lite' | 'full' | 'ultra';\nimport { ask, askToggle, arrowSelect, printSection, printSeparator, dim, reset, violet } from './prompts';\nexport type ConfigPatch = Pick<KiroGraphConfig, 'enableEmbeddings' | 'useVecIndex' | 'semanticEngine' | 'typesenseDashboard' | 'qdrantDashboard' | 'extractDocstrings' | 'trackCallSites' | 'enableArchitecture' | 'cavemanMode' | 'shellCompressionLevel' | 'enableMemory' | 'enableWatchmen' | 'watchmenThreshold' | 'watchmenSynthesisMode' | 'watchmenLocalModel' | 'enableDocs' | 'docsContextLimit' | 'enableData' | 'dataContextLimit' | 'enableSecurity' | 'enablePatterns'> & { embeddingModel?: string; embeddingDim?: number };\nexport type SemanticEngine = KiroGraphConfig['semanticEngine'];\n\nexport const DEFAULT_EMBEDDING_MODEL = 'nomic-ai/nomic-embed-text-v1.5';\n\n/** Well-known embedding models with their output dimensions. */\nconst PRESET_MODELS = [\n {\n value: 'nomic-ai/nomic-embed-text-v1.5',\n label: 'nomic-embed-text-v1.5',\n dim: 768,\n description: '768-dim \u00B7 ~130MB \u00B7 Best quality for code search (recommended)',\n },\n {\n value: 'onnx-community/embeddinggemma-300m-ONNX',\n label: 'embeddinggemma-300m',\n dim: 768,\n description: '768-dim \u00B7 ~300MB \u00B7 Google Gemma-based, multilingual, 2048-token context',\n },\n {\n value: 'Xenova/all-MiniLM-L6-v2',\n label: 'all-MiniLM-L6-v2',\n dim: 384,\n description: '384-dim \u00B7 ~23MB \u00B7 Fast and lightweight, lower accuracy',\n },\n {\n value: 'BAAI/bge-base-en-v1.5',\n label: 'bge-base-en-v1.5',\n dim: 768,\n description: '768-dim \u00B7 ~110MB \u00B7 Strong general-purpose alternative to nomic',\n },\n {\n value: '__other__',\n label: 'Other',\n dim: 768,\n description: 'Enter a custom HuggingFace model ID and embedding dimension',\n },\n] as const;\n\nexport async function promptConfigOptions(rl: readline.Interface): Promise<ConfigPatch> {\n // \u2500\u2500 Semantic Search \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83D\uDD0D', 'Semantic Search');\n\n const enableEmbeddings = await askToggle(\n rl,\n 'Semantic embeddings (similarity search):',\n 'Enables natural-language code search via vector embeddings. A local model (~130MB) is downloaded on first use.',\n );\n\n const patch: ConfigPatch = { enableEmbeddings, useVecIndex: false, semanticEngine: 'cosine', typesenseDashboard: false, qdrantDashboard: false, extractDocstrings: true, trackCallSites: true, enableArchitecture: false, cavemanMode: 'off', shellCompressionLevel: 'normal', enableMemory: false, enableWatchmen: false, watchmenThreshold: 5, watchmenSynthesisMode: 'local', watchmenLocalModel: 'onnx-community/gemma-4-E4B-it-ONNX', enableDocs: false, docsContextLimit: 0, enableData: false, dataContextLimit: 0, enableSecurity: false, enablePatterns: false };\n\n if (enableEmbeddings) {\n // \u2500\u2500 Model selection \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\u2500\u2500\u2500\u2500\u2500\u2500\n const modelChoice = await arrowSelect<string>(\n rl,\n 'Embedding model:',\n PRESET_MODELS.map(m => ({ value: m.value, label: m.label, description: m.description })),\n );\n\n let embeddingModel: string;\n let embeddingDim: number;\n\n if (modelChoice === '__other__') {\n console.log(`\\n ${dim}Enter a HuggingFace model ID in the format org/model-name.${reset}`);\n while (true) {\n const raw = (await ask(rl, ` ${violet}Model identifier:${reset} `)).trim();\n if (raw.includes('/')) { embeddingModel = raw; break; }\n console.log(` Expected a HuggingFace model ID in the format org/model-name (e.g. nomic-ai/nomic-embed-text-v1.5).`);\n }\n console.log(`\\n ${dim}Enter the embedding output dimension for this model (check the model card on HuggingFace).${reset}`);\n while (true) {\n const raw = (await ask(rl, ` ${violet}Embedding dimension (e.g. 768, 384):${reset} `)).trim();\n const n = parseInt(raw, 10);\n if (!isNaN(n) && n > 0) { embeddingDim = n; break; }\n console.log(` Expected a positive integer (e.g. 768, 384, 1536).`);\n }\n } else {\n const preset = PRESET_MODELS.find(m => m.value === modelChoice)!;\n embeddingModel = preset.value;\n embeddingDim = preset.dim;\n }\n\n patch.embeddingModel = embeddingModel;\n patch.embeddingDim = embeddingDim;\n\n // \u2500\u2500 Engine selection \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\u2500\u2500\u2500\u2500\u2500\n const semanticEngine = await arrowSelect<SemanticEngine>(rl, 'Vector search engine:', [\n { value: 'cosine', label: 'cosine', description: 'In-process cosine similarity. No extra deps. Best for small/medium projects.' },\n { value: 'sqlite-vec', label: 'sqlite-vec', description: 'ANN index. Sub-linear search. Best for large codebases. Needs: better-sqlite3, sqlite-vec (native).' },\n { value: 'orama', label: 'orama', description: 'Hybrid search (full-text + vector). Pure JS. Needs: @orama/orama, @orama/plugin-data-persistence.' },\n { value: 'pglite', label: 'pglite', description: 'Hybrid search via PostgreSQL + pgvector. Exact results. Pure WASM. Needs: @electric-sql/pglite.' },\n { value: 'lancedb', label: 'lancedb', description: 'ANN search via LanceDB (Apache Lance columnar format). Pure JS. Needs: @lancedb/lancedb.' },\n { value: 'qdrant', label: 'qdrant', description: 'ANN search via Qdrant embedded binary (HNSW index, Cosine). Needs: qdrant-local.' },\n { value: 'typesense', label: 'typesense', description: 'ANN search via Typesense (auto-downloaded binary, HNSW, Cosine). Needs: typesense.' },\n ]);\n patch.semanticEngine = semanticEngine;\n patch.useVecIndex = semanticEngine === 'sqlite-vec';\n\n if (semanticEngine === 'typesense') {\n patch.typesenseDashboard = await askToggle(rl,\n 'Typesense dashboard:',\n 'Serves the Typesense Dashboard locally and opens it in your browser after indexing completes.',\n false,\n );\n }\n\n if (semanticEngine === 'qdrant') {\n patch.qdrantDashboard = await askToggle(rl,\n 'Qdrant dashboard:',\n 'Downloads the Qdrant Web UI (first time only) and opens it in your browser after indexing completes.',\n false,\n );\n }\n }\n\n // \u2500\u2500 Graph Features \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83D\uDCCA', 'Graph Features');\n\n patch.extractDocstrings = await askToggle(rl,\n 'Docstring extraction:',\n 'Enriches symbol metadata and improves context quality. Slightly increases indexing time.',\n );\n\n patch.trackCallSites = await askToggle(rl,\n 'Call site tracking (caller/callee graph):',\n 'Enables kirograph_callers and kirograph_callees MCP tools. Increases index size.',\n );\n\n patch.enableArchitecture = await askToggle(rl,\n 'Architecture analysis (packages + layers):',\n 'Detects packages from manifests and architectural layers. Enables kirograph_architecture, kirograph_coupling, kirograph_package.',\n false,\n );\n\n // \u2500\u2500 Security \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83D\uDD12', 'Security');\n\n patch.enableSecurity = await askToggle(rl,\n 'Security analysis (vulnerability scanning + reachability):',\n 'Scans dependency manifests for known vulnerabilities and performs reachability analysis. Requires Architecture analysis (will be auto-enabled). Enables kirograph_security, kirograph_vulns, kirograph_sbom, kirograph_vex, kirograph_reachability MCP tools.',\n false,\n );\n\n if (patch.enableSecurity && !patch.enableArchitecture) {\n patch.enableArchitecture = true;\n console.log(' \u2139 Architecture analysis auto-enabled (required by Security module)');\n }\n\n // \u2500\u2500 Pattern Matching \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83D\uDD0D', 'Pattern Matching');\n\n patch.enablePatterns = await askToggle(rl,\n 'Precise SAST with ast-grep?',\n 'Runs AST structural pattern matching during indexing using @ast-grep/napi (~15MB native binding). Unlike heuristic symbol-name analysis, matches real code structure \u2014 precise SQL injection, path traversal, eval detection. Requires @ast-grep/napi (will be installed automatically if you answer yes).',\n false,\n );\n\n // \u2500\u2500 Documentation \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83D\uDCD6', 'Documentation');\n\n (patch as any).enableDocs = await askToggle(rl,\n 'Documentation indexing (section-level retrieval):',\n 'Indexes docs by heading structure. Enables kirograph_docs_toc, kirograph_docs_search, kirograph_docs_section, kirograph_docs_outline, kirograph_docs_refs.',\n false,\n );\n\n if ((patch as any).enableDocs) {\n const contextChoice = await arrowSelect<number>(rl, 'Include doc sections in kirograph_context results?', [\n { value: 0, label: '0 (disabled)', description: 'Docs stay separate \u2014 use kirograph_docs_* tools explicitly (recommended)' },\n { value: 3, label: '3 sections', description: 'Include up to 3 relevant doc sections in context results' },\n { value: 5, label: '5 sections', description: 'Include up to 5 relevant doc sections in context results' },\n { value: 10, label: '10 sections', description: 'Include up to 10 relevant doc sections in context results' },\n ]);\n (patch as any).docsContextLimit = contextChoice;\n }\n\n // \u2500\u2500 Data \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83D\uDCCA', 'Data');\n\n (patch as any).enableData = await askToggle(rl,\n 'Tabular data indexing (CSV/TSV/JSONL/JSON/Excel/Parquet):',\n 'Indexes data files for structured querying. Enables kirograph_data_list, kirograph_data_describe, kirograph_data_query, kirograph_data_aggregate, kirograph_data_search.',\n false,\n );\n\n if ((patch as any).enableData) {\n (patch as any).dataInstallExcel = await askToggle(rl,\n 'Install Excel support (xlsx package)?',\n 'Required for .xlsx/.xls files. CSV/TSV/JSONL/JSON are always supported without extra deps.',\n false,\n );\n\n (patch as any).dataInstallParquet = await askToggle(rl,\n 'Install Parquet support (parquetjs-lite package)?',\n 'Required for .parquet files. CSV/TSV/JSONL/JSON are always supported without extra deps.',\n false,\n );\n\n const contextChoice = await arrowSelect<number>(rl, 'Include dataset schemas in kirograph_context results?', [\n { value: 0, label: '0 (disabled)', description: 'Data stays separate \u2014 use kirograph_data_* tools explicitly (recommended)' },\n { value: 2, label: '2 datasets', description: 'Include up to 2 relevant dataset schemas in context results' },\n { value: 5, label: '5 datasets', description: 'Include up to 5 relevant dataset schemas in context results' },\n ]);\n (patch as any).dataContextLimit = contextChoice;\n }\n\n // \u2500\u2500 Agent Behavior \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83E\uDD16', 'Agent Behavior');\n\n const cavemanChoice = await arrowSelect(rl, 'Communication style (caveman mode):', [\n { value: 'off', label: 'off', description: 'Normal responses \u2014 no compression' },\n { value: 'lite', label: 'lite', description: 'Compact, no filler, full sentences' },\n { value: 'full', label: 'full', description: 'Fragments, no articles, short synonyms' },\n { value: 'ultra', label: 'ultra', description: 'Max compression, abbreviations, \u2192 for causality' },\n ]);\n patch.cavemanMode = cavemanChoice as CavemanMode | 'off';\n\n const compressionChoice = await arrowSelect(rl, 'Shell compression (kirograph_exec default level):', [\n { value: 'off', label: 'off', description: 'No compression hook or steering (tool still available)' },\n { value: 'normal', label: 'normal', description: 'Balanced: removes noise, keeps structure (recommended)' },\n { value: 'aggressive', label: 'aggressive', description: 'More compact: groups by category, limits output' },\n { value: 'ultra', label: 'ultra', description: 'Maximum compression: counts and summaries only' },\n ]);\n patch.shellCompressionLevel = compressionChoice as KiroGraphConfig['shellCompressionLevel'];\n\n // \u2500\u2500 Memory \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83E\uDDE0', 'Memory');\n\n patch.enableMemory = await askToggle(rl,\n 'Persistent memory (cross-session observations):',\n 'Stores decisions, errors, and patterns across sessions. Compressed (if caveman is on), linked to code symbols, searchable via kirograph_mem_* tools. Zero LLM tokens on write.',\n false,\n );\n\n if (patch.enableMemory) {\n patch.enableWatchmen = await askToggle(rl,\n 'Watchmen (auto-synthesize workspace briefs from memory):',\n 'When enough observations accumulate (default: 5), synthesizes them into .kiro/steering/kirograph-watchmen.md, CLAUDE.md, AGENTS.md, or the equivalent for your tool.',\n false,\n );\n\n if (patch.enableWatchmen) {\n // \u2500\u2500 Synthesis mode \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\u2500\n const synthesisMode = await arrowSelect<KiroGraphConfig['watchmenSynthesisMode']>(\n rl,\n 'Watchmen synthesis mode:',\n [\n {\n value: 'local',\n label: 'Local model',\n description: 'Runs a local HuggingFace model via @huggingface/transformers. Zero API cost, no data leaves your machine. Model downloaded once to ~/.kirograph/models/. Works for all tools via runCommand hook.',\n },\n {\n value: 'agent',\n label: 'Active agent',\n description: '\u26A0 Kiro only. Uses the active Kiro agent to synthesize. Consumes API tokens/credits on every synthesis. Not supported for other tools.',\n },\n ],\n );\n patch.watchmenSynthesisMode = synthesisMode;\n\n if (synthesisMode === 'local') {\n // \u2500\u2500 Local model selection \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\n const LOCAL_MODELS = [\n {\n value: 'onnx-community/gemma-4-E4B-it-ONNX',\n label: 'Gemma 4 E4B (recommended)',\n description: '~3\u20134 GB \u00B7 Google DeepMind Gemma 4 \u00B7 4.5B params \u00B7 128K context \u00B7 Best quality \u00B7 Apache 2.0',\n },\n {\n value: 'onnx-community/Qwen2.5-1.5B-Instruct',\n label: 'Qwen2.5-1.5B',\n description: '~1.5 GB \u00B7 Lighter option if RAM is limited \u00B7 Acceptable quality',\n },\n {\n value: 'HuggingFaceTB/SmolLM2-1.7B-Instruct',\n label: 'SmolLM2-1.7B',\n description: '~1.7 GB \u00B7 HuggingFace compact model \u00B7 Good at following structured formats',\n },\n {\n value: '__other__',\n label: 'Other',\n description: 'Enter a custom HuggingFace model ID (must have ONNX weights on onnx-community)',\n },\n ] as const;\n\n const modelChoice = await arrowSelect<string>(rl, 'Local synthesis model:', LOCAL_MODELS.map(m => ({ value: m.value, label: m.label, description: m.description })));\n\n if (modelChoice === '__other__') {\n console.log(`\\n ${dim}Enter a HuggingFace model ID (e.g. onnx-community/gemma-4-E4B-it-ONNX).${reset}`);\n while (true) {\n const raw = (await ask(rl, ` ${violet}Model identifier:${reset} `)).trim();\n if (raw.includes('/')) { patch.watchmenLocalModel = raw; break; }\n console.log(` Expected a HuggingFace model ID in the format org/model-name.`);\n }\n } else {\n patch.watchmenLocalModel = modelChoice;\n }\n }\n }\n }\n\n return patch;\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,qBAA8F;AAIvF,MAAM,0BAA0B;AAGvC,MAAM,gBAAgB;AAAA,EACpB;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,KAAK;AAAA,IACL,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,KAAK;AAAA,IACL,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,KAAK;AAAA,IACL,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,KAAK;AAAA,IACL,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,KAAK;AAAA,IACL,aAAa;AAAA,EACf;AACF;AAEA,eAAsB,oBAAoB,IAA8C;AAEtF,mCAAa,aAAM,iBAAiB;AAEpC,QAAM,mBAAmB,UAAM;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,QAAqB,EAAE,kBAAkB,aAAa,OAAO,gBAAgB,UAAU,oBAAoB,OAAO,iBAAiB,OAAO,mBAAmB,MAAM,gBAAgB,MAAM,oBAAoB,OAAO,aAAa,OAAO,uBAAuB,UAAU,cAAc,OAAO,gBAAgB,OAAO,mBAAmB,GAAG,uBAAuB,SAAS,oBAAoB,sCAAsC,YAAY,OAAO,kBAAkB,GAAG,YAAY,OAAO,kBAAkB,GAAG,gBAAgB,OAAO,gBAAgB,MAAM;
|
|
4
|
+
"sourcesContent": ["/**\n * KiroGraph Installer \u2014 configuration prompting\n */\n\nimport * as readline from 'readline';\nimport { KiroGraphConfig } from '../../config';\ntype CavemanMode = 'lite' | 'full' | 'ultra';\nimport { ask, askToggle, arrowSelect, printSection, printSeparator, dim, reset, violet } from './prompts';\nexport type ConfigPatch = Pick<KiroGraphConfig, 'enableEmbeddings' | 'useVecIndex' | 'semanticEngine' | 'turboquantMemDocs' | 'turboquantBits' | 'turbovecMemDocs' | 'turbovecBits' | 'typesenseDashboard' | 'qdrantDashboard' | 'extractDocstrings' | 'trackCallSites' | 'enableArchitecture' | 'cavemanMode' | 'shellCompressionLevel' | 'enableMemory' | 'enableWatchmen' | 'watchmenThreshold' | 'watchmenSynthesisMode' | 'watchmenLocalModel' | 'enableDocs' | 'docsContextLimit' | 'enableData' | 'dataContextLimit' | 'enableSecurity' | 'enablePatterns'> & { embeddingModel?: string; embeddingDim?: number };\nexport type SemanticEngine = KiroGraphConfig['semanticEngine'];\n\nexport const DEFAULT_EMBEDDING_MODEL = 'nomic-ai/nomic-embed-text-v1.5';\n\n/** Well-known embedding models with their output dimensions. */\nconst PRESET_MODELS = [\n {\n value: 'nomic-ai/nomic-embed-text-v1.5',\n label: 'nomic-embed-text-v1.5',\n dim: 768,\n description: '768-dim \u00B7 ~130MB \u00B7 Best quality for code search (recommended)',\n },\n {\n value: 'onnx-community/embeddinggemma-300m-ONNX',\n label: 'embeddinggemma-300m',\n dim: 768,\n description: '768-dim \u00B7 ~300MB \u00B7 Google Gemma-based, multilingual, 2048-token context',\n },\n {\n value: 'Xenova/all-MiniLM-L6-v2',\n label: 'all-MiniLM-L6-v2',\n dim: 384,\n description: '384-dim \u00B7 ~23MB \u00B7 Fast and lightweight, lower accuracy',\n },\n {\n value: 'BAAI/bge-base-en-v1.5',\n label: 'bge-base-en-v1.5',\n dim: 768,\n description: '768-dim \u00B7 ~110MB \u00B7 Strong general-purpose alternative to nomic',\n },\n {\n value: '__other__',\n label: 'Other',\n dim: 768,\n description: 'Enter a custom HuggingFace model ID and embedding dimension',\n },\n] as const;\n\nexport async function promptConfigOptions(rl: readline.Interface): Promise<ConfigPatch> {\n // \u2500\u2500 Semantic Search \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83D\uDD0D', 'Semantic Search');\n\n const enableEmbeddings = await askToggle(\n rl,\n 'Semantic embeddings (similarity search):',\n 'Enables natural-language code search via vector embeddings. A local model (~130MB) is downloaded on first use.',\n );\n\n const patch: ConfigPatch = { enableEmbeddings, useVecIndex: false, semanticEngine: 'cosine', turboquantMemDocs: false, turboquantBits: 3, turbovecMemDocs: false, turbovecBits: 4, typesenseDashboard: false, qdrantDashboard: false, extractDocstrings: true, trackCallSites: true, enableArchitecture: false, cavemanMode: 'off', shellCompressionLevel: 'normal', enableMemory: false, enableWatchmen: false, watchmenThreshold: 5, watchmenSynthesisMode: 'local', watchmenLocalModel: 'onnx-community/gemma-4-E4B-it-ONNX', enableDocs: false, docsContextLimit: 0, enableData: false, dataContextLimit: 0, enableSecurity: false, enablePatterns: false };\n\n if (enableEmbeddings) {\n // \u2500\u2500 Model selection \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\u2500\u2500\u2500\u2500\u2500\u2500\n const modelChoice = await arrowSelect<string>(\n rl,\n 'Embedding model:',\n PRESET_MODELS.map(m => ({ value: m.value, label: m.label, description: m.description })),\n );\n\n let embeddingModel: string;\n let embeddingDim: number;\n\n if (modelChoice === '__other__') {\n console.log(`\\n ${dim}Enter a HuggingFace model ID in the format org/model-name.${reset}`);\n while (true) {\n const raw = (await ask(rl, ` ${violet}Model identifier:${reset} `)).trim();\n if (raw.includes('/')) { embeddingModel = raw; break; }\n console.log(` Expected a HuggingFace model ID in the format org/model-name (e.g. nomic-ai/nomic-embed-text-v1.5).`);\n }\n console.log(`\\n ${dim}Enter the embedding output dimension for this model (check the model card on HuggingFace).${reset}`);\n while (true) {\n const raw = (await ask(rl, ` ${violet}Embedding dimension (e.g. 768, 384):${reset} `)).trim();\n const n = parseInt(raw, 10);\n if (!isNaN(n) && n > 0) { embeddingDim = n; break; }\n console.log(` Expected a positive integer (e.g. 768, 384, 1536).`);\n }\n } else {\n const preset = PRESET_MODELS.find(m => m.value === modelChoice)!;\n embeddingModel = preset.value;\n embeddingDim = preset.dim;\n }\n\n patch.embeddingModel = embeddingModel;\n patch.embeddingDim = embeddingDim;\n\n // \u2500\u2500 Engine selection \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\u2500\u2500\u2500\u2500\u2500\n const semanticEngine = await arrowSelect<SemanticEngine>(rl, 'Vector search engine:', [\n { value: 'cosine', label: 'cosine', description: 'In-process cosine similarity. No extra deps. Best for small/medium projects.' },\n { value: 'turboquant', label: 'turboquant', description: 'ANN index, zero native deps. Compresses embeddings 20\u201330\u00D7 (Google TurboQuant). ANN without native binaries \u2014 ideal for CI, ARM, restricted envs. Optional: npm install turboquant-js.' },\n { value: 'turbovec', label: 'turbovec', description: 'ANN search via Rust/SIMD (napi-rs). Same TurboQuant algorithm but NEON on ARM and AVX-512BW on x86 \u2014 faster than turboquant-js at the cost of a one-time Rust build. Requires Rust toolchain. Build: cd native/turbovec-node && npm install && npm run build.' },\n { value: 'sqlite-vec', label: 'sqlite-vec', description: 'ANN index. Sub-linear search. Best for large codebases. Needs: better-sqlite3, sqlite-vec (native).' },\n { value: 'orama', label: 'orama', description: 'Hybrid search (full-text + vector). Pure JS. Needs: @orama/orama, @orama/plugin-data-persistence.' },\n { value: 'pglite', label: 'pglite', description: 'Hybrid search via PostgreSQL + pgvector. Exact results. Pure WASM. Needs: @electric-sql/pglite.' },\n { value: 'lancedb', label: 'lancedb', description: 'ANN search via LanceDB (Apache Lance columnar format). Pure JS. Needs: @lancedb/lancedb.' },\n { value: 'qdrant', label: 'qdrant', description: 'ANN search via Qdrant embedded binary (HNSW index, Cosine). Needs: qdrant-local.' },\n { value: 'typesense', label: 'typesense', description: 'ANN search via Typesense (auto-downloaded binary, HNSW, Cosine). Needs: typesense.' },\n ]);\n patch.semanticEngine = semanticEngine;\n patch.useVecIndex = semanticEngine === 'sqlite-vec';\n\n // TurboQuant for memory & docs: offer when cosine or turboquant is the code-node engine\n if (semanticEngine === 'cosine' || semanticEngine === 'turboquant') {\n patch.turboquantMemDocs = await askToggle(rl,\n 'TurboQuant for memory & docs search (optional):',\n 'Replaces the default linear cosine scan in memory observations and doc sections with a compressed ANN index \u2014 no native deps required. Most useful when you accumulate many observations or large doc sets (1 000+ entries).',\n false,\n );\n }\n\n // TurboVec bit width\n if (semanticEngine === 'turbovec') {\n patch.turbovecBits = await arrowSelect<number>(rl, 'TurboVec bits per coordinate:', [\n { value: 4, label: '4 bits (recommended)', description: 'Best quality, ~19\u00D7 compression vs raw Float32. Default.' },\n { value: 3, label: '3 bits', description: 'Balanced \u2014 ~25\u00D7 compression, slight quality drop.' },\n { value: 2, label: '2 bits', description: 'Highest compression (~38\u00D7), lowest accuracy.' },\n ]);\n patch.turbovecMemDocs = await askToggle(rl,\n 'TurboVec for memory & docs search (optional):',\n 'Replaces the default linear cosine scan in memory observations and doc sections with the TurboVec ANN index. Requires the addon to be built.',\n false,\n );\n }\n\n if (semanticEngine === 'typesense') {\n patch.typesenseDashboard = await askToggle(rl,\n 'Typesense dashboard:',\n 'Serves the Typesense Dashboard locally and opens it in your browser after indexing completes.',\n false,\n );\n }\n\n if (semanticEngine === 'qdrant') {\n patch.qdrantDashboard = await askToggle(rl,\n 'Qdrant dashboard:',\n 'Downloads the Qdrant Web UI (first time only) and opens it in your browser after indexing completes.',\n false,\n );\n }\n }\n\n // \u2500\u2500 Graph Features \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83D\uDCCA', 'Graph Features');\n\n patch.extractDocstrings = await askToggle(rl,\n 'Docstring extraction:',\n 'Enriches symbol metadata and improves context quality. Slightly increases indexing time.',\n );\n\n patch.trackCallSites = await askToggle(rl,\n 'Call site tracking (caller/callee graph):',\n 'Enables kirograph_callers and kirograph_callees MCP tools. Increases index size.',\n );\n\n patch.enableArchitecture = await askToggle(rl,\n 'Architecture analysis (packages + layers):',\n 'Detects packages from manifests and architectural layers. Enables kirograph_architecture, kirograph_coupling, kirograph_package.',\n false,\n );\n\n // \u2500\u2500 Security \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83D\uDD12', 'Security');\n\n patch.enableSecurity = await askToggle(rl,\n 'Security analysis (vulnerability scanning + reachability):',\n 'Scans dependency manifests for known vulnerabilities and performs reachability analysis. Requires Architecture analysis (will be auto-enabled). Enables kirograph_security, kirograph_vulns, kirograph_sbom, kirograph_vex, kirograph_reachability MCP tools.',\n false,\n );\n\n if (patch.enableSecurity && !patch.enableArchitecture) {\n patch.enableArchitecture = true;\n console.log(' \u2139 Architecture analysis auto-enabled (required by Security module)');\n }\n\n // \u2500\u2500 Pattern Matching \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83D\uDD0D', 'Pattern Matching');\n\n patch.enablePatterns = await askToggle(rl,\n 'Precise SAST with ast-grep?',\n 'Runs AST structural pattern matching during indexing using @ast-grep/napi (~15MB native binding). Unlike heuristic symbol-name analysis, matches real code structure \u2014 precise SQL injection, path traversal, eval detection. Requires @ast-grep/napi (will be installed automatically if you answer yes).',\n false,\n );\n\n // \u2500\u2500 Documentation \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83D\uDCD6', 'Documentation');\n\n (patch as any).enableDocs = await askToggle(rl,\n 'Documentation indexing (section-level retrieval):',\n 'Indexes docs by heading structure. Enables kirograph_docs_toc, kirograph_docs_search, kirograph_docs_section, kirograph_docs_outline, kirograph_docs_refs.',\n false,\n );\n\n if ((patch as any).enableDocs) {\n const contextChoice = await arrowSelect<number>(rl, 'Include doc sections in kirograph_context results?', [\n { value: 0, label: '0 (disabled)', description: 'Docs stay separate \u2014 use kirograph_docs_* tools explicitly (recommended)' },\n { value: 3, label: '3 sections', description: 'Include up to 3 relevant doc sections in context results' },\n { value: 5, label: '5 sections', description: 'Include up to 5 relevant doc sections in context results' },\n { value: 10, label: '10 sections', description: 'Include up to 10 relevant doc sections in context results' },\n ]);\n (patch as any).docsContextLimit = contextChoice;\n }\n\n // \u2500\u2500 Data \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83D\uDCCA', 'Data');\n\n (patch as any).enableData = await askToggle(rl,\n 'Tabular data indexing (CSV/TSV/JSONL/JSON/Excel/Parquet):',\n 'Indexes data files for structured querying. Enables kirograph_data_list, kirograph_data_describe, kirograph_data_query, kirograph_data_aggregate, kirograph_data_search.',\n false,\n );\n\n if ((patch as any).enableData) {\n (patch as any).dataInstallExcel = await askToggle(rl,\n 'Install Excel support (xlsx package)?',\n 'Required for .xlsx/.xls files. CSV/TSV/JSONL/JSON are always supported without extra deps.',\n false,\n );\n\n (patch as any).dataInstallParquet = await askToggle(rl,\n 'Install Parquet support (parquetjs-lite package)?',\n 'Required for .parquet files. CSV/TSV/JSONL/JSON are always supported without extra deps.',\n false,\n );\n\n (patch as any).dataInstallPdf = await askToggle(rl,\n 'Install PDF support (@firecrawl/pdf-inspector package)?',\n 'Required for .pdf files. Rust/NAPI binary \u2014 prebuilts for linux-x64 and macOS ARM64.',\n false,\n );\n\n const contextChoice = await arrowSelect<number>(rl, 'Include dataset schemas in kirograph_context results?', [\n { value: 0, label: '0 (disabled)', description: 'Data stays separate \u2014 use kirograph_data_* tools explicitly (recommended)' },\n { value: 2, label: '2 datasets', description: 'Include up to 2 relevant dataset schemas in context results' },\n { value: 5, label: '5 datasets', description: 'Include up to 5 relevant dataset schemas in context results' },\n ]);\n (patch as any).dataContextLimit = contextChoice;\n }\n\n // \u2500\u2500 Agent Behavior \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83E\uDD16', 'Agent Behavior');\n\n const cavemanChoice = await arrowSelect(rl, 'Communication style (caveman mode):', [\n { value: 'off', label: 'off', description: 'Normal responses \u2014 no compression' },\n { value: 'lite', label: 'lite', description: 'Compact, no filler, full sentences' },\n { value: 'full', label: 'full', description: 'Fragments, no articles, short synonyms' },\n { value: 'ultra', label: 'ultra', description: 'Max compression, abbreviations, \u2192 for causality' },\n ]);\n patch.cavemanMode = cavemanChoice as CavemanMode | 'off';\n\n const compressionChoice = await arrowSelect(rl, 'Shell compression (kirograph_exec default level):', [\n { value: 'off', label: 'off', description: 'No compression hook or steering (tool still available)' },\n { value: 'normal', label: 'normal', description: 'Balanced: removes noise, keeps structure (recommended)' },\n { value: 'aggressive', label: 'aggressive', description: 'More compact: groups by category, limits output' },\n { value: 'ultra', label: 'ultra', description: 'Maximum compression: counts and summaries only' },\n ]);\n patch.shellCompressionLevel = compressionChoice as KiroGraphConfig['shellCompressionLevel'];\n\n // \u2500\u2500 Memory \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n printSection('\uD83E\uDDE0', 'Memory');\n\n patch.enableMemory = await askToggle(rl,\n 'Persistent memory (cross-session observations):',\n 'Stores decisions, errors, and patterns across sessions. Compressed (if caveman is on), linked to code symbols, searchable via kirograph_mem_* tools. Zero LLM tokens on write.',\n false,\n );\n\n if (patch.enableMemory) {\n patch.enableWatchmen = await askToggle(rl,\n 'Watchmen (auto-synthesize workspace briefs from memory):',\n 'When enough observations accumulate (default: 5), synthesizes them into .kiro/steering/kirograph-watchmen.md, CLAUDE.md, AGENTS.md, or the equivalent for your tool.',\n false,\n );\n\n if (patch.enableWatchmen) {\n // \u2500\u2500 Synthesis mode \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\u2500\n const synthesisMode = await arrowSelect<KiroGraphConfig['watchmenSynthesisMode']>(\n rl,\n 'Watchmen synthesis mode:',\n [\n {\n value: 'local',\n label: 'Local model',\n description: 'Runs a local HuggingFace model via @huggingface/transformers. Zero API cost, no data leaves your machine. Model downloaded once to ~/.kirograph/models/. Works for all tools via runCommand hook.',\n },\n {\n value: 'agent',\n label: 'Active agent',\n description: '\u26A0 Kiro only. Uses the active Kiro agent to synthesize. Consumes API tokens/credits on every synthesis. Not supported for other tools.',\n },\n ],\n );\n patch.watchmenSynthesisMode = synthesisMode;\n\n if (synthesisMode === 'local') {\n // \u2500\u2500 Local model selection \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\n const LOCAL_MODELS = [\n {\n value: 'onnx-community/gemma-4-E4B-it-ONNX',\n label: 'Gemma 4 E4B (recommended)',\n description: '~3\u20134 GB \u00B7 Google DeepMind Gemma 4 \u00B7 4.5B params \u00B7 128K context \u00B7 Best quality \u00B7 Apache 2.0',\n },\n {\n value: 'onnx-community/Qwen2.5-1.5B-Instruct',\n label: 'Qwen2.5-1.5B',\n description: '~1.5 GB \u00B7 Lighter option if RAM is limited \u00B7 Acceptable quality',\n },\n {\n value: 'HuggingFaceTB/SmolLM2-1.7B-Instruct',\n label: 'SmolLM2-1.7B',\n description: '~1.7 GB \u00B7 HuggingFace compact model \u00B7 Good at following structured formats',\n },\n {\n value: '__other__',\n label: 'Other',\n description: 'Enter a custom HuggingFace model ID (must have ONNX weights on onnx-community)',\n },\n ] as const;\n\n const modelChoice = await arrowSelect<string>(rl, 'Local synthesis model:', LOCAL_MODELS.map(m => ({ value: m.value, label: m.label, description: m.description })));\n\n if (modelChoice === '__other__') {\n console.log(`\\n ${dim}Enter a HuggingFace model ID (e.g. onnx-community/gemma-4-E4B-it-ONNX).${reset}`);\n while (true) {\n const raw = (await ask(rl, ` ${violet}Model identifier:${reset} `)).trim();\n if (raw.includes('/')) { patch.watchmenLocalModel = raw; break; }\n console.log(` Expected a HuggingFace model ID in the format org/model-name.`);\n }\n } else {\n patch.watchmenLocalModel = modelChoice;\n }\n }\n }\n }\n\n return patch;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -44,6 +44,70 @@ var import_config_prompt = require("./config-prompt");
|
|
|
44
44
|
var import_dashboard = require("./dashboard");
|
|
45
45
|
var import_qdrant_dashboard = require("./qdrant-dashboard");
|
|
46
46
|
var import_targets = require("./targets");
|
|
47
|
+
function _findRustc() {
|
|
48
|
+
const inPath = (0, import_child_process.spawnSync)("rustc", ["--version"], { encoding: "utf8", shell: true });
|
|
49
|
+
if (inPath.status === 0) return "rustc";
|
|
50
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
51
|
+
const cargoRustc = path.join(home, ".cargo", "bin", "rustc");
|
|
52
|
+
if (fs.existsSync(cargoRustc)) return cargoRustc;
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
function _installTurbovecAddon() {
|
|
56
|
+
const nativeDir = path.join(__dirname, "..", "..", "..", "native", "turbovec-node");
|
|
57
|
+
const hasAddon = fs.existsSync(nativeDir) && fs.readdirSync(nativeDir).some((f) => f.startsWith("turbovec_node.") && f.endsWith(".node"));
|
|
58
|
+
if (hasAddon) {
|
|
59
|
+
console.log(` \u2713 turbovec-node addon already built`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
let rustc = _findRustc();
|
|
63
|
+
if (!rustc) {
|
|
64
|
+
console.log(`
|
|
65
|
+
Rust toolchain not found. Installing via rustup...`);
|
|
66
|
+
const isWindows = process.platform === "win32";
|
|
67
|
+
if (isWindows) {
|
|
68
|
+
console.warn(` \u2717 Automated rustup install is not supported on Windows.`);
|
|
69
|
+
console.warn(` Download rustup-init.exe from https://rustup.rs and re-run kirograph install.`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const rustup = (0, import_child_process.spawnSync)(
|
|
73
|
+
"sh",
|
|
74
|
+
["-c", 'curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path'],
|
|
75
|
+
{ stdio: "inherit", shell: false }
|
|
76
|
+
);
|
|
77
|
+
if (rustup.status !== 0) {
|
|
78
|
+
console.warn(` \u2717 rustup install failed. Install Rust manually: https://rustup.rs`);
|
|
79
|
+
console.warn(` Then: cd native/turbovec-node && npm install && npm run build`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
rustc = _findRustc();
|
|
83
|
+
if (!rustc) {
|
|
84
|
+
console.warn(` \u2717 rustc still not found after rustup install. Re-run kirograph install in a new shell.`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
console.log(` \u2713 Rust installed: ${(0, import_child_process.spawnSync)(rustc, ["--version"], { encoding: "utf8" }).stdout?.trim()}`);
|
|
88
|
+
} else {
|
|
89
|
+
console.log(` \u2713 Rust: ${(0, import_child_process.spawnSync)(rustc, ["--version"], { encoding: "utf8" }).stdout?.trim()}`);
|
|
90
|
+
}
|
|
91
|
+
if (!process.env.PATH?.includes(".cargo")) {
|
|
92
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
93
|
+
process.env.PATH = `${path.join(home, ".cargo", "bin")}:${process.env.PATH ?? ""}`;
|
|
94
|
+
}
|
|
95
|
+
console.log(`
|
|
96
|
+
Building turbovec-node native addon (Rust/napi-rs)...`);
|
|
97
|
+
console.log(` This may take a few minutes on first build.`);
|
|
98
|
+
const npmInstall = (0, import_child_process.spawnSync)("npm", ["install"], { cwd: nativeDir, stdio: "inherit", shell: true });
|
|
99
|
+
if (npmInstall.status !== 0) {
|
|
100
|
+
console.warn(` \u2717 npm install failed in native/turbovec-node`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const build = (0, import_child_process.spawnSync)("npm", ["run", "build"], { cwd: nativeDir, stdio: "inherit", shell: true });
|
|
104
|
+
if (build.status === 0) {
|
|
105
|
+
console.log(` \u2713 turbovec-node addon built`);
|
|
106
|
+
} else {
|
|
107
|
+
console.warn(` \u2717 Build failed (exit ${build.status}). Run manually:`);
|
|
108
|
+
console.warn(` cd native/turbovec-node && npm install && npm run build`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
47
111
|
async function runInstaller(target = "kiro", opts = {}) {
|
|
48
112
|
(0, import_banner.printBanner)();
|
|
49
113
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -94,6 +158,28 @@ async function runInstaller(target = "kiro", opts = {}) {
|
|
|
94
158
|
console.log(` \u2713 Reusing existing KiroGraph data in ${cwd}/.kirograph/`);
|
|
95
159
|
console.log(` \u2022 semanticEngine: ${config.semanticEngine}`);
|
|
96
160
|
console.log(` \u2022 enableEmbeddings: ${config.enableEmbeddings}`);
|
|
161
|
+
if (config.enableEmbeddings && config.semanticEngine === "turboquant") {
|
|
162
|
+
let tqAvailable = false;
|
|
163
|
+
try {
|
|
164
|
+
require("turboquant-js");
|
|
165
|
+
tqAvailable = true;
|
|
166
|
+
} catch {
|
|
167
|
+
}
|
|
168
|
+
if (!tqAvailable) {
|
|
169
|
+
console.log(`
|
|
170
|
+
Installing TurboQuant dependencies...`);
|
|
171
|
+
const result = (0, import_child_process.spawnSync)("npm", ["install", "turboquant-js"], { stdio: "inherit", shell: true });
|
|
172
|
+
if (result.status === 0) {
|
|
173
|
+
console.log(` \u2713 turboquant-js installed`);
|
|
174
|
+
} else {
|
|
175
|
+
console.warn(` \u2717 npm install failed (exit ${result.status}). Run manually:`);
|
|
176
|
+
console.warn(` npm install turboquant-js`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (config.enableEmbeddings && config.semanticEngine === "turbovec") {
|
|
181
|
+
_installTurbovecAddon();
|
|
182
|
+
}
|
|
97
183
|
console.log(` \u2022 enableArchitecture: ${config.enableArchitecture}`);
|
|
98
184
|
console.log(` \u2022 cavemanMode: ${cavemanMode}`);
|
|
99
185
|
console.log(` \u2022 shellCompressionLevel: ${shellCompressionLevel}`);
|
|
@@ -187,6 +273,18 @@ async function runInstaller(target = "kiro", opts = {}) {
|
|
|
187
273
|
console.warn(` \u2717 npm install failed (exit ${result.status}). Run manually:`);
|
|
188
274
|
console.warn(` npm install typesense`);
|
|
189
275
|
}
|
|
276
|
+
} else if (patch.semanticEngine === "turboquant") {
|
|
277
|
+
console.log(`
|
|
278
|
+
Installing TurboQuant dependencies...`);
|
|
279
|
+
const result = (0, import_child_process.spawnSync)("npm", ["install", "turboquant-js"], { stdio: "inherit", shell: true });
|
|
280
|
+
if (result.status === 0) {
|
|
281
|
+
console.log(` \u2713 turboquant-js installed`);
|
|
282
|
+
} else {
|
|
283
|
+
console.warn(` \u2717 npm install failed (exit ${result.status}). Run manually:`);
|
|
284
|
+
console.warn(` npm install turboquant-js`);
|
|
285
|
+
}
|
|
286
|
+
} else if (patch.semanticEngine === "turbovec") {
|
|
287
|
+
_installTurbovecAddon();
|
|
190
288
|
}
|
|
191
289
|
}
|
|
192
290
|
console.log(` \u2022 extractDocstrings: ${patch.extractDocstrings}`);
|
|
@@ -220,6 +318,16 @@ async function runInstaller(target = "kiro", opts = {}) {
|
|
|
220
318
|
console.warn(` \u2717 npm install failed. Run manually: npm install parquetjs-lite`);
|
|
221
319
|
}
|
|
222
320
|
}
|
|
321
|
+
if (patch.dataInstallPdf) {
|
|
322
|
+
console.log(`
|
|
323
|
+
Installing @firecrawl/pdf-inspector...`);
|
|
324
|
+
const pdfResult = (0, import_child_process.spawnSync)("npm", ["install", "--save-optional", "@firecrawl/pdf-inspector"], { stdio: "inherit", shell: true });
|
|
325
|
+
if (pdfResult.status === 0) {
|
|
326
|
+
console.log(` \u2713 @firecrawl/pdf-inspector installed`);
|
|
327
|
+
} else {
|
|
328
|
+
console.warn(` \u2717 npm install failed. Run manually: npm install --save-optional @firecrawl/pdf-inspector`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
223
331
|
}
|
|
224
332
|
if (enablePatterns) {
|
|
225
333
|
console.log(`
|