kirograph 0.14.0 → 0.15.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 +128 -20
- package/dist/assets/logo.png +0 -0
- package/dist/bin/commands/help.js +3 -0
- package/dist/bin/commands/help.js.map +2 -2
- package/dist/bin/commands/memory.js +483 -0
- package/dist/bin/commands/memory.js.map +7 -0
- package/dist/bin/commands/uninit.js +22 -13
- package/dist/bin/commands/uninit.js.map +2 -2
- package/dist/bin/installer/config-prompt.js +37 -23
- package/dist/bin/installer/config-prompt.js.map +2 -2
- package/dist/bin/installer/hooks.js +53 -75
- package/dist/bin/installer/hooks.js.map +2 -2
- package/dist/bin/installer/index.js +9 -4
- package/dist/bin/installer/index.js.map +2 -2
- package/dist/bin/installer/prompts.js +37 -6
- package/dist/bin/installer/prompts.js.map +2 -2
- package/dist/bin/installer/steering.js +19 -0
- package/dist/bin/installer/steering.js.map +2 -2
- package/dist/bin/installer/targets/aider.js +72 -0
- package/dist/bin/installer/targets/aider.js.map +7 -0
- package/dist/bin/installer/targets/amp.js +91 -0
- package/dist/bin/installer/targets/amp.js.map +7 -0
- package/dist/bin/installer/targets/antigravity.js +109 -0
- package/dist/bin/installer/targets/antigravity.js.map +7 -0
- package/dist/bin/installer/targets/augment.js +81 -0
- package/dist/bin/installer/targets/augment.js.map +7 -0
- package/dist/bin/installer/targets/claude.js +1 -1
- package/dist/bin/installer/targets/claude.js.map +2 -2
- package/dist/bin/installer/targets/cline.js +91 -0
- package/dist/bin/installer/targets/cline.js.map +7 -0
- package/dist/bin/installer/targets/codex.js +1 -1
- package/dist/bin/installer/targets/codex.js.map +2 -2
- package/dist/bin/installer/targets/continue.js +107 -0
- package/dist/bin/installer/targets/continue.js.map +7 -0
- package/dist/bin/installer/targets/copilot.js +123 -0
- package/dist/bin/installer/targets/copilot.js.map +7 -0
- package/dist/bin/installer/targets/cursor.js +143 -0
- package/dist/bin/installer/targets/cursor.js.map +7 -0
- package/dist/bin/installer/targets/devin.js +148 -0
- package/dist/bin/installer/targets/devin.js.map +7 -0
- package/dist/bin/installer/targets/gemini-cli.js +126 -0
- package/dist/bin/installer/targets/gemini-cli.js.map +7 -0
- package/dist/bin/installer/targets/generic.js +120 -0
- package/dist/bin/installer/targets/generic.js.map +7 -0
- package/dist/bin/installer/targets/goose.js +72 -0
- package/dist/bin/installer/targets/goose.js.map +7 -0
- package/dist/bin/installer/targets/index.js.map +1 -1
- package/dist/bin/installer/targets/junie.js +105 -0
- package/dist/bin/installer/targets/junie.js.map +7 -0
- package/dist/bin/installer/targets/kilo.js +122 -0
- package/dist/bin/installer/targets/kilo.js.map +7 -0
- package/dist/bin/installer/targets/kiro.js +3 -3
- package/dist/bin/installer/targets/kiro.js.map +2 -2
- package/dist/bin/installer/targets/opencode.js +135 -0
- package/dist/bin/installer/targets/opencode.js.map +7 -0
- package/dist/bin/installer/targets/openhands.js +90 -0
- package/dist/bin/installer/targets/openhands.js.map +7 -0
- package/dist/bin/installer/targets/replit.js +72 -0
- package/dist/bin/installer/targets/replit.js.map +7 -0
- package/dist/bin/installer/targets/roo.js +96 -0
- package/dist/bin/installer/targets/roo.js.map +7 -0
- package/dist/bin/installer/targets/tabnine.js +82 -0
- package/dist/bin/installer/targets/tabnine.js.map +7 -0
- package/dist/bin/installer/targets/trae.js +84 -0
- package/dist/bin/installer/targets/trae.js.map +7 -0
- package/dist/bin/installer/targets/warp.js +97 -0
- package/dist/bin/installer/targets/warp.js.map +7 -0
- package/dist/bin/installer/targets/windsurf.js +141 -0
- package/dist/bin/installer/targets/windsurf.js.map +7 -0
- package/dist/bin/kirograph.js +3 -1
- package/dist/bin/kirograph.js.map +3 -3
- package/dist/compression/naive-cost.js +14 -0
- package/dist/compression/naive-cost.js.map +2 -2
- package/dist/compression/tracker.js +18 -4
- package/dist/compression/tracker.js.map +2 -2
- package/dist/compression/types.js.map +1 -1
- package/dist/config.js +33 -1
- package/dist/config.js.map +2 -2
- package/dist/db/database.js +17 -0
- package/dist/db/database.js.map +2 -2
- package/dist/db/memory-schema.sql +51 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +2 -2
- package/dist/mcp/tool-names.js +5 -1
- package/dist/mcp/tool-names.js.map +2 -2
- package/dist/mcp/tools.js +232 -3
- package/dist/mcp/tools.js.map +2 -2
- package/dist/memory/compress.js +142 -0
- package/dist/memory/compress.js.map +7 -0
- package/dist/memory/database.js +375 -0
- package/dist/memory/database.js.map +7 -0
- package/dist/memory/index.js +239 -0
- package/dist/memory/index.js.map +7 -0
- package/dist/memory/symbols.js +54 -0
- package/dist/memory/symbols.js.map +7 -0
- package/dist/memory/types.js +17 -0
- package/dist/memory/types.js.map +7 -0
- package/dist/memory/vectors.js +199 -0
- package/dist/memory/vectors.js.map +7 -0
- package/package.json +1 -1
|
@@ -34,8 +34,10 @@ __export(uninit_exports, {
|
|
|
34
34
|
module.exports = __toCommonJS(uninit_exports);
|
|
35
35
|
var path = __toESM(require("path"));
|
|
36
36
|
var fs = __toESM(require("fs"));
|
|
37
|
+
var readline = __toESM(require("readline"));
|
|
37
38
|
var import_banner = require("../banner");
|
|
38
39
|
var import_ui = require("../ui");
|
|
40
|
+
var import_prompts = require("../installer/prompts");
|
|
39
41
|
const UNINIT_FAREWELLS = [
|
|
40
42
|
"Oh. So it's come to this.",
|
|
41
43
|
"We're sorry to see you go. (Are we? Yes. We are.)",
|
|
@@ -49,14 +51,6 @@ const UNINIT_FAREWELLS = [
|
|
|
49
51
|
"See you on the other side of `kirograph install`."
|
|
50
52
|
];
|
|
51
53
|
const UNINIT_TARGETS = ["kiro", "claude", "codex", "all"];
|
|
52
|
-
async function confirm(question) {
|
|
53
|
-
const readline = await import("readline");
|
|
54
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
55
|
-
return new Promise((resolve) => rl.question(question, (ans) => {
|
|
56
|
-
rl.close();
|
|
57
|
-
resolve(ans.toLowerCase() === "y");
|
|
58
|
-
}));
|
|
59
|
-
}
|
|
60
54
|
async function runUninit(projectPath, opts) {
|
|
61
55
|
const target = path.resolve(projectPath ?? process.cwd());
|
|
62
56
|
const integration = (opts.target ?? "kiro").toLowerCase();
|
|
@@ -77,10 +71,11 @@ async function runUninit(projectPath, opts) {
|
|
|
77
71
|
console.log(` ${import_ui.violet}${import_ui.bold}${farewell}${import_ui.reset}`);
|
|
78
72
|
console.log(`
|
|
79
73
|
${import_ui.dim}This can remove ${integration} integration files and, separately, the shared .kirograph/ data.${import_ui.reset}`);
|
|
80
|
-
console.log(` ${import_ui.dim}Your source code is untouched.${import_ui.reset}
|
|
81
|
-
|
|
82
|
-
removeIntegration = await
|
|
83
|
-
removeGraph = await
|
|
74
|
+
console.log(` ${import_ui.dim}Your source code is untouched.${import_ui.reset}`);
|
|
75
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
76
|
+
removeIntegration = await (0, import_prompts.askToggle)(rl, `Remove ${integration} integration files?`, "Removes hooks, steering, MCP config, and agent instructions for this target.", false);
|
|
77
|
+
removeGraph = await (0, import_prompts.askToggle)(rl, "Remove shared .kirograph/ data too?", "Deletes the graph database, snapshots, and all indexed data. Cannot be undone.", false);
|
|
78
|
+
rl.close();
|
|
84
79
|
if (!removeIntegration && !removeGraph) {
|
|
85
80
|
console.log(`
|
|
86
81
|
${import_ui.dim}Cancelled. Nothing removed.${import_ui.reset}
|
|
@@ -95,12 +90,21 @@ async function runUninit(projectPath, opts) {
|
|
|
95
90
|
}
|
|
96
91
|
if (removeIntegration && (integration === "kiro" || integration === "all")) {
|
|
97
92
|
const kiroHooks = [
|
|
93
|
+
"kirograph-mark-dirty-on-save.kiro.hook",
|
|
94
|
+
"kirograph-mark-dirty-on-create.kiro.hook",
|
|
95
|
+
"kirograph-sync-on-delete.kiro.hook",
|
|
96
|
+
"kirograph-sync-if-dirty.kiro.hook",
|
|
97
|
+
"kirograph-compress-hint.kiro.hook",
|
|
98
|
+
"kirograph-mem-capture.kiro.hook",
|
|
99
|
+
// Legacy .json filenames
|
|
98
100
|
"kirograph-mark-dirty-on-save.json",
|
|
99
101
|
"kirograph-mark-dirty-on-create.json",
|
|
100
102
|
"kirograph-sync-on-delete.json",
|
|
101
103
|
"kirograph-sync-if-dirty.json",
|
|
102
104
|
"kirograph-sync-on-save.json",
|
|
103
|
-
"kirograph-sync-on-create.json"
|
|
105
|
+
"kirograph-sync-on-create.json",
|
|
106
|
+
"kirograph-compress-hint.json",
|
|
107
|
+
"kirograph-mem-capture.json"
|
|
104
108
|
];
|
|
105
109
|
const hooksDir = path.join(target, ".kiro", "hooks");
|
|
106
110
|
let removedHooks = 0;
|
|
@@ -122,6 +126,11 @@ async function runUninit(projectPath, opts) {
|
|
|
122
126
|
fs.unlinkSync(agentPath);
|
|
123
127
|
console.log(` ${import_ui.green}\u2713${import_ui.reset} Removed .kiro/agents/kirograph.json`);
|
|
124
128
|
}
|
|
129
|
+
const { removeMcpServersConfig } = await Promise.resolve().then(() => require("../installer/common.js"));
|
|
130
|
+
const mcpPath = path.join(target, ".kiro", "settings", "mcp.json");
|
|
131
|
+
if (removeMcpServersConfig(mcpPath)) {
|
|
132
|
+
console.log(` ${import_ui.green}\u2713${import_ui.reset} Removed kirograph from .kiro/settings/mcp.json`);
|
|
133
|
+
}
|
|
125
134
|
}
|
|
126
135
|
if (removeIntegration && (integration === "claude" || integration === "all")) {
|
|
127
136
|
const { uninitClaude } = await Promise.resolve().then(() => require("../installer/targets/claude.js"));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/bin/commands/uninit.ts"],
|
|
4
|
-
"sourcesContent": ["import { Command } from 'commander';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { printBanner } from '../banner';\nimport { dim, reset, violet, bold, green } from '../ui';\n\nexport const UNINIT_FAREWELLS = [\n \"Oh. So it's come to this.\",\n \"We're sorry to see you go. (Are we? Yes. We are.)\",\n \"Deleting months of carefully indexed knowledge. Bold move.\",\n \"Fine. We'll just sit here in the dark.\",\n \"You can always come back. We won't mention this.\",\n \"The graph remembers everything. Except, soon, anything.\",\n \"Somewhere a tree-sitter is crying.\",\n \"Uninstalling... and pretending it doesn't hurt.\",\n \"574 embeddings. Gone. Just like that.\",\n \"See you on the other side of `kirograph install`.\",\n];\n\ntype UninitTarget = 'kiro' | 'claude' | 'codex' | 'all';\n\nconst UNINIT_TARGETS: UninitTarget[] = ['kiro', 'claude', 'codex', 'all'];\n\nasync function
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,WAAsB;AACtB,SAAoB;AACpB,oBAA4B;AAC5B,gBAAgD;
|
|
4
|
+
"sourcesContent": ["import { Command } from 'commander';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as readline from 'readline';\nimport { printBanner } from '../banner';\nimport { dim, reset, violet, bold, green } from '../ui';\nimport { askToggle } from '../installer/prompts';\n\nexport const UNINIT_FAREWELLS = [\n \"Oh. So it's come to this.\",\n \"We're sorry to see you go. (Are we? Yes. We are.)\",\n \"Deleting months of carefully indexed knowledge. Bold move.\",\n \"Fine. We'll just sit here in the dark.\",\n \"You can always come back. We won't mention this.\",\n \"The graph remembers everything. Except, soon, anything.\",\n \"Somewhere a tree-sitter is crying.\",\n \"Uninstalling... and pretending it doesn't hurt.\",\n \"574 embeddings. Gone. Just like that.\",\n \"See you on the other side of `kirograph install`.\",\n];\n\ntype UninitTarget = 'kiro' | 'claude' | 'codex' | 'all';\n\nconst UNINIT_TARGETS: UninitTarget[] = ['kiro', 'claude', 'codex', 'all'];\n\nasync function runUninit(projectPath: string | undefined, opts: { force?: boolean; target?: string }): Promise<void> {\n const target = path.resolve(projectPath ?? process.cwd());\n const integration = (opts.target ?? 'kiro').toLowerCase() as UninitTarget;\n if (!UNINIT_TARGETS.includes(integration)) {\n console.error(`Unknown uninit target: ${opts.target}. Choose from: kiro, claude, codex, all`);\n process.exit(1);\n }\n const dir = path.join(target, '.kirograph');\n if (!fs.existsSync(dir)) { console.log('Not initialized.'); return; }\n\n let removeIntegration = true;\n let removeGraph = opts.force === true;\n\n if (!opts.force) {\n printBanner();\n const farewell = UNINIT_FAREWELLS[Math.floor(Math.random() * UNINIT_FAREWELLS.length)]!;\n console.log(` ${violet}${bold}${farewell}${reset}`);\n console.log(`\\n ${dim}This can remove ${integration} integration files and, separately, the shared .kirograph/ data.${reset}`);\n console.log(` ${dim}Your source code is untouched.${reset}`);\n\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n\n removeIntegration = await askToggle(rl, `Remove ${integration} integration files?`, 'Removes hooks, steering, MCP config, and agent instructions for this target.', false);\n removeGraph = await askToggle(rl, 'Remove shared .kirograph/ data too?', 'Deletes the graph database, snapshots, and all indexed data. Cannot be undone.', false);\n\n rl.close();\n\n if (!removeIntegration && !removeGraph) {\n console.log(`\\n ${dim}Cancelled. Nothing removed.${reset}\\n`);\n return;\n }\n console.log();\n }\n\n if (removeGraph) {\n fs.rmSync(dir, { recursive: true, force: true });\n console.log(` ${green}\u2713${reset} Removed .kirograph/`);\n }\n\n if (removeIntegration && (integration === 'kiro' || integration === 'all')) {\n // Remove .kiro hooks created by kirograph\n const kiroHooks = [\n 'kirograph-mark-dirty-on-save.kiro.hook',\n 'kirograph-mark-dirty-on-create.kiro.hook',\n 'kirograph-sync-on-delete.kiro.hook',\n 'kirograph-sync-if-dirty.kiro.hook',\n 'kirograph-compress-hint.kiro.hook',\n 'kirograph-mem-capture.kiro.hook',\n // Legacy .json filenames\n 'kirograph-mark-dirty-on-save.json',\n 'kirograph-mark-dirty-on-create.json',\n 'kirograph-sync-on-delete.json',\n 'kirograph-sync-if-dirty.json',\n 'kirograph-sync-on-save.json',\n 'kirograph-sync-on-create.json',\n 'kirograph-compress-hint.json',\n 'kirograph-mem-capture.json',\n ];\n const hooksDir = path.join(target, '.kiro', 'hooks');\n let removedHooks = 0;\n for (const hook of kiroHooks) {\n const p = path.join(hooksDir, hook);\n if (fs.existsSync(p)) { fs.unlinkSync(p); removedHooks++; }\n }\n if (removedHooks > 0) console.log(` ${green}\u2713${reset} Removed ${removedHooks} hook(s) from .kiro/hooks/`);\n\n // Remove .kiro/steering/kirograph.md\n const steeringPath = path.join(target, '.kiro', 'steering', 'kirograph.md');\n if (fs.existsSync(steeringPath)) {\n fs.unlinkSync(steeringPath);\n console.log(` ${green}\u2713${reset} Removed .kiro/steering/kirograph.md`);\n }\n\n // Remove .kiro/agents/kirograph.json\n const agentPath = path.join(target, '.kiro', 'agents', 'kirograph.json');\n if (fs.existsSync(agentPath)) {\n fs.unlinkSync(agentPath);\n console.log(` ${green}\u2713${reset} Removed .kiro/agents/kirograph.json`);\n }\n\n // Remove kirograph server from .kiro/settings/mcp.json\n const { removeMcpServersConfig } = await Promise.resolve().then(() => require('../installer/common.js'));\n const mcpPath = path.join(target, '.kiro', 'settings', 'mcp.json');\n if (removeMcpServersConfig(mcpPath)) {\n console.log(` ${green}\u2713${reset} Removed kirograph from .kiro/settings/mcp.json`);\n }\n }\n\n if (removeIntegration && (integration === 'claude' || integration === 'all')) {\n const { uninitClaude } = await Promise.resolve().then(() => require('../installer/targets/claude.js'));\n uninitClaude(target);\n }\n\n if (removeIntegration && (integration === 'codex' || integration === 'all')) {\n const { uninitCodex } = await Promise.resolve().then(() => require('../installer/targets/codex.js'));\n uninitCodex(target);\n }\n\n console.log(`\\n ${dim}Done. Run ${violet}kirograph install --target ${integration === 'all' ? 'kiro' : integration}${reset}${dim} to come back anytime.${reset}\\n`);\n}\n\nexport function register(program: Command): void {\n program\n .command('uninit [projectPath]')\n .description('Remove KiroGraph from a project')\n .option('--force', 'Skip confirmation')\n .option('--target <target>', 'Integration target to clean up: kiro, claude, codex, or all', 'kiro')\n .action(runUninit);\n\n program\n .command('uninstall [projectPath]')\n .description('Alias for uninit. Remove KiroGraph from a project')\n .option('--force', 'Skip confirmation')\n .option('--target <target>', 'Integration target to clean up: kiro, claude, codex, or all', 'kiro')\n .action(runUninit);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -57,16 +57,17 @@ const PRESET_MODELS = [
|
|
|
57
57
|
}
|
|
58
58
|
];
|
|
59
59
|
async function promptConfigOptions(rl) {
|
|
60
|
-
|
|
60
|
+
(0, import_prompts.printSection)("\u{1F50D}", "Semantic Search");
|
|
61
|
+
const enableEmbeddings = await (0, import_prompts.askToggle)(
|
|
61
62
|
rl,
|
|
62
|
-
"
|
|
63
|
-
"Enables
|
|
63
|
+
"Semantic embeddings (similarity search):",
|
|
64
|
+
"Enables natural-language code search via vector embeddings. A local model (~130MB) is downloaded on first use."
|
|
64
65
|
);
|
|
65
|
-
const patch = { enableEmbeddings, useVecIndex: false, semanticEngine: "cosine", typesenseDashboard: false, qdrantDashboard: false, extractDocstrings: true, trackCallSites: true, enableArchitecture: false, cavemanMode: "off", shellCompressionLevel: "normal" };
|
|
66
|
+
const patch = { enableEmbeddings, useVecIndex: false, semanticEngine: "cosine", typesenseDashboard: false, qdrantDashboard: false, extractDocstrings: true, trackCallSites: true, enableArchitecture: false, cavemanMode: "off", shellCompressionLevel: "normal", enableMemory: false };
|
|
66
67
|
if (enableEmbeddings) {
|
|
67
68
|
const modelChoice = await (0, import_prompts.arrowSelect)(
|
|
68
69
|
rl,
|
|
69
|
-
"
|
|
70
|
+
"Embedding model:",
|
|
70
71
|
PRESET_MODELS.map((m) => ({ value: m.value, label: m.label, description: m.description }))
|
|
71
72
|
);
|
|
72
73
|
let embeddingModel;
|
|
@@ -100,7 +101,7 @@ async function promptConfigOptions(rl) {
|
|
|
100
101
|
}
|
|
101
102
|
patch.embeddingModel = embeddingModel;
|
|
102
103
|
patch.embeddingDim = embeddingDim;
|
|
103
|
-
const semanticEngine = await (0, import_prompts.arrowSelect)(rl, "
|
|
104
|
+
const semanticEngine = await (0, import_prompts.arrowSelect)(rl, "Vector search engine:", [
|
|
104
105
|
{ value: "cosine", label: "cosine", description: "In-process cosine similarity. No extra deps. Best for small/medium projects." },
|
|
105
106
|
{ value: "sqlite-vec", label: "sqlite-vec", description: "ANN index. Sub-linear search. Best for large codebases. Needs: better-sqlite3, sqlite-vec (native)." },
|
|
106
107
|
{ value: "orama", label: "orama", description: "Hybrid search (full-text + vector). Pure JS. Needs: @orama/orama, @orama/plugin-data-persistence." },
|
|
@@ -112,49 +113,62 @@ async function promptConfigOptions(rl) {
|
|
|
112
113
|
patch.semanticEngine = semanticEngine;
|
|
113
114
|
patch.useVecIndex = semanticEngine === "sqlite-vec";
|
|
114
115
|
if (semanticEngine === "typesense") {
|
|
115
|
-
patch.typesenseDashboard = await (0, import_prompts.
|
|
116
|
+
patch.typesenseDashboard = await (0, import_prompts.askToggle)(
|
|
116
117
|
rl,
|
|
117
|
-
"
|
|
118
|
-
"Serves the Typesense Dashboard locally and opens it in your browser after indexing completes."
|
|
118
|
+
"Typesense dashboard:",
|
|
119
|
+
"Serves the Typesense Dashboard locally and opens it in your browser after indexing completes.",
|
|
120
|
+
false
|
|
119
121
|
);
|
|
120
122
|
}
|
|
121
123
|
if (semanticEngine === "qdrant") {
|
|
122
|
-
patch.qdrantDashboard = await (0, import_prompts.
|
|
124
|
+
patch.qdrantDashboard = await (0, import_prompts.askToggle)(
|
|
123
125
|
rl,
|
|
124
|
-
"
|
|
125
|
-
"Downloads the Qdrant Web UI (first time only) and opens it in your browser after indexing completes."
|
|
126
|
+
"Qdrant dashboard:",
|
|
127
|
+
"Downloads the Qdrant Web UI (first time only) and opens it in your browser after indexing completes.",
|
|
128
|
+
false
|
|
126
129
|
);
|
|
127
130
|
}
|
|
128
131
|
}
|
|
129
|
-
|
|
132
|
+
(0, import_prompts.printSection)("\u{1F4CA}", "Graph Features");
|
|
133
|
+
patch.extractDocstrings = await (0, import_prompts.askToggle)(
|
|
130
134
|
rl,
|
|
131
|
-
"
|
|
135
|
+
"Docstring extraction:",
|
|
132
136
|
"Enriches symbol metadata and improves context quality. Slightly increases indexing time."
|
|
133
137
|
);
|
|
134
|
-
patch.trackCallSites = await (0, import_prompts.
|
|
138
|
+
patch.trackCallSites = await (0, import_prompts.askToggle)(
|
|
135
139
|
rl,
|
|
136
|
-
"
|
|
137
|
-
"Enables
|
|
140
|
+
"Call site tracking (caller/callee graph):",
|
|
141
|
+
"Enables kirograph_callers and kirograph_callees MCP tools. Increases index size."
|
|
138
142
|
);
|
|
139
|
-
patch.enableArchitecture = await (0, import_prompts.
|
|
143
|
+
patch.enableArchitecture = await (0, import_prompts.askToggle)(
|
|
140
144
|
rl,
|
|
141
|
-
"
|
|
142
|
-
"Detects packages from manifests
|
|
145
|
+
"Architecture analysis (packages + layers):",
|
|
146
|
+
"Detects packages from manifests and architectural layers. Enables kirograph_architecture, kirograph_coupling, kirograph_package.",
|
|
147
|
+
false
|
|
143
148
|
);
|
|
144
|
-
|
|
145
|
-
|
|
149
|
+
(0, import_prompts.printSection)("\u{1F916}", "Agent Behavior");
|
|
150
|
+
const cavemanChoice = await (0, import_prompts.arrowSelect)(rl, "Communication style (caveman mode):", [
|
|
151
|
+
{ value: "off", label: "off", description: "Normal responses \u2014 no compression" },
|
|
146
152
|
{ value: "lite", label: "lite", description: "Compact, no filler, full sentences" },
|
|
147
153
|
{ value: "full", label: "full", description: "Fragments, no articles, short synonyms" },
|
|
148
154
|
{ value: "ultra", label: "ultra", description: "Max compression, abbreviations, \u2192 for causality" }
|
|
149
155
|
]);
|
|
150
156
|
patch.cavemanMode = cavemanChoice;
|
|
151
|
-
const compressionChoice = await (0, import_prompts.arrowSelect)(rl, "Shell compression
|
|
157
|
+
const compressionChoice = await (0, import_prompts.arrowSelect)(rl, "Shell compression (kirograph_exec default level):", [
|
|
152
158
|
{ value: "off", label: "off", description: "No compression hook or steering (tool still available)" },
|
|
153
159
|
{ value: "normal", label: "normal", description: "Balanced: removes noise, keeps structure (recommended)" },
|
|
154
160
|
{ value: "aggressive", label: "aggressive", description: "More compact: groups by category, limits output" },
|
|
155
161
|
{ value: "ultra", label: "ultra", description: "Maximum compression: counts and summaries only" }
|
|
156
162
|
]);
|
|
157
163
|
patch.shellCompressionLevel = compressionChoice;
|
|
164
|
+
(0, import_prompts.printSection)("\u{1F9E0}", "Memory");
|
|
165
|
+
patch.enableMemory = await (0, import_prompts.askToggle)(
|
|
166
|
+
rl,
|
|
167
|
+
"Persistent memory (cross-session observations):",
|
|
168
|
+
"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.",
|
|
169
|
+
false
|
|
170
|
+
// Requires explicit enable
|
|
171
|
+
);
|
|
158
172
|
return patch;
|
|
159
173
|
}
|
|
160
174
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -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, askBool, arrowSelect, dim, reset, violet } from './prompts';\nexport type ConfigPatch = Pick<KiroGraphConfig, 'enableEmbeddings' | 'useVecIndex' | 'semanticEngine' | 'typesenseDashboard' | 'qdrantDashboard' | 'extractDocstrings' | 'trackCallSites' | 'enableArchitecture' | 'cavemanMode' | 'shellCompressionLevel'> & { 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 const enableEmbeddings = await askBool(\n rl,\n 'Enable semantic embeddings for similarity search? (requires a local embedding model)',\n 'Enables semantic/similarity-based code search. Increases indexing time; the chosen embedding model is downloaded automatically 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' };\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 'Choose an 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, 'Choose the semantic 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 askBool(\n rl,\n 'Open Typesense dashboard after indexing?',\n 'Serves the Typesense Dashboard locally and opens it in your browser after indexing completes.',\n );\n }\n\n if (semanticEngine === 'qdrant') {\n patch.qdrantDashboard = await askBool(\n rl,\n 'Open Qdrant dashboard after indexing?',\n 'Downloads the Qdrant Web UI (first time only) and opens it in your browser after indexing completes.',\n );\n }\n }\n\n patch.extractDocstrings = await askBool(\n rl,\n 'Extract docstrings from source files?',\n 'Enriches symbol metadata and improves context quality. Slightly increases indexing time.',\n );\n\n patch.trackCallSites = await askBool(\n rl,\n 'Track call sites to enable caller/callee graph traversal?',\n 'Enables the kirograph_callers and kirograph_callees MCP tools for graph traversal. Increases index size.',\n );\n\n patch.enableArchitecture = await askBool(\n rl,\n 'Enable architecture analysis (package graph + layer detection)?',\n 'Detects packages from manifests (package.json, go.mod, Cargo.toml, etc.) and architectural layers (api, service, data, ui, shared) from file structure. Enables kirograph_architecture, kirograph_coupling, and kirograph_package MCP tools.',\n );\n\n const cavemanChoice = await arrowSelect(rl, 'Caveman mode: agent communication style:', [\n { value: 'off', label: 'off', description: 'Normal responses' },\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: default level for kirograph_exec:', [\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 return patch;\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,
|
|
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'> & { 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 };\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 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 as any).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, // Requires explicit enable\n );\n\n return patch;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -34,95 +34,41 @@ module.exports = __toCommonJS(hooks_exports);
|
|
|
34
34
|
var fs = __toESM(require("fs"));
|
|
35
35
|
var path = __toESM(require("path"));
|
|
36
36
|
var import_errors = require("../../errors");
|
|
37
|
-
const
|
|
38
|
-
"**/*.ts",
|
|
39
|
-
"**/*.tsx",
|
|
40
|
-
"**/*.js",
|
|
41
|
-
"**/*.jsx",
|
|
42
|
-
"**/*.py",
|
|
43
|
-
"**/*.go",
|
|
44
|
-
"**/*.rs",
|
|
45
|
-
"**/*.java",
|
|
46
|
-
"**/*.cs",
|
|
47
|
-
"**/*.rb",
|
|
48
|
-
"**/*.php",
|
|
49
|
-
"**/*.swift",
|
|
50
|
-
"**/*.kt",
|
|
51
|
-
"**/*.dart",
|
|
52
|
-
"**/*.ex",
|
|
53
|
-
"**/*.exs",
|
|
54
|
-
"**/*.scala",
|
|
55
|
-
"**/*.sc",
|
|
56
|
-
"**/*.lua",
|
|
57
|
-
"**/*.zig",
|
|
58
|
-
"**/*.sh",
|
|
59
|
-
"**/*.bash",
|
|
60
|
-
"**/*.ml",
|
|
61
|
-
"**/*.mli",
|
|
62
|
-
"**/*.elm",
|
|
63
|
-
"**/*.sol",
|
|
64
|
-
"**/*.vue",
|
|
65
|
-
"**/*.m",
|
|
66
|
-
"**/*.yaml",
|
|
67
|
-
"**/*.yml",
|
|
68
|
-
"**/*.tf",
|
|
69
|
-
"**/*.tfvars",
|
|
70
|
-
"**/*.css",
|
|
71
|
-
"**/*.scss",
|
|
72
|
-
"**/*.sass",
|
|
73
|
-
"**/*.html"
|
|
74
|
-
];
|
|
37
|
+
const HOOK_EXT = ".kiro.hook";
|
|
75
38
|
const HOOKS = [
|
|
76
39
|
{
|
|
77
|
-
filename:
|
|
78
|
-
hook: {
|
|
79
|
-
name: "KiroGraph Mark Dirty on Save",
|
|
80
|
-
version: "1.0.0",
|
|
81
|
-
description: "Mark the KiroGraph index as dirty when source files are saved. Sync is deferred to agent idle.",
|
|
82
|
-
when: { type: "fileEdited", patterns: FILE_PATTERNS },
|
|
83
|
-
then: { type: "runCommand", command: "kirograph mark-dirty 2>/dev/null || true" }
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
filename: "kirograph-mark-dirty-on-create.json",
|
|
40
|
+
filename: `kirograph-sync-if-dirty${HOOK_EXT}`,
|
|
88
41
|
hook: {
|
|
89
|
-
name: "KiroGraph
|
|
42
|
+
name: "KiroGraph Sync on Agent Stop",
|
|
90
43
|
version: "1.0.0",
|
|
91
|
-
description: "
|
|
92
|
-
when: { type: "
|
|
93
|
-
then: { type: "runCommand", command: "kirograph
|
|
44
|
+
description: "Sync the KiroGraph index when the agent stops, picking up any file edits, creates, or deletes from the session.",
|
|
45
|
+
when: { type: "agentStop" },
|
|
46
|
+
then: { type: "runCommand", command: "kirograph sync --quiet 2>&1 > /dev/null" }
|
|
94
47
|
}
|
|
95
48
|
},
|
|
96
49
|
{
|
|
97
|
-
filename:
|
|
50
|
+
filename: `kirograph-compress-hint${HOOK_EXT}`,
|
|
98
51
|
hook: {
|
|
99
|
-
name: "KiroGraph
|
|
52
|
+
name: "KiroGraph Compression Hint",
|
|
100
53
|
version: "1.0.0",
|
|
101
|
-
description: "
|
|
102
|
-
when: { type: "
|
|
103
|
-
then: {
|
|
54
|
+
description: "Remind the agent to use kirograph_exec for shell commands that benefit from token compression (git, gh, test, lint, build, docker, aws, grep).",
|
|
55
|
+
when: { type: "preToolUse", toolTypes: ["shell"] },
|
|
56
|
+
then: {
|
|
57
|
+
type: "askAgent",
|
|
58
|
+
prompt: "If this shell command is a git operation, GitHub CLI, test runner, linter, build tool, file listing, grep/rg, docker/kubectl, AWS CLI, or package manager command, consider using the kirograph_exec MCP tool instead for 60-90% token savings. The tool compresses output automatically while preserving error details."
|
|
59
|
+
}
|
|
104
60
|
}
|
|
105
61
|
},
|
|
106
62
|
{
|
|
107
|
-
filename:
|
|
63
|
+
filename: `kirograph-mem-capture${HOOK_EXT}`,
|
|
108
64
|
hook: {
|
|
109
|
-
name: "KiroGraph
|
|
65
|
+
name: "KiroGraph Memory Capture",
|
|
110
66
|
version: "1.0.0",
|
|
111
|
-
description: "
|
|
67
|
+
description: "Prompt the agent to store important observations in memory at the end of each session.",
|
|
112
68
|
when: { type: "agentStop" },
|
|
113
|
-
then: { type: "runCommand", command: "kirograph sync-if-dirty --quiet 2>/dev/null || true" }
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
filename: "kirograph-compress-hint.json",
|
|
118
|
-
hook: {
|
|
119
|
-
name: "KiroGraph Compression Hint",
|
|
120
|
-
version: "1.0.0",
|
|
121
|
-
description: "Remind the agent to use kirograph_exec for shell commands that benefit from token compression (git, gh, test, lint, build, docker, aws, grep).",
|
|
122
|
-
when: { type: "preToolUse", toolTypes: ["shell"] },
|
|
123
69
|
then: {
|
|
124
70
|
type: "askAgent",
|
|
125
|
-
prompt: "
|
|
71
|
+
prompt: "Before ending, review what happened in this session. If there were any important decisions, bug root causes, architecture insights, error patterns, or lessons learned, store them using kirograph_mem_store with the appropriate kind (decision, error, pattern, architecture, note). Keep observations concise \u2014 one fact per observation. Skip if nothing noteworthy happened."
|
|
126
72
|
}
|
|
127
73
|
}
|
|
128
74
|
}
|
|
@@ -137,7 +83,7 @@ function migrateOnIdleHooks(hooksDir) {
|
|
|
137
83
|
if (!fs.existsSync(hooksDir)) return;
|
|
138
84
|
let files;
|
|
139
85
|
try {
|
|
140
|
-
files = fs.readdirSync(hooksDir).filter((f) => f.endsWith(".json"));
|
|
86
|
+
files = fs.readdirSync(hooksDir).filter((f) => f.endsWith(".json") || f.endsWith(HOOK_EXT));
|
|
141
87
|
} catch {
|
|
142
88
|
return;
|
|
143
89
|
}
|
|
@@ -157,8 +103,21 @@ function migrateOnIdleHooks(hooksDir) {
|
|
|
157
103
|
(0, import_errors.logWarn)(`KiroGraph installer: could not parse hook file ${filePath}`);
|
|
158
104
|
continue;
|
|
159
105
|
}
|
|
106
|
+
let changed = false;
|
|
160
107
|
if (obj?.when?.type === "onIdle") {
|
|
161
108
|
obj.when.type = "agentStop";
|
|
109
|
+
changed = true;
|
|
110
|
+
}
|
|
111
|
+
if (file.endsWith(".json") && file.startsWith("kirograph-")) {
|
|
112
|
+
const newName = file.replace(/\.json$/, HOOK_EXT);
|
|
113
|
+
const newPath = path.join(hooksDir, newName);
|
|
114
|
+
try {
|
|
115
|
+
fs.writeFileSync(newPath, JSON.stringify(obj, null, 2) + "\n");
|
|
116
|
+
fs.unlinkSync(filePath);
|
|
117
|
+
} catch {
|
|
118
|
+
(0, import_errors.logWarn)(`KiroGraph installer: could not migrate hook file ${filePath} \u2192 ${newName}`);
|
|
119
|
+
}
|
|
120
|
+
} else if (changed) {
|
|
162
121
|
try {
|
|
163
122
|
fs.writeFileSync(filePath, JSON.stringify(obj, null, 2) + "\n");
|
|
164
123
|
} catch {
|
|
@@ -171,13 +130,32 @@ function writeHooks(kiroDir, opts) {
|
|
|
171
130
|
const hooksDir = path.join(kiroDir, "hooks");
|
|
172
131
|
ensureDir(hooksDir);
|
|
173
132
|
migrateOnIdleHooks(hooksDir);
|
|
174
|
-
const oldHooks = [
|
|
133
|
+
const oldHooks = [
|
|
134
|
+
"kirograph-sync-on-save.json",
|
|
135
|
+
"kirograph-sync-on-create.json",
|
|
136
|
+
// Legacy .json versions (migrated to .kiro.hook)
|
|
137
|
+
"kirograph-mark-dirty-on-save.json",
|
|
138
|
+
"kirograph-mark-dirty-on-create.json",
|
|
139
|
+
"kirograph-sync-on-delete.json",
|
|
140
|
+
"kirograph-sync-if-dirty.json",
|
|
141
|
+
"kirograph-compress-hint.json",
|
|
142
|
+
"kirograph-mem-capture.json",
|
|
143
|
+
// Removed per-file hooks (consolidated into agentStop sync)
|
|
144
|
+
`kirograph-mark-dirty-on-save${HOOK_EXT}`,
|
|
145
|
+
`kirograph-mark-dirty-on-create${HOOK_EXT}`,
|
|
146
|
+
`kirograph-sync-on-delete${HOOK_EXT}`
|
|
147
|
+
];
|
|
175
148
|
for (const old of oldHooks) {
|
|
176
149
|
const p = path.join(hooksDir, old);
|
|
177
150
|
if (fs.existsSync(p)) fs.unlinkSync(p);
|
|
178
151
|
}
|
|
179
152
|
for (const { filename, hook } of HOOKS) {
|
|
180
|
-
if (filename ===
|
|
153
|
+
if (filename === `kirograph-compress-hint${HOOK_EXT}` && opts?.enableCompression === false) {
|
|
154
|
+
const p = path.join(hooksDir, filename);
|
|
155
|
+
if (fs.existsSync(p)) fs.unlinkSync(p);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (filename === `kirograph-mem-capture${HOOK_EXT}` && !opts?.enableMemory) {
|
|
181
159
|
const p = path.join(hooksDir, filename);
|
|
182
160
|
if (fs.existsSync(p)) fs.unlinkSync(p);
|
|
183
161
|
continue;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/bin/installer/hooks.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * KiroGraph Installer \u2014 Kiro hook file management\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { logWarn } from '../../errors';\n\n// \u2500\u2500 Constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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\nconst
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,SAAoB;AACpB,WAAsB;AACtB,oBAAwB;AAIxB,MAAM,
|
|
4
|
+
"sourcesContent": ["/**\n * KiroGraph Installer \u2014 Kiro hook file management\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { logWarn } from '../../errors';\n\n// \u2500\u2500 Constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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\nconst HOOK_EXT = '.kiro.hook';\n\nconst HOOKS: Array<{ filename: string; hook: object }> = [\n {\n filename: `kirograph-sync-if-dirty${HOOK_EXT}`,\n hook: {\n name: 'KiroGraph Sync on Agent Stop',\n version: '1.0.0',\n description: 'Sync the KiroGraph index when the agent stops, picking up any file edits, creates, or deletes from the session.',\n when: { type: 'agentStop' },\n then: { type: 'runCommand', command: 'kirograph sync --quiet 2>&1 > /dev/null' },\n },\n },\n {\n filename: `kirograph-compress-hint${HOOK_EXT}`,\n hook: {\n name: 'KiroGraph Compression Hint',\n version: '1.0.0',\n description: 'Remind the agent to use kirograph_exec for shell commands that benefit from token compression (git, gh, test, lint, build, docker, aws, grep).',\n when: { type: 'preToolUse', toolTypes: ['shell'] },\n then: {\n type: 'askAgent',\n prompt: 'If this shell command is a git operation, GitHub CLI, test runner, linter, build tool, file listing, grep/rg, docker/kubectl, AWS CLI, or package manager command, consider using the kirograph_exec MCP tool instead for 60-90% token savings. The tool compresses output automatically while preserving error details.',\n },\n },\n },\n {\n filename: `kirograph-mem-capture${HOOK_EXT}`,\n hook: {\n name: 'KiroGraph Memory Capture',\n version: '1.0.0',\n description: 'Prompt the agent to store important observations in memory at the end of each session.',\n when: { type: 'agentStop' },\n then: {\n type: 'askAgent',\n prompt: 'Before ending, review what happened in this session. If there were any important decisions, bug root causes, architecture insights, error patterns, or lessons learned, store them using kirograph_mem_store with the appropriate kind (decision, error, pattern, architecture, note). Keep observations concise \u2014 one fact per observation. Skip if nothing noteworthy happened.',\n },\n },\n },\n];\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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\nfunction ensureDir(p: string): void {\n fs.mkdirSync(p, { recursive: true });\n}\n\nfunction writeJson(p: string, data: unknown): void {\n fs.writeFileSync(p, JSON.stringify(data, null, 2) + '\\n');\n}\n\nfunction migrateOnIdleHooks(hooksDir: string): void {\n if (!fs.existsSync(hooksDir)) return;\n let files: string[];\n try {\n files = fs.readdirSync(hooksDir).filter(f => f.endsWith('.json') || f.endsWith(HOOK_EXT));\n } catch {\n return;\n }\n for (const file of files) {\n const filePath = path.join(hooksDir, file);\n let raw: string;\n try {\n raw = fs.readFileSync(filePath, 'utf8');\n } catch {\n logWarn(`KiroGraph installer: could not read hook file ${filePath}`);\n continue;\n }\n let obj: any;\n try {\n obj = JSON.parse(raw);\n } catch {\n logWarn(`KiroGraph installer: could not parse hook file ${filePath}`);\n continue;\n }\n let changed = false;\n if (obj?.when?.type === 'onIdle') {\n obj.when.type = 'agentStop';\n changed = true;\n }\n // Migrate .json \u2192 .kiro.hook extension\n if (file.endsWith('.json') && file.startsWith('kirograph-')) {\n const newName = file.replace(/\\.json$/, HOOK_EXT);\n const newPath = path.join(hooksDir, newName);\n try {\n fs.writeFileSync(newPath, JSON.stringify(obj, null, 2) + '\\n');\n fs.unlinkSync(filePath);\n } catch {\n logWarn(`KiroGraph installer: could not migrate hook file ${filePath} \u2192 ${newName}`);\n }\n } else if (changed) {\n try {\n fs.writeFileSync(filePath, JSON.stringify(obj, null, 2) + '\\n');\n } catch {\n logWarn(`KiroGraph installer: could not write migrated hook file ${filePath}`);\n }\n }\n }\n}\n\n// \u2500\u2500 Public \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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\nexport function writeHooks(kiroDir: string, opts?: { enableCompression?: boolean; enableMemory?: boolean }): void {\n const hooksDir = path.join(kiroDir, 'hooks');\n ensureDir(hooksDir);\n\n migrateOnIdleHooks(hooksDir);\n\n const oldHooks = [\n 'kirograph-sync-on-save.json', 'kirograph-sync-on-create.json',\n // Legacy .json versions (migrated to .kiro.hook)\n 'kirograph-mark-dirty-on-save.json', 'kirograph-mark-dirty-on-create.json',\n 'kirograph-sync-on-delete.json', 'kirograph-sync-if-dirty.json',\n 'kirograph-compress-hint.json', 'kirograph-mem-capture.json',\n // Removed per-file hooks (consolidated into agentStop sync)\n `kirograph-mark-dirty-on-save${HOOK_EXT}`,\n `kirograph-mark-dirty-on-create${HOOK_EXT}`,\n `kirograph-sync-on-delete${HOOK_EXT}`,\n ];\n for (const old of oldHooks) {\n const p = path.join(hooksDir, old);\n if (fs.existsSync(p)) fs.unlinkSync(p);\n }\n\n for (const { filename, hook } of HOOKS) {\n // Skip compression hook if compression is disabled\n if (filename === `kirograph-compress-hint${HOOK_EXT}` && opts?.enableCompression === false) {\n const p = path.join(hooksDir, filename);\n if (fs.existsSync(p)) fs.unlinkSync(p);\n continue;\n }\n // Skip memory hook if memory is disabled\n if (filename === `kirograph-mem-capture${HOOK_EXT}` && !opts?.enableMemory) {\n const p = path.join(hooksDir, filename);\n if (fs.existsSync(p)) fs.unlinkSync(p);\n continue;\n }\n writeJson(path.join(hooksDir, filename), hook);\n }\n\n console.log(` \u2713 Auto-sync hooks written to ${hooksDir}`);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,SAAoB;AACpB,WAAsB;AACtB,oBAAwB;AAIxB,MAAM,WAAW;AAEjB,MAAM,QAAmD;AAAA,EACvD;AAAA,IACE,UAAU,0BAA0B,QAAQ;AAAA,IAC5C,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa;AAAA,MACb,MAAM,EAAE,MAAM,YAAY;AAAA,MAC1B,MAAM,EAAE,MAAM,cAAc,SAAS,0CAA0C;AAAA,IACjF;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU,0BAA0B,QAAQ;AAAA,IAC5C,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa;AAAA,MACb,MAAM,EAAE,MAAM,cAAc,WAAW,CAAC,OAAO,EAAE;AAAA,MACjD,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU,wBAAwB,QAAQ;AAAA,IAC1C,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa;AAAA,MACb,MAAM,EAAE,MAAM,YAAY;AAAA,MAC1B,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,UAAU,GAAiB;AAClC,KAAG,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AACrC;AAEA,SAAS,UAAU,GAAW,MAAqB;AACjD,KAAG,cAAc,GAAG,KAAK,UAAU,MAAM,MAAM,CAAC,IAAI,IAAI;AAC1D;AAEA,SAAS,mBAAmB,UAAwB;AAClD,MAAI,CAAC,GAAG,WAAW,QAAQ,EAAG;AAC9B,MAAI;AACJ,MAAI;AACF,YAAQ,GAAG,YAAY,QAAQ,EAAE,OAAO,OAAK,EAAE,SAAS,OAAO,KAAK,EAAE,SAAS,QAAQ,CAAC;AAAA,EAC1F,QAAQ;AACN;AAAA,EACF;AACA,aAAW,QAAQ,OAAO;AACxB,UAAM,WAAW,KAAK,KAAK,UAAU,IAAI;AACzC,QAAI;AACJ,QAAI;AACF,YAAM,GAAG,aAAa,UAAU,MAAM;AAAA,IACxC,QAAQ;AACN,iCAAQ,iDAAiD,QAAQ,EAAE;AACnE;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACF,YAAM,KAAK,MAAM,GAAG;AAAA,IACtB,QAAQ;AACN,iCAAQ,kDAAkD,QAAQ,EAAE;AACpE;AAAA,IACF;AACA,QAAI,UAAU;AACd,QAAI,KAAK,MAAM,SAAS,UAAU;AAChC,UAAI,KAAK,OAAO;AAChB,gBAAU;AAAA,IACZ;AAEA,QAAI,KAAK,SAAS,OAAO,KAAK,KAAK,WAAW,YAAY,GAAG;AAC3D,YAAM,UAAU,KAAK,QAAQ,WAAW,QAAQ;AAChD,YAAM,UAAU,KAAK,KAAK,UAAU,OAAO;AAC3C,UAAI;AACF,WAAG,cAAc,SAAS,KAAK,UAAU,KAAK,MAAM,CAAC,IAAI,IAAI;AAC7D,WAAG,WAAW,QAAQ;AAAA,MACxB,QAAQ;AACN,mCAAQ,oDAAoD,QAAQ,WAAM,OAAO,EAAE;AAAA,MACrF;AAAA,IACF,WAAW,SAAS;AAClB,UAAI;AACF,WAAG,cAAc,UAAU,KAAK,UAAU,KAAK,MAAM,CAAC,IAAI,IAAI;AAAA,MAChE,QAAQ;AACN,mCAAQ,2DAA2D,QAAQ,EAAE;AAAA,MAC/E;AAAA,IACF;AAAA,EACF;AACF;AAIO,SAAS,WAAW,SAAiB,MAAsE;AAChH,QAAM,WAAW,KAAK,KAAK,SAAS,OAAO;AAC3C,YAAU,QAAQ;AAElB,qBAAmB,QAAQ;AAE3B,QAAM,WAAW;AAAA,IACf;AAAA,IAA+B;AAAA;AAAA,IAE/B;AAAA,IAAqC;AAAA,IACrC;AAAA,IAAiC;AAAA,IACjC;AAAA,IAAgC;AAAA;AAAA,IAEhC,+BAA+B,QAAQ;AAAA,IACvC,iCAAiC,QAAQ;AAAA,IACzC,2BAA2B,QAAQ;AAAA,EACrC;AACA,aAAW,OAAO,UAAU;AAC1B,UAAM,IAAI,KAAK,KAAK,UAAU,GAAG;AACjC,QAAI,GAAG,WAAW,CAAC,EAAG,IAAG,WAAW,CAAC;AAAA,EACvC;AAEA,aAAW,EAAE,UAAU,KAAK,KAAK,OAAO;AAEtC,QAAI,aAAa,0BAA0B,QAAQ,MAAM,MAAM,sBAAsB,OAAO;AAC1F,YAAM,IAAI,KAAK,KAAK,UAAU,QAAQ;AACtC,UAAI,GAAG,WAAW,CAAC,EAAG,IAAG,WAAW,CAAC;AACrC;AAAA,IACF;AAEA,QAAI,aAAa,wBAAwB,QAAQ,MAAM,CAAC,MAAM,cAAc;AAC1E,YAAM,IAAI,KAAK,KAAK,UAAU,QAAQ;AACtC,UAAI,GAAG,WAAW,CAAC,EAAG,IAAG,WAAW,CAAC;AACrC;AAAA,IACF;AACA,cAAU,KAAK,KAAK,UAAU,QAAQ,GAAG,IAAI;AAAA,EAC/C;AAEA,UAAQ,IAAI,uCAAkC,QAAQ,EAAE;AAC1D;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|