kirograph 0.14.1 → 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/uninit.js +10 -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 +20 -1
- 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/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/package.json +1 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
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
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var trae_exports = {};
|
|
30
|
+
__export(trae_exports, {
|
|
31
|
+
installTraeEarly: () => installTraeEarly,
|
|
32
|
+
installTraeLate: () => installTraeLate,
|
|
33
|
+
printTraeNextSteps: () => printTraeNextSteps,
|
|
34
|
+
uninitTrae: () => uninitTrae
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(trae_exports);
|
|
37
|
+
var fs = __toESM(require("fs"));
|
|
38
|
+
var path = __toESM(require("path"));
|
|
39
|
+
var import_common = require("../common");
|
|
40
|
+
var import_instructions = require("../instructions");
|
|
41
|
+
var import_common2 = require("../common");
|
|
42
|
+
function installTraeEarly(projectRoot) {
|
|
43
|
+
const mcpPath = path.join(projectRoot, ".trae", "mcp.json");
|
|
44
|
+
(0, import_common.writeMcpServersConfig)(mcpPath, {
|
|
45
|
+
command: import_common.KIROGRAPH_COMMAND,
|
|
46
|
+
args: import_common.KIROGRAPH_MCP_ARGS
|
|
47
|
+
});
|
|
48
|
+
console.log(` \u2713 Trae MCP server registered in ${mcpPath}`);
|
|
49
|
+
}
|
|
50
|
+
function installTraeLate(projectRoot, cavemanMode, shellCompressionLevel, enableMemory) {
|
|
51
|
+
const instructionsPath = path.join(projectRoot, ".kirograph", "trae.md");
|
|
52
|
+
(0, import_common.ensureDir)(path.dirname(instructionsPath));
|
|
53
|
+
fs.writeFileSync(instructionsPath, (0, import_instructions.buildAgentInstructions)((0, import_common2.buildInstructionOpts)(cavemanMode, shellCompressionLevel, enableMemory)));
|
|
54
|
+
console.log(` \u2713 Trae instructions written to ${instructionsPath}`);
|
|
55
|
+
const rulesDir = path.join(projectRoot, ".trae", "rules");
|
|
56
|
+
(0, import_common.ensureDir)(rulesDir);
|
|
57
|
+
const rulePath = path.join(rulesDir, "kirograph.md");
|
|
58
|
+
const frontmatter = "---\nalwaysApply: true\n---\n\n";
|
|
59
|
+
fs.writeFileSync(rulePath, frontmatter + (0, import_instructions.buildAgentInstructions)((0, import_common2.buildInstructionOpts)(cavemanMode, shellCompressionLevel, enableMemory)));
|
|
60
|
+
console.log(` \u2713 Trae rule written to ${rulePath}`);
|
|
61
|
+
}
|
|
62
|
+
function uninitTrae(projectRoot) {
|
|
63
|
+
const mcpPath = path.join(projectRoot, ".trae", "mcp.json");
|
|
64
|
+
if ((0, import_common.removeMcpServersConfig)(mcpPath)) {
|
|
65
|
+
console.log(` \u2713 Removed kirograph from .trae/mcp.json`);
|
|
66
|
+
}
|
|
67
|
+
const rulePath = path.join(projectRoot, ".trae", "rules", "kirograph.md");
|
|
68
|
+
if (fs.existsSync(rulePath)) {
|
|
69
|
+
fs.unlinkSync(rulePath);
|
|
70
|
+
console.log(` \u2713 Removed .trae/rules/kirograph.md`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function printTraeNextSteps() {
|
|
74
|
+
console.log("\n Done! Restart Trae for the MCP server to load.");
|
|
75
|
+
console.log(" KiroGraph rule is in .trae/rules/kirograph.md\n");
|
|
76
|
+
}
|
|
77
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
78
|
+
0 && (module.exports = {
|
|
79
|
+
installTraeEarly,
|
|
80
|
+
installTraeLate,
|
|
81
|
+
printTraeNextSteps,
|
|
82
|
+
uninitTrae
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=trae.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/bin/installer/targets/trae.ts"],
|
|
4
|
+
"sourcesContent": ["import * as fs from 'fs';\nimport * as path from 'path';\nimport { CavemanMode } from '../caveman';\nimport {\n ensureDir,\n KIROGRAPH_COMMAND,\n KIROGRAPH_MCP_ARGS,\n removeMcpServersConfig,\n writeMcpServersConfig,\n} from '../common';\nimport { buildAgentInstructions } from '../instructions';\nimport { buildInstructionOpts } from '../common';\n\nexport function installTraeEarly(projectRoot: string): void {\n const mcpPath = path.join(projectRoot, '.trae', 'mcp.json');\n writeMcpServersConfig(mcpPath, {\n command: KIROGRAPH_COMMAND,\n args: KIROGRAPH_MCP_ARGS,\n });\n console.log(` \u2713 Trae MCP server registered in ${mcpPath}`);\n}\n\nexport function installTraeLate(projectRoot: string, cavemanMode?: CavemanMode | 'off', shellCompressionLevel?: string, enableMemory?: boolean): void {\n const instructionsPath = path.join(projectRoot, '.kirograph', 'trae.md');\n ensureDir(path.dirname(instructionsPath));\n fs.writeFileSync(instructionsPath, buildAgentInstructions(buildInstructionOpts(cavemanMode, shellCompressionLevel, enableMemory)));\n console.log(` \u2713 Trae instructions written to ${instructionsPath}`);\n\n const rulesDir = path.join(projectRoot, '.trae', 'rules');\n ensureDir(rulesDir);\n const rulePath = path.join(rulesDir, 'kirograph.md');\n const frontmatter = '---\\nalwaysApply: true\\n---\\n\\n';\n fs.writeFileSync(rulePath, frontmatter + buildAgentInstructions(buildInstructionOpts(cavemanMode, shellCompressionLevel, enableMemory)));\n console.log(` \u2713 Trae rule written to ${rulePath}`);\n}\n\nexport function uninitTrae(projectRoot: string): void {\n const mcpPath = path.join(projectRoot, '.trae', 'mcp.json');\n if (removeMcpServersConfig(mcpPath)) {\n console.log(` \u2713 Removed kirograph from .trae/mcp.json`);\n }\n\n const rulePath = path.join(projectRoot, '.trae', 'rules', 'kirograph.md');\n if (fs.existsSync(rulePath)) {\n fs.unlinkSync(rulePath);\n console.log(` \u2713 Removed .trae/rules/kirograph.md`);\n }\n}\n\nexport function printTraeNextSteps(): void {\n console.log('\\n Done! Restart Trae for the MCP server to load.');\n console.log(' KiroGraph rule is in .trae/rules/kirograph.md\\n');\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAoB;AACpB,WAAsB;AAEtB,oBAMO;AACP,0BAAuC;AACvC,IAAAA,iBAAqC;AAE9B,SAAS,iBAAiB,aAA2B;AAC1D,QAAM,UAAU,KAAK,KAAK,aAAa,SAAS,UAAU;AAC1D,2CAAsB,SAAS;AAAA,IAC7B,SAAS;AAAA,IACT,MAAM;AAAA,EACR,CAAC;AACD,UAAQ,IAAI,0CAAqC,OAAO,EAAE;AAC5D;AAEO,SAAS,gBAAgB,aAAqB,aAAmC,uBAAgC,cAA8B;AACpJ,QAAM,mBAAmB,KAAK,KAAK,aAAa,cAAc,SAAS;AACvE,+BAAU,KAAK,QAAQ,gBAAgB,CAAC;AACxC,KAAG,cAAc,sBAAkB,gDAAuB,qCAAqB,aAAa,uBAAuB,YAAY,CAAC,CAAC;AACjI,UAAQ,IAAI,yCAAoC,gBAAgB,EAAE;AAElE,QAAM,WAAW,KAAK,KAAK,aAAa,SAAS,OAAO;AACxD,+BAAU,QAAQ;AAClB,QAAM,WAAW,KAAK,KAAK,UAAU,cAAc;AACnD,QAAM,cAAc;AACpB,KAAG,cAAc,UAAU,kBAAc,gDAAuB,qCAAqB,aAAa,uBAAuB,YAAY,CAAC,CAAC;AACvI,UAAQ,IAAI,iCAA4B,QAAQ,EAAE;AACpD;AAEO,SAAS,WAAW,aAA2B;AACpD,QAAM,UAAU,KAAK,KAAK,aAAa,SAAS,UAAU;AAC1D,UAAI,sCAAuB,OAAO,GAAG;AACnC,YAAQ,IAAI,gDAA2C;AAAA,EACzD;AAEA,QAAM,WAAW,KAAK,KAAK,aAAa,SAAS,SAAS,cAAc;AACxE,MAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,OAAG,WAAW,QAAQ;AACtB,YAAQ,IAAI,2CAAsC;AAAA,EACpD;AACF;AAEO,SAAS,qBAA2B;AACzC,UAAQ,IAAI,oDAAoD;AAChE,UAAQ,IAAI,mDAAmD;AACjE;",
|
|
6
|
+
"names": ["import_common"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
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
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var warp_exports = {};
|
|
30
|
+
__export(warp_exports, {
|
|
31
|
+
installWarpEarly: () => installWarpEarly,
|
|
32
|
+
installWarpLate: () => installWarpLate,
|
|
33
|
+
printWarpNextSteps: () => printWarpNextSteps,
|
|
34
|
+
uninitWarp: () => uninitWarp
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(warp_exports);
|
|
37
|
+
var fs = __toESM(require("fs"));
|
|
38
|
+
var path = __toESM(require("path"));
|
|
39
|
+
var import_common = require("../common");
|
|
40
|
+
var import_instructions = require("../instructions");
|
|
41
|
+
const WARP_BLOCK_ID = "warp";
|
|
42
|
+
function installWarpEarly(projectRoot) {
|
|
43
|
+
const mcpPath = path.join(projectRoot, ".warp", ".mcp.json");
|
|
44
|
+
(0, import_common.ensureDir)(path.dirname(mcpPath));
|
|
45
|
+
const config = (0, import_common.readJson)(mcpPath);
|
|
46
|
+
config.mcpServers = config.mcpServers ?? {};
|
|
47
|
+
config.mcpServers[import_common.KIROGRAPH_SERVER_NAME] = {
|
|
48
|
+
command: import_common.KIROGRAPH_COMMAND,
|
|
49
|
+
args: import_common.KIROGRAPH_MCP_ARGS
|
|
50
|
+
};
|
|
51
|
+
(0, import_common.writeJson)(mcpPath, config);
|
|
52
|
+
console.log(` \u2713 Warp MCP server registered in ${mcpPath}`);
|
|
53
|
+
}
|
|
54
|
+
function installWarpLate(projectRoot, cavemanMode, shellCompressionLevel, enableMemory) {
|
|
55
|
+
const opts = (0, import_common.buildInstructionOpts)(cavemanMode, shellCompressionLevel, enableMemory);
|
|
56
|
+
const instructionsPath = path.join(projectRoot, ".kirograph", "warp.md");
|
|
57
|
+
(0, import_common.ensureDir)(path.dirname(instructionsPath));
|
|
58
|
+
fs.writeFileSync(instructionsPath, (0, import_instructions.buildAgentInstructions)(opts));
|
|
59
|
+
console.log(` \u2713 Warp instructions written to ${instructionsPath}`);
|
|
60
|
+
const agentsPath = path.join(projectRoot, "AGENTS.md");
|
|
61
|
+
const changed = (0, import_common.upsertGeneratedBlock)(agentsPath, WARP_BLOCK_ID, "## KiroGraph", (0, import_instructions.buildAgentInstructions)(opts));
|
|
62
|
+
console.log(changed ? ` \u2713 AGENTS.md updated with KiroGraph instructions (Warp)` : ` \u2713 AGENTS.md already up to date`);
|
|
63
|
+
const legacyRule = path.join(projectRoot, ".warp", "rules", "kirograph.md");
|
|
64
|
+
if (fs.existsSync(legacyRule)) {
|
|
65
|
+
fs.unlinkSync(legacyRule);
|
|
66
|
+
console.log(` \u2713 Removed legacy .warp/rules/kirograph.md`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function uninitWarp(projectRoot) {
|
|
70
|
+
const mcpPath = path.join(projectRoot, ".warp", ".mcp.json");
|
|
71
|
+
if (fs.existsSync(mcpPath)) {
|
|
72
|
+
const config = (0, import_common.readJson)(mcpPath);
|
|
73
|
+
if (config.mcpServers?.[import_common.KIROGRAPH_SERVER_NAME]) {
|
|
74
|
+
delete config.mcpServers[import_common.KIROGRAPH_SERVER_NAME];
|
|
75
|
+
if (Object.keys(config.mcpServers).length === 0) delete config.mcpServers;
|
|
76
|
+
(0, import_common.writeJson)(mcpPath, config);
|
|
77
|
+
console.log(` \u2713 Removed kirograph from .warp/.mcp.json`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const agentsPath = path.join(projectRoot, "AGENTS.md");
|
|
81
|
+
if ((0, import_common.removeGeneratedBlock)(agentsPath, WARP_BLOCK_ID)) {
|
|
82
|
+
console.log(` \u2713 Removed KiroGraph block from AGENTS.md (Warp)`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function printWarpNextSteps() {
|
|
86
|
+
console.log("\n Done! Restart Warp for the MCP server to load.");
|
|
87
|
+
console.log(" MCP is in .warp/.mcp.json");
|
|
88
|
+
console.log(" KiroGraph instructions are in AGENTS.md\n");
|
|
89
|
+
}
|
|
90
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
91
|
+
0 && (module.exports = {
|
|
92
|
+
installWarpEarly,
|
|
93
|
+
installWarpLate,
|
|
94
|
+
printWarpNextSteps,
|
|
95
|
+
uninitWarp
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=warp.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/bin/installer/targets/warp.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Warp target.\n *\n * MCP: .warp/.mcp.json (project-level, standard mcpServers format)\n * Rules: AGENTS.md (Warp reads this natively, upsert block)\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { CavemanMode } from '../caveman';\nimport {\n ensureDir,\n buildInstructionOpts,\n readJson,\n writeJson,\n KIROGRAPH_COMMAND,\n KIROGRAPH_MCP_ARGS,\n KIROGRAPH_SERVER_NAME,\n upsertGeneratedBlock,\n removeGeneratedBlock,\n} from '../common';\nimport { buildAgentInstructions } from '../instructions';\n\nconst WARP_BLOCK_ID = 'warp';\n\nexport function installWarpEarly(projectRoot: string): void {\n // Write MCP to .warp/.mcp.json (project-level)\n const mcpPath = path.join(projectRoot, '.warp', '.mcp.json');\n ensureDir(path.dirname(mcpPath));\n const config = readJson(mcpPath);\n config.mcpServers = config.mcpServers ?? {};\n config.mcpServers[KIROGRAPH_SERVER_NAME] = {\n command: KIROGRAPH_COMMAND,\n args: KIROGRAPH_MCP_ARGS,\n };\n writeJson(mcpPath, config);\n console.log(` \u2713 Warp MCP server registered in ${mcpPath}`);\n}\n\nexport function installWarpLate(projectRoot: string, cavemanMode?: CavemanMode | 'off', shellCompressionLevel?: string, enableMemory?: boolean): void {\n const opts = buildInstructionOpts(cavemanMode, shellCompressionLevel, enableMemory);\n\n const instructionsPath = path.join(projectRoot, '.kirograph', 'warp.md');\n ensureDir(path.dirname(instructionsPath));\n fs.writeFileSync(instructionsPath, buildAgentInstructions(opts));\n console.log(` \u2713 Warp instructions written to ${instructionsPath}`);\n\n // Write to AGENTS.md (Warp reads this natively)\n const agentsPath = path.join(projectRoot, 'AGENTS.md');\n const changed = upsertGeneratedBlock(agentsPath, WARP_BLOCK_ID, '## KiroGraph', buildAgentInstructions(opts));\n console.log(changed\n ? ` \u2713 AGENTS.md updated with KiroGraph instructions (Warp)`\n : ` \u2713 AGENTS.md already up to date`);\n\n // Remove legacy .warp/rules/kirograph.md if it exists\n const legacyRule = path.join(projectRoot, '.warp', 'rules', 'kirograph.md');\n if (fs.existsSync(legacyRule)) {\n fs.unlinkSync(legacyRule);\n console.log(` \u2713 Removed legacy .warp/rules/kirograph.md`);\n }\n}\n\nexport function uninitWarp(projectRoot: string): void {\n // Remove MCP entry\n const mcpPath = path.join(projectRoot, '.warp', '.mcp.json');\n if (fs.existsSync(mcpPath)) {\n const config = readJson(mcpPath);\n if (config.mcpServers?.[KIROGRAPH_SERVER_NAME]) {\n delete config.mcpServers[KIROGRAPH_SERVER_NAME];\n if (Object.keys(config.mcpServers).length === 0) delete config.mcpServers;\n writeJson(mcpPath, config);\n console.log(` \u2713 Removed kirograph from .warp/.mcp.json`);\n }\n }\n\n // Remove AGENTS.md block\n const agentsPath = path.join(projectRoot, 'AGENTS.md');\n if (removeGeneratedBlock(agentsPath, WARP_BLOCK_ID)) {\n console.log(` \u2713 Removed KiroGraph block from AGENTS.md (Warp)`);\n }\n}\n\nexport function printWarpNextSteps(): void {\n console.log('\\n Done! Restart Warp for the MCP server to load.');\n console.log(' MCP is in .warp/.mcp.json');\n console.log(' KiroGraph instructions are in AGENTS.md\\n');\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,SAAoB;AACpB,WAAsB;AAEtB,oBAUO;AACP,0BAAuC;AAEvC,MAAM,gBAAgB;AAEf,SAAS,iBAAiB,aAA2B;AAE1D,QAAM,UAAU,KAAK,KAAK,aAAa,SAAS,WAAW;AAC3D,+BAAU,KAAK,QAAQ,OAAO,CAAC;AAC/B,QAAM,aAAS,wBAAS,OAAO;AAC/B,SAAO,aAAa,OAAO,cAAc,CAAC;AAC1C,SAAO,WAAW,mCAAqB,IAAI;AAAA,IACzC,SAAS;AAAA,IACT,MAAM;AAAA,EACR;AACA,+BAAU,SAAS,MAAM;AACzB,UAAQ,IAAI,0CAAqC,OAAO,EAAE;AAC5D;AAEO,SAAS,gBAAgB,aAAqB,aAAmC,uBAAgC,cAA8B;AACpJ,QAAM,WAAO,oCAAqB,aAAa,uBAAuB,YAAY;AAElF,QAAM,mBAAmB,KAAK,KAAK,aAAa,cAAc,SAAS;AACvE,+BAAU,KAAK,QAAQ,gBAAgB,CAAC;AACxC,KAAG,cAAc,sBAAkB,4CAAuB,IAAI,CAAC;AAC/D,UAAQ,IAAI,yCAAoC,gBAAgB,EAAE;AAGlE,QAAM,aAAa,KAAK,KAAK,aAAa,WAAW;AACrD,QAAM,cAAU,oCAAqB,YAAY,eAAe,oBAAgB,4CAAuB,IAAI,CAAC;AAC5G,UAAQ,IAAI,UACR,kEACA,uCAAkC;AAGtC,QAAM,aAAa,KAAK,KAAK,aAAa,SAAS,SAAS,cAAc;AAC1E,MAAI,GAAG,WAAW,UAAU,GAAG;AAC7B,OAAG,WAAW,UAAU;AACxB,YAAQ,IAAI,kDAA6C;AAAA,EAC3D;AACF;AAEO,SAAS,WAAW,aAA2B;AAEpD,QAAM,UAAU,KAAK,KAAK,aAAa,SAAS,WAAW;AAC3D,MAAI,GAAG,WAAW,OAAO,GAAG;AAC1B,UAAM,aAAS,wBAAS,OAAO;AAC/B,QAAI,OAAO,aAAa,mCAAqB,GAAG;AAC9C,aAAO,OAAO,WAAW,mCAAqB;AAC9C,UAAI,OAAO,KAAK,OAAO,UAAU,EAAE,WAAW,EAAG,QAAO,OAAO;AAC/D,mCAAU,SAAS,MAAM;AACzB,cAAQ,IAAI,iDAA4C;AAAA,IAC1D;AAAA,EACF;AAGA,QAAM,aAAa,KAAK,KAAK,aAAa,WAAW;AACrD,UAAI,oCAAqB,YAAY,aAAa,GAAG;AACnD,YAAQ,IAAI,wDAAmD;AAAA,EACjE;AACF;AAEO,SAAS,qBAA2B;AACzC,UAAQ,IAAI,oDAAoD;AAChE,UAAQ,IAAI,6BAA6B;AACzC,UAAQ,IAAI,6CAA6C;AAC3D;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
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
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var windsurf_exports = {};
|
|
30
|
+
__export(windsurf_exports, {
|
|
31
|
+
installWindsurfEarly: () => installWindsurfEarly,
|
|
32
|
+
installWindsurfLate: () => installWindsurfLate,
|
|
33
|
+
printWindsurfNextSteps: () => printWindsurfNextSteps,
|
|
34
|
+
uninitWindsurf: () => uninitWindsurf
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(windsurf_exports);
|
|
37
|
+
var fs = __toESM(require("fs"));
|
|
38
|
+
var path = __toESM(require("path"));
|
|
39
|
+
var import_common = require("../common");
|
|
40
|
+
var import_instructions = require("../instructions");
|
|
41
|
+
const WINDSURF_RULES_FILE = "kirograph.md";
|
|
42
|
+
function buildWindsurfHooks() {
|
|
43
|
+
return {
|
|
44
|
+
hooks: {
|
|
45
|
+
post_cascade_response: [
|
|
46
|
+
{ command: "kirograph sync --quiet 2>/dev/null || true", show_output: false }
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function buildWindsurfRule(instructions) {
|
|
52
|
+
const frontmatter = [
|
|
53
|
+
"---",
|
|
54
|
+
"trigger: always_on",
|
|
55
|
+
"---",
|
|
56
|
+
""
|
|
57
|
+
].join("\n");
|
|
58
|
+
return frontmatter + instructions;
|
|
59
|
+
}
|
|
60
|
+
function installWindsurfEarly(_projectRoot) {
|
|
61
|
+
}
|
|
62
|
+
function installWindsurfLate(projectRoot, cavemanMode, shellCompressionLevel, enableMemory) {
|
|
63
|
+
const opts = (0, import_common.buildInstructionOpts)(cavemanMode, shellCompressionLevel, enableMemory, true);
|
|
64
|
+
const instructionsPath = path.join(projectRoot, ".kirograph", "windsurf.md");
|
|
65
|
+
(0, import_common.ensureDir)(path.dirname(instructionsPath));
|
|
66
|
+
fs.writeFileSync(instructionsPath, (0, import_instructions.buildAgentInstructions)(opts));
|
|
67
|
+
console.log(` \u2713 Windsurf instructions written to ${instructionsPath}`);
|
|
68
|
+
const rulesDir = path.join(projectRoot, ".windsurf", "rules");
|
|
69
|
+
(0, import_common.ensureDir)(rulesDir);
|
|
70
|
+
const rulePath = path.join(rulesDir, WINDSURF_RULES_FILE);
|
|
71
|
+
fs.writeFileSync(rulePath, buildWindsurfRule((0, import_instructions.buildAgentInstructions)(opts)));
|
|
72
|
+
console.log(` \u2713 Windsurf rule written to ${rulePath}`);
|
|
73
|
+
const legacyPath = path.join(projectRoot, ".windsurfrules");
|
|
74
|
+
if (fs.existsSync(legacyPath)) {
|
|
75
|
+
const content = fs.readFileSync(legacyPath, "utf8");
|
|
76
|
+
if (content.includes("kirograph")) {
|
|
77
|
+
fs.unlinkSync(legacyPath);
|
|
78
|
+
console.log(` \u2713 Removed legacy .windsurfrules (migrated to .windsurf/rules/)`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const hooksPath = path.join(projectRoot, ".windsurf", "hooks.json");
|
|
82
|
+
const existing = (0, import_common.readJson)(hooksPath);
|
|
83
|
+
const kgHooks = buildWindsurfHooks();
|
|
84
|
+
existing.hooks = existing.hooks ?? {};
|
|
85
|
+
for (const [event, commands] of Object.entries(kgHooks.hooks)) {
|
|
86
|
+
existing.hooks[event] = existing.hooks[event] ?? [];
|
|
87
|
+
for (const cmd of commands) {
|
|
88
|
+
if (!existing.hooks[event].some((h) => h.command === cmd.command)) {
|
|
89
|
+
existing.hooks[event].push(cmd);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
(0, import_common.writeJson)(hooksPath, existing);
|
|
94
|
+
console.log(` \u2713 Windsurf hooks written to ${hooksPath}`);
|
|
95
|
+
}
|
|
96
|
+
function uninitWindsurf(projectRoot) {
|
|
97
|
+
const rulePath = path.join(projectRoot, ".windsurf", "rules", WINDSURF_RULES_FILE);
|
|
98
|
+
if (fs.existsSync(rulePath)) {
|
|
99
|
+
fs.unlinkSync(rulePath);
|
|
100
|
+
console.log(` \u2713 Removed .windsurf/rules/${WINDSURF_RULES_FILE}`);
|
|
101
|
+
}
|
|
102
|
+
const legacyPath = path.join(projectRoot, ".windsurfrules");
|
|
103
|
+
if (fs.existsSync(legacyPath)) {
|
|
104
|
+
const content = fs.readFileSync(legacyPath, "utf8");
|
|
105
|
+
if (content.includes("kirograph")) {
|
|
106
|
+
fs.unlinkSync(legacyPath);
|
|
107
|
+
console.log(` \u2713 Removed legacy .windsurfrules`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const hooksPath = path.join(projectRoot, ".windsurf", "hooks.json");
|
|
111
|
+
if (fs.existsSync(hooksPath)) {
|
|
112
|
+
const config = (0, import_common.readJson)(hooksPath);
|
|
113
|
+
if (config.hooks) {
|
|
114
|
+
let changed = false;
|
|
115
|
+
for (const event of Object.keys(config.hooks)) {
|
|
116
|
+
const before = config.hooks[event].length;
|
|
117
|
+
config.hooks[event] = config.hooks[event].filter((h) => !h.command?.includes("kirograph"));
|
|
118
|
+
if (config.hooks[event].length === 0) delete config.hooks[event];
|
|
119
|
+
if (config.hooks[event]?.length !== before) changed = true;
|
|
120
|
+
}
|
|
121
|
+
if (Object.keys(config.hooks).length === 0) delete config.hooks;
|
|
122
|
+
if (changed) {
|
|
123
|
+
(0, import_common.writeJson)(hooksPath, config);
|
|
124
|
+
console.log(` \u2713 Removed kirograph hooks from .windsurf/hooks.json`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function printWindsurfNextSteps(projectRoot) {
|
|
130
|
+
console.log("\n Done! KiroGraph rule is in .windsurf/rules/kirograph.md");
|
|
131
|
+
console.log(" Auto-sync hook is in .windsurf/hooks.json");
|
|
132
|
+
(0, import_common.printMcpSetup)("~/.codeium/windsurf/mcp_config.json", projectRoot);
|
|
133
|
+
}
|
|
134
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
135
|
+
0 && (module.exports = {
|
|
136
|
+
installWindsurfEarly,
|
|
137
|
+
installWindsurfLate,
|
|
138
|
+
printWindsurfNextSteps,
|
|
139
|
+
uninitWindsurf
|
|
140
|
+
});
|
|
141
|
+
//# sourceMappingURL=windsurf.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/bin/installer/targets/windsurf.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Windsurf target.\n *\n * MCP: user-scoped at ~/.codeium/windsurf/mcp_config.json (print instructions)\n * Rules: .windsurf/rules/kirograph.md (workspace-level, with frontmatter)\n * Hooks: .windsurf/hooks.json (workspace-level)\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { CavemanMode } from '../caveman';\nimport {\n ensureDir,\n buildInstructionOpts,\n readJson,\n writeJson,\n printMcpSetup,\n} from '../common';\nimport { buildAgentInstructions } from '../instructions';\n\nconst WINDSURF_RULES_FILE = 'kirograph.md';\n\nfunction buildWindsurfHooks(): object {\n return {\n hooks: {\n post_cascade_response: [\n { command: 'kirograph sync --quiet 2>/dev/null || true', show_output: false },\n ],\n },\n };\n}\n\nfunction buildWindsurfRule(instructions: string): string {\n const frontmatter = [\n '---',\n 'trigger: always_on',\n '---',\n '',\n ].join('\\n');\n return frontmatter + instructions;\n}\n\nexport function installWindsurfEarly(_projectRoot: string): void {\n // Windsurf MCP is user-scoped at ~/.codeium/windsurf/mcp_config.json.\n // We print the setup instructions in printNextSteps.\n}\n\nexport function installWindsurfLate(projectRoot: string, cavemanMode?: CavemanMode | 'off', shellCompressionLevel?: string, enableMemory?: boolean): void {\n const opts = buildInstructionOpts(cavemanMode, shellCompressionLevel, enableMemory, true);\n\n const instructionsPath = path.join(projectRoot, '.kirograph', 'windsurf.md');\n ensureDir(path.dirname(instructionsPath));\n fs.writeFileSync(instructionsPath, buildAgentInstructions(opts));\n console.log(` \u2713 Windsurf instructions written to ${instructionsPath}`);\n\n // Write rules file inside .windsurf/rules/ with frontmatter\n const rulesDir = path.join(projectRoot, '.windsurf', 'rules');\n ensureDir(rulesDir);\n const rulePath = path.join(rulesDir, WINDSURF_RULES_FILE);\n fs.writeFileSync(rulePath, buildWindsurfRule(buildAgentInstructions(opts)));\n console.log(` \u2713 Windsurf rule written to ${rulePath}`);\n\n // Remove legacy .windsurfrules if it exists and was created by us\n const legacyPath = path.join(projectRoot, '.windsurfrules');\n if (fs.existsSync(legacyPath)) {\n const content = fs.readFileSync(legacyPath, 'utf8');\n if (content.includes('kirograph')) {\n fs.unlinkSync(legacyPath);\n console.log(` \u2713 Removed legacy .windsurfrules (migrated to .windsurf/rules/)`);\n }\n }\n\n // Write hooks\n const hooksPath = path.join(projectRoot, '.windsurf', 'hooks.json');\n const existing = readJson(hooksPath);\n const kgHooks = buildWindsurfHooks() as any;\n existing.hooks = existing.hooks ?? {};\n for (const [event, commands] of Object.entries(kgHooks.hooks)) {\n existing.hooks[event] = existing.hooks[event] ?? [];\n for (const cmd of commands as Array<{ command: string; show_output: boolean }>) {\n if (!existing.hooks[event].some((h: any) => h.command === cmd.command)) {\n existing.hooks[event].push(cmd);\n }\n }\n }\n writeJson(hooksPath, existing);\n console.log(` \u2713 Windsurf hooks written to ${hooksPath}`);\n}\n\nexport function uninitWindsurf(projectRoot: string): void {\n // Remove rule file\n const rulePath = path.join(projectRoot, '.windsurf', 'rules', WINDSURF_RULES_FILE);\n if (fs.existsSync(rulePath)) {\n fs.unlinkSync(rulePath);\n console.log(` \u2713 Removed .windsurf/rules/${WINDSURF_RULES_FILE}`);\n }\n\n // Remove legacy .windsurfrules block\n const legacyPath = path.join(projectRoot, '.windsurfrules');\n if (fs.existsSync(legacyPath)) {\n const content = fs.readFileSync(legacyPath, 'utf8');\n if (content.includes('kirograph')) {\n fs.unlinkSync(legacyPath);\n console.log(` \u2713 Removed legacy .windsurfrules`);\n }\n }\n\n // Remove kirograph hooks\n const hooksPath = path.join(projectRoot, '.windsurf', 'hooks.json');\n if (fs.existsSync(hooksPath)) {\n const config = readJson(hooksPath);\n if (config.hooks) {\n let changed = false;\n for (const event of Object.keys(config.hooks)) {\n const before = config.hooks[event].length;\n config.hooks[event] = config.hooks[event].filter((h: any) => !h.command?.includes('kirograph'));\n if (config.hooks[event].length === 0) delete config.hooks[event];\n if (config.hooks[event]?.length !== before) changed = true;\n }\n if (Object.keys(config.hooks).length === 0) delete config.hooks;\n if (changed) {\n writeJson(hooksPath, config);\n console.log(` \u2713 Removed kirograph hooks from .windsurf/hooks.json`);\n }\n }\n }\n}\n\nexport function printWindsurfNextSteps(projectRoot: string): void {\n console.log('\\n Done! KiroGraph rule is in .windsurf/rules/kirograph.md');\n console.log(' Auto-sync hook is in .windsurf/hooks.json');\n printMcpSetup('~/.codeium/windsurf/mcp_config.json', projectRoot);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/bin/kirograph.js
CHANGED
|
@@ -31,6 +31,7 @@ var import_export = require("./commands/export");
|
|
|
31
31
|
var import_gain = require("./commands/gain");
|
|
32
32
|
var import_compression = require("./commands/compression");
|
|
33
33
|
var import_exec = require("./commands/exec");
|
|
34
|
+
var import_memory = require("./commands/memory");
|
|
34
35
|
process.on("uncaughtException", (err) => {
|
|
35
36
|
const msg = err?.message ?? String(err);
|
|
36
37
|
const isWasmAbort = msg.includes("Aborted(") || msg.includes("RuntimeError") || err?.constructor?.name === "RuntimeError";
|
|
@@ -59,7 +60,7 @@ process.on("uncaughtException", (err) => {
|
|
|
59
60
|
process.exit(1);
|
|
60
61
|
});
|
|
61
62
|
const program = new import_commander.Command();
|
|
62
|
-
program.name("kirograph").description("Semantic code knowledge graph for Kiro").version("0.
|
|
63
|
+
program.name("kirograph").description("Semantic code knowledge graph for Kiro").version("0.15.0").addHelpCommand(true).hook("preAction", (thisCommand) => {
|
|
63
64
|
const name = thisCommand.name();
|
|
64
65
|
if (name === "init") (0, import_banner.printBanner)();
|
|
65
66
|
});
|
|
@@ -91,6 +92,7 @@ program.name("kirograph").description("Semantic code knowledge graph for Kiro").
|
|
|
91
92
|
(0, import_gain.register)(program);
|
|
92
93
|
(0, import_compression.register)(program);
|
|
93
94
|
(0, import_exec.register)(program);
|
|
95
|
+
(0, import_memory.register)(program);
|
|
94
96
|
if (process.argv.length === 2) {
|
|
95
97
|
(0, import_banner.printBanner)();
|
|
96
98
|
(0, import_help.printColoredHelp)();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/bin/kirograph.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n/**\n * KiroGraph CLI\n */\n\nimport { Command } from 'commander';\nimport { printBanner } from './banner';\nimport { printColoredHelp, register as registerHelp } from './commands/help';\nimport { register as registerInit } from './commands/init';\nimport { register as registerUninit } from './commands/uninit';\nimport { register as registerIndex } from './commands/index';\nimport { register as registerSync } from './commands/sync';\nimport { register as registerStatus } from './commands/status';\nimport { register as registerQuery } from './commands/query';\nimport { register as registerFiles } from './commands/files';\nimport { register as registerContext } from './commands/context';\nimport { register as registerAffected } from './commands/affected';\nimport { register as registerMarkDirty } from './commands/mark-dirty';\nimport { register as registerSyncIfDirty } from './commands/sync-if-dirty';\nimport { register as registerUnlock } from './commands/unlock';\nimport { register as registerInstall } from './commands/install';\nimport { register as registerServe } from './commands/serve';\nimport { register as registerDashboard } from './commands/dashboard';\nimport { register as registerArchitecture } from './commands/architecture';\nimport { register as registerCoupling } from './commands/coupling';\nimport { register as registerPackage } from './commands/package';\nimport { register as registerCaveman } from './commands/caveman';\nimport { register as registerDeadCode } from './commands/dead-code';\nimport { register as registerHotspots } from './commands/hotspots';\nimport { register as registerSurprising } from './commands/surprising';\nimport { register as registerSnapshot } from './commands/snapshot';\nimport { register as registerPath } from './commands/path';\nimport { register as registerExport } from './commands/export';\nimport { register as registerGain } from './commands/gain';\nimport { register as registerCompression } from './commands/compression';\nimport { register as registerExec } from './commands/exec';\n\n// \u2500\u2500 Global error handler for WASM runtime crashes \u2500\u2500\u2500\u2500\u2500\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//\n// node-sqlite3-wasm calls process.abort() when it hits a fatal error (e.g.\n// database is locked by another process). This produces a raw \"Aborted()\"\n// message with no context. We intercept it here to print a clear explanation\n// before the process exits.\nprocess.on('uncaughtException', (err: Error) => {\n const msg = err?.message ?? String(err);\n const isWasmAbort = msg.includes('Aborted(') || msg.includes('RuntimeError') || (err as any)?.constructor?.name === 'RuntimeError';\n\n if (isWasmAbort) {\n process.stderr.write([\n '',\n ' \u2716 KiroGraph crashed: SQLite WASM runtime aborted.',\n '',\n ' Most likely cause: another process (e.g. the Kiro MCP server) is',\n ' holding the database open while indexing is running.',\n '',\n ' How to fix:',\n ' 1. Close Kiro IDE (or disable the kirograph MCP server) before indexing',\n ' 2. Run: kirograph unlock',\n ' 3. Then retry: kirograph index',\n '',\n ' If the problem persists, delete the lock manually:',\n ' del .kirograph\\\\kirograph.db.lock (Windows)',\n ' rm -rf .kirograph/kirograph.db.lock (macOS/Linux)',\n '',\n ].join('\\n'));\n process.exit(1);\n }\n\n // Not a WASM crash \u2014 re-throw as normal\n process.stderr.write(`Uncaught error: ${msg}\\n`);\n process.exit(1);\n});\n\ndeclare const __CLI_VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name('kirograph')\n .description('Semantic code knowledge graph for Kiro')\n .version(__CLI_VERSION__)\n .addHelpCommand(true)\n .hook('preAction', (thisCommand) => {\n const name = thisCommand.name();\n if (name === 'init') printBanner();\n });\n\nregisterInstall(program);\nregisterInit(program);\nregisterUninit(program);\nregisterIndex(program);\nregisterSync(program);\nregisterSyncIfDirty(program);\nregisterMarkDirty(program);\nregisterStatus(program);\nregisterQuery(program);\nregisterContext(program);\nregisterFiles(program);\nregisterAffected(program);\nregisterUnlock(program);\nregisterServe(program);\nregisterDashboard(program);\nregisterArchitecture(program);\nregisterCoupling(program);\nregisterPackage(program);\nregisterCaveman(program);\nregisterDeadCode(program);\nregisterHotspots(program);\nregisterSurprising(program);\nregisterSnapshot(program);\nregisterPath(program);\nregisterExport(program);\nregisterGain(program);\nregisterCompression(program);\nregisterExec(program);\n\n// Show banner + help when called with no arguments, otherwise parse normally\nif (process.argv.length === 2) {\n printBanner();\n printColoredHelp();\n process.exit(0);\n}\n\nregisterHelp(program);\n\nprogram.parse(process.argv);\n"],
|
|
5
|
-
"mappings": ";;AAKA,uBAAwB;AACxB,oBAA4B;AAC5B,kBAA2D;AAC3D,kBAAyC;AACzC,oBAA2C;AAC3C,sBAA0C;AAC1C,kBAAyC;AACzC,oBAA2C;AAC3C,mBAA0C;AAC1C,mBAA0C;AAC1C,qBAA4C;AAC5C,sBAA6C;AAC7C,wBAA8C;AAC9C,2BAAgD;AAChD,oBAA2C;AAC3C,qBAA4C;AAC5C,mBAA0C;AAC1C,uBAA8C;AAC9C,0BAAiD;AACjD,sBAA6C;AAC7C,qBAA4C;AAC5C,qBAA4C;AAC5C,uBAA6C;AAC7C,sBAA6C;AAC7C,wBAA+C;AAC/C,sBAA6C;AAC7C,kBAAyC;AACzC,oBAA2C;AAC3C,kBAAyC;AACzC,yBAAgD;AAChD,kBAAyC;
|
|
6
|
-
"names": ["registerInstall", "registerInit", "registerUninit", "registerIndex", "registerSync", "registerSyncIfDirty", "registerMarkDirty", "registerStatus", "registerQuery", "registerContext", "registerFiles", "registerAffected", "registerUnlock", "registerServe", "registerDashboard", "registerArchitecture", "registerCoupling", "registerPackage", "registerCaveman", "registerDeadCode", "registerHotspots", "registerSurprising", "registerSnapshot", "registerPath", "registerExport", "registerGain", "registerCompression", "registerExec", "registerHelp"]
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n/**\n * KiroGraph CLI\n */\n\nimport { Command } from 'commander';\nimport { printBanner } from './banner';\nimport { printColoredHelp, register as registerHelp } from './commands/help';\nimport { register as registerInit } from './commands/init';\nimport { register as registerUninit } from './commands/uninit';\nimport { register as registerIndex } from './commands/index';\nimport { register as registerSync } from './commands/sync';\nimport { register as registerStatus } from './commands/status';\nimport { register as registerQuery } from './commands/query';\nimport { register as registerFiles } from './commands/files';\nimport { register as registerContext } from './commands/context';\nimport { register as registerAffected } from './commands/affected';\nimport { register as registerMarkDirty } from './commands/mark-dirty';\nimport { register as registerSyncIfDirty } from './commands/sync-if-dirty';\nimport { register as registerUnlock } from './commands/unlock';\nimport { register as registerInstall } from './commands/install';\nimport { register as registerServe } from './commands/serve';\nimport { register as registerDashboard } from './commands/dashboard';\nimport { register as registerArchitecture } from './commands/architecture';\nimport { register as registerCoupling } from './commands/coupling';\nimport { register as registerPackage } from './commands/package';\nimport { register as registerCaveman } from './commands/caveman';\nimport { register as registerDeadCode } from './commands/dead-code';\nimport { register as registerHotspots } from './commands/hotspots';\nimport { register as registerSurprising } from './commands/surprising';\nimport { register as registerSnapshot } from './commands/snapshot';\nimport { register as registerPath } from './commands/path';\nimport { register as registerExport } from './commands/export';\nimport { register as registerGain } from './commands/gain';\nimport { register as registerCompression } from './commands/compression';\nimport { register as registerExec } from './commands/exec';\nimport { register as registerMemory } from './commands/memory';\n\n// \u2500\u2500 Global error handler for WASM runtime crashes \u2500\u2500\u2500\u2500\u2500\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//\n// node-sqlite3-wasm calls process.abort() when it hits a fatal error (e.g.\n// database is locked by another process). This produces a raw \"Aborted()\"\n// message with no context. We intercept it here to print a clear explanation\n// before the process exits.\nprocess.on('uncaughtException', (err: Error) => {\n const msg = err?.message ?? String(err);\n const isWasmAbort = msg.includes('Aborted(') || msg.includes('RuntimeError') || (err as any)?.constructor?.name === 'RuntimeError';\n\n if (isWasmAbort) {\n process.stderr.write([\n '',\n ' \u2716 KiroGraph crashed: SQLite WASM runtime aborted.',\n '',\n ' Most likely cause: another process (e.g. the Kiro MCP server) is',\n ' holding the database open while indexing is running.',\n '',\n ' How to fix:',\n ' 1. Close Kiro IDE (or disable the kirograph MCP server) before indexing',\n ' 2. Run: kirograph unlock',\n ' 3. Then retry: kirograph index',\n '',\n ' If the problem persists, delete the lock manually:',\n ' del .kirograph\\\\kirograph.db.lock (Windows)',\n ' rm -rf .kirograph/kirograph.db.lock (macOS/Linux)',\n '',\n ].join('\\n'));\n process.exit(1);\n }\n\n // Not a WASM crash \u2014 re-throw as normal\n process.stderr.write(`Uncaught error: ${msg}\\n`);\n process.exit(1);\n});\n\ndeclare const __CLI_VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name('kirograph')\n .description('Semantic code knowledge graph for Kiro')\n .version(__CLI_VERSION__)\n .addHelpCommand(true)\n .hook('preAction', (thisCommand) => {\n const name = thisCommand.name();\n if (name === 'init') printBanner();\n });\n\nregisterInstall(program);\nregisterInit(program);\nregisterUninit(program);\nregisterIndex(program);\nregisterSync(program);\nregisterSyncIfDirty(program);\nregisterMarkDirty(program);\nregisterStatus(program);\nregisterQuery(program);\nregisterContext(program);\nregisterFiles(program);\nregisterAffected(program);\nregisterUnlock(program);\nregisterServe(program);\nregisterDashboard(program);\nregisterArchitecture(program);\nregisterCoupling(program);\nregisterPackage(program);\nregisterCaveman(program);\nregisterDeadCode(program);\nregisterHotspots(program);\nregisterSurprising(program);\nregisterSnapshot(program);\nregisterPath(program);\nregisterExport(program);\nregisterGain(program);\nregisterCompression(program);\nregisterExec(program);\nregisterMemory(program);\n\n// Show banner + help when called with no arguments, otherwise parse normally\nif (process.argv.length === 2) {\n printBanner();\n printColoredHelp();\n process.exit(0);\n}\n\nregisterHelp(program);\n\nprogram.parse(process.argv);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["registerInstall", "registerInit", "registerUninit", "registerIndex", "registerSync", "registerSyncIfDirty", "registerMarkDirty", "registerStatus", "registerQuery", "registerContext", "registerFiles", "registerAffected", "registerUnlock", "registerServe", "registerDashboard", "registerArchitecture", "registerCoupling", "registerPackage", "registerCaveman", "registerDeadCode", "registerHotspots", "registerSurprising", "registerSnapshot", "registerPath", "registerExport", "registerGain", "registerCompression", "registerExec", "registerMemory", "registerHelp"]
|
|
7
7
|
}
|
|
@@ -82,6 +82,20 @@ function estimateNaiveCost(toolName, outputTokens, args) {
|
|
|
82
82
|
case "kirograph_diff": {
|
|
83
83
|
return Math.max(outputTokens * 3, AVG_FILE_TOKENS * 5);
|
|
84
84
|
}
|
|
85
|
+
case "kirograph_mem_search": {
|
|
86
|
+
const limit = args?.limit || 10;
|
|
87
|
+
const filesEstimate = Math.min(Math.ceil(limit / 2), 5);
|
|
88
|
+
return filesEstimate * AVG_FILE_TOKENS + AVG_GREP_TOKENS;
|
|
89
|
+
}
|
|
90
|
+
case "kirograph_mem_store": {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
case "kirograph_mem_timeline": {
|
|
94
|
+
return AVG_FILE_TOKENS + AVG_GREP_TOKENS;
|
|
95
|
+
}
|
|
96
|
+
case "kirograph_mem_status": {
|
|
97
|
+
return 500;
|
|
98
|
+
}
|
|
85
99
|
// kirograph_exec and kirograph_gain are tracked separately
|
|
86
100
|
default:
|
|
87
101
|
return null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/compression/naive-cost.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Naive cost estimator for KiroGraph MCP tools.\n *\n * Estimates how many tokens the agent would have consumed doing the same\n * work without KiroGraph (reading files, running grep, etc.).\n *\n * These are conservative estimates based on typical agent behavior:\n * - kirograph_context: agent would read 5-10 files fully to orient\n * - kirograph_search: agent would run grep/ripgrep across the project\n * - kirograph_callers/callees: agent would grep for the symbol name + read each file\n * - kirograph_impact: agent would trace callers recursively (multiple grep + read cycles)\n * - kirograph_node: agent would read the full file containing the symbol\n * - kirograph_files: agent would run find/ls -R\n * - kirograph_status: agent would check file counts, run wc, etc.\n * - kirograph_hotspots/surprising/dead_code: not feasible manually (infinite cost \u2192 cap at 5x)\n */\n\nimport { estimateTokens } from './index';\n\n/** Average tokens per file read (medium-sized source file ~200 lines) */\nconst AVG_FILE_TOKENS = 1500;\n\n/** Average tokens for a grep result across a medium project */\nconst AVG_GREP_TOKENS = 800;\n\n/** Average tokens for ls -R or find output on a medium project */\nconst AVG_FIND_TOKENS = 2000;\n\n/**\n * Estimate the naive token cost (what the agent would have spent without KiroGraph).\n *\n * @param toolName - The MCP tool that was called\n * @param outputTokens - Actual tokens in the tool's response\n * @param args - The tool arguments (for context-aware estimation)\n * @returns Estimated naive cost in tokens, or null if not estimable\n */\nexport function estimateNaiveCost(toolName: string, outputTokens: number, args?: Record<string, unknown>): number | null {\n switch (toolName) {\n case 'kirograph_context': {\n // Agent would read ~5-10 files to understand a task area\n const maxNodes = (args?.maxNodes as number) || 20;\n const filesEstimate = Math.min(Math.ceil(maxNodes / 2), 10);\n return filesEstimate * AVG_FILE_TOKENS;\n }\n\n case 'kirograph_search': {\n // Agent would run grep/ripgrep and read through results\n const limit = (args?.limit as number) || 10;\n // grep output + reading top matches\n return AVG_GREP_TOKENS + Math.min(limit, 5) * (AVG_FILE_TOKENS / 3);\n }\n\n case 'kirograph_callers': {\n // Agent would grep for the symbol, then read each calling file\n const limit = (args?.limit as number) || 20;\n const callersEstimate = Math.min(limit, 10);\n return AVG_GREP_TOKENS + callersEstimate * (AVG_FILE_TOKENS / 2);\n }\n\n case 'kirograph_callees': {\n // Agent would read the function body + grep for each called symbol\n return AVG_FILE_TOKENS + AVG_GREP_TOKENS * 3;\n }\n\n case 'kirograph_impact': {\n // Agent would need multiple rounds of grep + read (recursive)\n const depth = (args?.depth as number) || 2;\n return (AVG_GREP_TOKENS + AVG_FILE_TOKENS * 3) * depth;\n }\n\n case 'kirograph_node': {\n // Agent would read the full file to find the symbol\n return AVG_FILE_TOKENS;\n }\n\n case 'kirograph_files': {\n // Agent would run find or ls -R\n return AVG_FIND_TOKENS;\n }\n\n case 'kirograph_status': {\n // Agent would run multiple commands (wc -l, find, du, etc.)\n return 500;\n }\n\n case 'kirograph_path': {\n // Agent would need to manually trace connections \u2014 multiple grep + read cycles\n return AVG_GREP_TOKENS * 4 + AVG_FILE_TOKENS * 3;\n }\n\n case 'kirograph_type_hierarchy': {\n // Agent would grep for extends/implements, read each file\n return AVG_GREP_TOKENS * 3 + AVG_FILE_TOKENS * 2;\n }\n\n case 'kirograph_dead_code': {\n // Not feasible manually \u2014 would require reading every file and cross-referencing\n // Cap at 5x the output (conservative)\n return Math.max(outputTokens * 5, AVG_FILE_TOKENS * 10);\n }\n\n case 'kirograph_circular_deps': {\n // Not feasible manually \u2014 would require building a full import graph\n return Math.max(outputTokens * 5, AVG_FILE_TOKENS * 8);\n }\n\n case 'kirograph_hotspots': {\n // Not feasible manually \u2014 would require counting edges for every symbol\n return Math.max(outputTokens * 5, AVG_FILE_TOKENS * 10);\n }\n\n case 'kirograph_surprising': {\n // Not feasible manually\n return Math.max(outputTokens * 5, AVG_FILE_TOKENS * 10);\n }\n\n case 'kirograph_architecture':\n case 'kirograph_coupling':\n case 'kirograph_package': {\n // Architecture analysis is not feasible manually\n return Math.max(outputTokens * 4, AVG_FILE_TOKENS * 5);\n }\n\n case 'kirograph_diff': {\n // Agent would need to compare file lists and grep for symbols\n return Math.max(outputTokens * 3, AVG_FILE_TOKENS * 5);\n }\n\n // kirograph_exec and kirograph_gain are tracked separately\n default:\n return null;\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBA,MAAM,kBAAkB;AAGxB,MAAM,kBAAkB;AAGxB,MAAM,kBAAkB;AAUjB,SAAS,kBAAkB,UAAkB,cAAsB,MAA+C;AACvH,UAAQ,UAAU;AAAA,IAChB,KAAK,qBAAqB;AAExB,YAAM,WAAY,MAAM,YAAuB;AAC/C,YAAM,gBAAgB,KAAK,IAAI,KAAK,KAAK,WAAW,CAAC,GAAG,EAAE;AAC1D,aAAO,gBAAgB;AAAA,IACzB;AAAA,IAEA,KAAK,oBAAoB;AAEvB,YAAM,QAAS,MAAM,SAAoB;AAEzC,aAAO,kBAAkB,KAAK,IAAI,OAAO,CAAC,KAAK,kBAAkB;AAAA,IACnE;AAAA,IAEA,KAAK,qBAAqB;AAExB,YAAM,QAAS,MAAM,SAAoB;AACzC,YAAM,kBAAkB,KAAK,IAAI,OAAO,EAAE;AAC1C,aAAO,kBAAkB,mBAAmB,kBAAkB;AAAA,IAChE;AAAA,IAEA,KAAK,qBAAqB;AAExB,aAAO,kBAAkB,kBAAkB;AAAA,IAC7C;AAAA,IAEA,KAAK,oBAAoB;AAEvB,YAAM,QAAS,MAAM,SAAoB;AACzC,cAAQ,kBAAkB,kBAAkB,KAAK;AAAA,IACnD;AAAA,IAEA,KAAK,kBAAkB;AAErB,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,mBAAmB;AAEtB,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,oBAAoB;AAEvB,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,kBAAkB;AAErB,aAAO,kBAAkB,IAAI,kBAAkB;AAAA,IACjD;AAAA,IAEA,KAAK,4BAA4B;AAE/B,aAAO,kBAAkB,IAAI,kBAAkB;AAAA,IACjD;AAAA,IAEA,KAAK,uBAAuB;AAG1B,aAAO,KAAK,IAAI,eAAe,GAAG,kBAAkB,EAAE;AAAA,IACxD;AAAA,IAEA,KAAK,2BAA2B;AAE9B,aAAO,KAAK,IAAI,eAAe,GAAG,kBAAkB,CAAC;AAAA,IACvD;AAAA,IAEA,KAAK,sBAAsB;AAEzB,aAAO,KAAK,IAAI,eAAe,GAAG,kBAAkB,EAAE;AAAA,IACxD;AAAA,IAEA,KAAK,wBAAwB;AAE3B,aAAO,KAAK,IAAI,eAAe,GAAG,kBAAkB,EAAE;AAAA,IACxD;AAAA,IAEA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,qBAAqB;AAExB,aAAO,KAAK,IAAI,eAAe,GAAG,kBAAkB,CAAC;AAAA,IACvD;AAAA,IAEA,KAAK,kBAAkB;AAErB,aAAO,KAAK,IAAI,eAAe,GAAG,kBAAkB,CAAC;AAAA,IACvD;AAAA;AAAA,IAGA;AACE,aAAO;AAAA,EACX;AACF;",
|
|
4
|
+
"sourcesContent": ["/**\n * Naive cost estimator for KiroGraph MCP tools.\n *\n * Estimates how many tokens the agent would have consumed doing the same\n * work without KiroGraph (reading files, running grep, etc.).\n *\n * These are conservative estimates based on typical agent behavior:\n * - kirograph_context: agent would read 5-10 files fully to orient\n * - kirograph_search: agent would run grep/ripgrep across the project\n * - kirograph_callers/callees: agent would grep for the symbol name + read each file\n * - kirograph_impact: agent would trace callers recursively (multiple grep + read cycles)\n * - kirograph_node: agent would read the full file containing the symbol\n * - kirograph_files: agent would run find/ls -R\n * - kirograph_status: agent would check file counts, run wc, etc.\n * - kirograph_hotspots/surprising/dead_code: not feasible manually (infinite cost \u2192 cap at 5x)\n */\n\nimport { estimateTokens } from './index';\n\n/** Average tokens per file read (medium-sized source file ~200 lines) */\nconst AVG_FILE_TOKENS = 1500;\n\n/** Average tokens for a grep result across a medium project */\nconst AVG_GREP_TOKENS = 800;\n\n/** Average tokens for ls -R or find output on a medium project */\nconst AVG_FIND_TOKENS = 2000;\n\n/**\n * Estimate the naive token cost (what the agent would have spent without KiroGraph).\n *\n * @param toolName - The MCP tool that was called\n * @param outputTokens - Actual tokens in the tool's response\n * @param args - The tool arguments (for context-aware estimation)\n * @returns Estimated naive cost in tokens, or null if not estimable\n */\nexport function estimateNaiveCost(toolName: string, outputTokens: number, args?: Record<string, unknown>): number | null {\n switch (toolName) {\n case 'kirograph_context': {\n // Agent would read ~5-10 files to understand a task area\n const maxNodes = (args?.maxNodes as number) || 20;\n const filesEstimate = Math.min(Math.ceil(maxNodes / 2), 10);\n return filesEstimate * AVG_FILE_TOKENS;\n }\n\n case 'kirograph_search': {\n // Agent would run grep/ripgrep and read through results\n const limit = (args?.limit as number) || 10;\n // grep output + reading top matches\n return AVG_GREP_TOKENS + Math.min(limit, 5) * (AVG_FILE_TOKENS / 3);\n }\n\n case 'kirograph_callers': {\n // Agent would grep for the symbol, then read each calling file\n const limit = (args?.limit as number) || 20;\n const callersEstimate = Math.min(limit, 10);\n return AVG_GREP_TOKENS + callersEstimate * (AVG_FILE_TOKENS / 2);\n }\n\n case 'kirograph_callees': {\n // Agent would read the function body + grep for each called symbol\n return AVG_FILE_TOKENS + AVG_GREP_TOKENS * 3;\n }\n\n case 'kirograph_impact': {\n // Agent would need multiple rounds of grep + read (recursive)\n const depth = (args?.depth as number) || 2;\n return (AVG_GREP_TOKENS + AVG_FILE_TOKENS * 3) * depth;\n }\n\n case 'kirograph_node': {\n // Agent would read the full file to find the symbol\n return AVG_FILE_TOKENS;\n }\n\n case 'kirograph_files': {\n // Agent would run find or ls -R\n return AVG_FIND_TOKENS;\n }\n\n case 'kirograph_status': {\n // Agent would run multiple commands (wc -l, find, du, etc.)\n return 500;\n }\n\n case 'kirograph_path': {\n // Agent would need to manually trace connections \u2014 multiple grep + read cycles\n return AVG_GREP_TOKENS * 4 + AVG_FILE_TOKENS * 3;\n }\n\n case 'kirograph_type_hierarchy': {\n // Agent would grep for extends/implements, read each file\n return AVG_GREP_TOKENS * 3 + AVG_FILE_TOKENS * 2;\n }\n\n case 'kirograph_dead_code': {\n // Not feasible manually \u2014 would require reading every file and cross-referencing\n // Cap at 5x the output (conservative)\n return Math.max(outputTokens * 5, AVG_FILE_TOKENS * 10);\n }\n\n case 'kirograph_circular_deps': {\n // Not feasible manually \u2014 would require building a full import graph\n return Math.max(outputTokens * 5, AVG_FILE_TOKENS * 8);\n }\n\n case 'kirograph_hotspots': {\n // Not feasible manually \u2014 would require counting edges for every symbol\n return Math.max(outputTokens * 5, AVG_FILE_TOKENS * 10);\n }\n\n case 'kirograph_surprising': {\n // Not feasible manually\n return Math.max(outputTokens * 5, AVG_FILE_TOKENS * 10);\n }\n\n case 'kirograph_architecture':\n case 'kirograph_coupling':\n case 'kirograph_package': {\n // Architecture analysis is not feasible manually\n return Math.max(outputTokens * 4, AVG_FILE_TOKENS * 5);\n }\n\n case 'kirograph_diff': {\n // Agent would need to compare file lists and grep for symbols\n return Math.max(outputTokens * 3, AVG_FILE_TOKENS * 5);\n }\n\n case 'kirograph_mem_search': {\n // Without memory, agent would re-read files to rediscover past decisions.\n // Typically 3-5 files + grep for related context.\n const limit = (args?.limit as number) || 10;\n const filesEstimate = Math.min(Math.ceil(limit / 2), 5);\n return filesEstimate * AVG_FILE_TOKENS + AVG_GREP_TOKENS;\n }\n\n case 'kirograph_mem_store': {\n // Storing has no direct naive equivalent \u2014 the knowledge would simply be lost.\n // We don't count savings on store; savings are realized on future searches.\n return null;\n }\n\n case 'kirograph_mem_timeline': {\n // Agent would ask user or re-read previous session context.\n return AVG_FILE_TOKENS + AVG_GREP_TOKENS;\n }\n\n case 'kirograph_mem_status': {\n // Lightweight status check, minimal naive cost.\n return 500;\n }\n\n // kirograph_exec and kirograph_gain are tracked separately\n default:\n return null;\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBA,MAAM,kBAAkB;AAGxB,MAAM,kBAAkB;AAGxB,MAAM,kBAAkB;AAUjB,SAAS,kBAAkB,UAAkB,cAAsB,MAA+C;AACvH,UAAQ,UAAU;AAAA,IAChB,KAAK,qBAAqB;AAExB,YAAM,WAAY,MAAM,YAAuB;AAC/C,YAAM,gBAAgB,KAAK,IAAI,KAAK,KAAK,WAAW,CAAC,GAAG,EAAE;AAC1D,aAAO,gBAAgB;AAAA,IACzB;AAAA,IAEA,KAAK,oBAAoB;AAEvB,YAAM,QAAS,MAAM,SAAoB;AAEzC,aAAO,kBAAkB,KAAK,IAAI,OAAO,CAAC,KAAK,kBAAkB;AAAA,IACnE;AAAA,IAEA,KAAK,qBAAqB;AAExB,YAAM,QAAS,MAAM,SAAoB;AACzC,YAAM,kBAAkB,KAAK,IAAI,OAAO,EAAE;AAC1C,aAAO,kBAAkB,mBAAmB,kBAAkB;AAAA,IAChE;AAAA,IAEA,KAAK,qBAAqB;AAExB,aAAO,kBAAkB,kBAAkB;AAAA,IAC7C;AAAA,IAEA,KAAK,oBAAoB;AAEvB,YAAM,QAAS,MAAM,SAAoB;AACzC,cAAQ,kBAAkB,kBAAkB,KAAK;AAAA,IACnD;AAAA,IAEA,KAAK,kBAAkB;AAErB,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,mBAAmB;AAEtB,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,oBAAoB;AAEvB,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,kBAAkB;AAErB,aAAO,kBAAkB,IAAI,kBAAkB;AAAA,IACjD;AAAA,IAEA,KAAK,4BAA4B;AAE/B,aAAO,kBAAkB,IAAI,kBAAkB;AAAA,IACjD;AAAA,IAEA,KAAK,uBAAuB;AAG1B,aAAO,KAAK,IAAI,eAAe,GAAG,kBAAkB,EAAE;AAAA,IACxD;AAAA,IAEA,KAAK,2BAA2B;AAE9B,aAAO,KAAK,IAAI,eAAe,GAAG,kBAAkB,CAAC;AAAA,IACvD;AAAA,IAEA,KAAK,sBAAsB;AAEzB,aAAO,KAAK,IAAI,eAAe,GAAG,kBAAkB,EAAE;AAAA,IACxD;AAAA,IAEA,KAAK,wBAAwB;AAE3B,aAAO,KAAK,IAAI,eAAe,GAAG,kBAAkB,EAAE;AAAA,IACxD;AAAA,IAEA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,qBAAqB;AAExB,aAAO,KAAK,IAAI,eAAe,GAAG,kBAAkB,CAAC;AAAA,IACvD;AAAA,IAEA,KAAK,kBAAkB;AAErB,aAAO,KAAK,IAAI,eAAe,GAAG,kBAAkB,CAAC;AAAA,IACvD;AAAA,IAEA,KAAK,wBAAwB;AAG3B,YAAM,QAAS,MAAM,SAAoB;AACzC,YAAM,gBAAgB,KAAK,IAAI,KAAK,KAAK,QAAQ,CAAC,GAAG,CAAC;AACtD,aAAO,gBAAgB,kBAAkB;AAAA,IAC3C;AAAA,IAEA,KAAK,uBAAuB;AAG1B,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,0BAA0B;AAE7B,aAAO,kBAAkB;AAAA,IAC3B;AAAA,IAEA,KAAK,wBAAwB;AAE3B,aAAO;AAAA,IACT;AAAA;AAAA,IAGA;AACE,aAAO;AAAA,EACX;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -87,6 +87,15 @@ class TokenTracker {
|
|
|
87
87
|
recordGraphSaving(toolName, outputTokens, naiveCost) {
|
|
88
88
|
this.record(toolName, naiveCost, outputTokens, `graph:${toolName}`, "graph");
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Record a memory tool saving.
|
|
92
|
+
* @param toolName - The MCP tool that was called
|
|
93
|
+
* @param outputTokens - Actual tokens returned by the tool
|
|
94
|
+
* @param naiveCost - Estimated tokens the agent would have used without memory
|
|
95
|
+
*/
|
|
96
|
+
recordMemorySaving(toolName, outputTokens, naiveCost) {
|
|
97
|
+
this.record(toolName, naiveCost, outputTokens, `memory:${toolName}`, "memory");
|
|
98
|
+
}
|
|
90
99
|
/**
|
|
91
100
|
* Get aggregated statistics for a time period.
|
|
92
101
|
*/
|
|
@@ -101,13 +110,13 @@ class TokenTracker {
|
|
|
101
110
|
savingsPercent: 0,
|
|
102
111
|
byFamily: {},
|
|
103
112
|
recentCommands: [],
|
|
104
|
-
bySource: { exec: { count: 0, saved: 0 }, graph: { count: 0, saved: 0 } }
|
|
113
|
+
bySource: { exec: { count: 0, saved: 0 }, graph: { count: 0, saved: 0 }, memory: { count: 0, saved: 0 } }
|
|
105
114
|
};
|
|
106
115
|
}
|
|
107
116
|
let totalOriginal = 0;
|
|
108
117
|
let totalCompressed = 0;
|
|
109
118
|
const byFamily = /* @__PURE__ */ new Map();
|
|
110
|
-
const bySource = { exec: { count: 0, saved: 0 }, graph: { count: 0, saved: 0 } };
|
|
119
|
+
const bySource = { exec: { count: 0, saved: 0 }, graph: { count: 0, saved: 0 }, memory: { count: 0, saved: 0 } };
|
|
111
120
|
for (const r of records) {
|
|
112
121
|
totalOriginal += r.originalTokens;
|
|
113
122
|
totalCompressed += r.compressedTokens;
|
|
@@ -118,8 +127,13 @@ class TokenTracker {
|
|
|
118
127
|
existing.totalCompressed += r.compressedTokens;
|
|
119
128
|
byFamily.set(family, existing);
|
|
120
129
|
const source = r.source || "exec";
|
|
121
|
-
bySource[source]
|
|
122
|
-
|
|
130
|
+
if (bySource[source]) {
|
|
131
|
+
bySource[source].count++;
|
|
132
|
+
bySource[source].saved += r.originalTokens - r.compressedTokens;
|
|
133
|
+
} else {
|
|
134
|
+
bySource.exec.count++;
|
|
135
|
+
bySource.exec.saved += r.originalTokens - r.compressedTokens;
|
|
136
|
+
}
|
|
123
137
|
}
|
|
124
138
|
const totalSaved = totalOriginal - totalCompressed;
|
|
125
139
|
const savingsPercent = totalOriginal > 0 ? Math.round(totalSaved / totalOriginal * 100) : 0;
|