@thejeetsingh/kalcode 2.0.0 → 2.2.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.
Files changed (125) hide show
  1. package/README.md +0 -4
  2. package/dist/bin/kalcode.d.ts +2 -0
  3. package/dist/bin/kalcode.js +12 -0
  4. package/dist/bin/kalcode.js.map +1 -0
  5. package/dist/src/agent/context.d.ts +6 -0
  6. package/dist/src/agent/context.js +60 -0
  7. package/dist/src/agent/context.js.map +1 -0
  8. package/dist/src/agent/history.d.ts +8 -0
  9. package/dist/src/agent/history.js +59 -0
  10. package/dist/src/agent/history.js.map +1 -0
  11. package/dist/src/agent/loop.d.ts +6 -0
  12. package/dist/src/agent/loop.js +235 -0
  13. package/dist/src/agent/loop.js.map +1 -0
  14. package/dist/src/agent/memory.d.ts +2 -0
  15. package/dist/src/agent/memory.js +27 -0
  16. package/dist/src/agent/memory.js.map +1 -0
  17. package/dist/src/agent/permissions.d.ts +5 -0
  18. package/dist/src/agent/permissions.js +66 -0
  19. package/dist/src/agent/permissions.js.map +1 -0
  20. package/dist/src/agent/text-tool-parser.d.ts +2 -0
  21. package/dist/src/agent/text-tool-parser.js +68 -0
  22. package/dist/src/agent/text-tool-parser.js.map +1 -0
  23. package/dist/src/api/client.d.ts +2 -0
  24. package/dist/src/api/client.js +86 -0
  25. package/dist/src/api/client.js.map +1 -0
  26. package/dist/src/api/stream-parser.d.ts +2 -0
  27. package/dist/src/api/stream-parser.js +97 -0
  28. package/dist/src/api/stream-parser.js.map +1 -0
  29. package/dist/src/config.d.ts +7 -0
  30. package/dist/src/config.js +52 -0
  31. package/dist/src/config.js.map +1 -0
  32. package/dist/src/constants.d.ts +25 -0
  33. package/{src/constants.ts → dist/src/constants.js} +17 -19
  34. package/dist/src/constants.js.map +1 -0
  35. package/dist/src/git/git.d.ts +15 -0
  36. package/dist/src/git/git.js +73 -0
  37. package/dist/src/git/git.js.map +1 -0
  38. package/dist/src/index.d.ts +1 -0
  39. package/dist/src/index.js +415 -0
  40. package/dist/src/index.js.map +1 -0
  41. package/dist/src/proxy/server.d.ts +1 -0
  42. package/dist/src/proxy/server.js +92 -0
  43. package/dist/src/proxy/server.js.map +1 -0
  44. package/dist/src/tools/edit-file.d.ts +2 -0
  45. package/dist/src/tools/edit-file.js +88 -0
  46. package/dist/src/tools/edit-file.js.map +1 -0
  47. package/dist/src/tools/glob-tool.d.ts +2 -0
  48. package/dist/src/tools/glob-tool.js +52 -0
  49. package/dist/src/tools/glob-tool.js.map +1 -0
  50. package/dist/src/tools/grep.d.ts +2 -0
  51. package/dist/src/tools/grep.js +93 -0
  52. package/dist/src/tools/grep.js.map +1 -0
  53. package/dist/src/tools/list-directory.d.ts +2 -0
  54. package/dist/src/tools/list-directory.js +90 -0
  55. package/dist/src/tools/list-directory.js.map +1 -0
  56. package/dist/src/tools/read-file.d.ts +2 -0
  57. package/dist/src/tools/read-file.js +64 -0
  58. package/dist/src/tools/read-file.js.map +1 -0
  59. package/dist/src/tools/registry.d.ts +4 -0
  60. package/dist/src/tools/registry.js +32 -0
  61. package/dist/src/tools/registry.js.map +1 -0
  62. package/dist/src/tools/run-command.d.ts +2 -0
  63. package/dist/src/tools/run-command.js +98 -0
  64. package/dist/src/tools/run-command.js.map +1 -0
  65. package/dist/src/tools/write-file.d.ts +2 -0
  66. package/dist/src/tools/write-file.js +39 -0
  67. package/dist/src/tools/write-file.js.map +1 -0
  68. package/dist/src/types.d.ts +61 -0
  69. package/dist/src/types.js +2 -0
  70. package/dist/src/types.js.map +1 -0
  71. package/dist/src/ui/input.d.ts +5 -0
  72. package/dist/src/ui/input.js +52 -0
  73. package/dist/src/ui/input.js.map +1 -0
  74. package/dist/src/ui/model-picker.d.ts +7 -0
  75. package/dist/src/ui/model-picker.js +70 -0
  76. package/dist/src/ui/model-picker.js.map +1 -0
  77. package/dist/src/ui/skills-picker.d.ts +2 -0
  78. package/dist/src/ui/skills-picker.js +95 -0
  79. package/dist/src/ui/skills-picker.js.map +1 -0
  80. package/dist/src/ui/skills.d.ts +14 -0
  81. package/dist/src/ui/skills.js +137 -0
  82. package/dist/src/ui/skills.js.map +1 -0
  83. package/dist/src/ui/spinner.d.ts +5 -0
  84. package/dist/src/ui/spinner.js +49 -0
  85. package/dist/src/ui/spinner.js.map +1 -0
  86. package/dist/src/ui/stream-renderer.d.ts +2 -0
  87. package/dist/src/ui/stream-renderer.js +66 -0
  88. package/dist/src/ui/stream-renderer.js.map +1 -0
  89. package/dist/src/ui/terminal.d.ts +24 -0
  90. package/dist/src/ui/terminal.js +272 -0
  91. package/dist/src/ui/terminal.js.map +1 -0
  92. package/package.json +16 -16
  93. package/api/health.ts +0 -10
  94. package/api/v1/chat/completions.ts +0 -59
  95. package/bin/kalcode.ts +0 -14
  96. package/src/agent/context.ts +0 -62
  97. package/src/agent/history.ts +0 -70
  98. package/src/agent/loop.ts +0 -282
  99. package/src/agent/memory.ts +0 -26
  100. package/src/agent/permissions.ts +0 -84
  101. package/src/agent/text-tool-parser.ts +0 -71
  102. package/src/api/client.ts +0 -110
  103. package/src/api/stream-parser.ts +0 -109
  104. package/src/config.ts +0 -61
  105. package/src/git/git.ts +0 -86
  106. package/src/index.ts +0 -403
  107. package/src/proxy/server.ts +0 -128
  108. package/src/tools/edit-file.ts +0 -97
  109. package/src/tools/glob-tool.ts +0 -59
  110. package/src/tools/grep.ts +0 -96
  111. package/src/tools/list-directory.ts +0 -101
  112. package/src/tools/read-file.ts +0 -71
  113. package/src/tools/registry.ts +0 -41
  114. package/src/tools/run-command.ts +0 -99
  115. package/src/tools/write-file.ts +0 -42
  116. package/src/types.ts +0 -68
  117. package/src/ui/input.ts +0 -60
  118. package/src/ui/model-picker.ts +0 -92
  119. package/src/ui/skills-picker.ts +0 -113
  120. package/src/ui/skills.ts +0 -152
  121. package/src/ui/spinner.ts +0 -56
  122. package/src/ui/stream-renderer.ts +0 -69
  123. package/src/ui/terminal.ts +0 -337
  124. package/tsconfig.json +0 -15
  125. package/vercel.json +0 -12
@@ -0,0 +1,52 @@
1
+ import { resolve } from "path";
2
+ import { glob } from "glob";
3
+ import { MAX_GLOB_RESULTS } from "../constants.js";
4
+ export const globTool = {
5
+ definition: {
6
+ type: "function",
7
+ function: {
8
+ name: "glob",
9
+ description: "Find files matching a glob pattern. Returns matching file paths sorted by modification time.",
10
+ parameters: {
11
+ type: "object",
12
+ properties: {
13
+ pattern: {
14
+ type: "string",
15
+ description: "Glob pattern (e.g., '**/*.ts', 'src/**/*.json')",
16
+ },
17
+ path: {
18
+ type: "string",
19
+ description: "Base directory to search from. Default: current directory",
20
+ },
21
+ },
22
+ required: ["pattern"],
23
+ },
24
+ },
25
+ },
26
+ async execute(args) {
27
+ const pattern = String(args.pattern);
28
+ const basePath = resolve(String(args.path || "."));
29
+ try {
30
+ const matches = await glob(pattern, {
31
+ cwd: basePath,
32
+ dot: false,
33
+ ignore: ["node_modules/**", ".git/**"],
34
+ maxDepth: 20,
35
+ });
36
+ if (matches.length === 0) {
37
+ return `No files matching pattern: ${pattern} in ${basePath}`;
38
+ }
39
+ const limited = matches.sort().slice(0, MAX_GLOB_RESULTS);
40
+ let result = `Found ${limited.length} file(s) matching "${pattern}":\n`;
41
+ result += limited.join("\n");
42
+ if (matches.length > MAX_GLOB_RESULTS) {
43
+ result += `\n... (results limited to ${MAX_GLOB_RESULTS})`;
44
+ }
45
+ return result;
46
+ }
47
+ catch (err) {
48
+ return `Error searching for files: ${err instanceof Error ? err.message : String(err)}`;
49
+ }
50
+ },
51
+ };
52
+ //# sourceMappingURL=glob-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob-tool.js","sourceRoot":"","sources":["../../../src/tools/glob-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,CAAC,MAAM,QAAQ,GAAgB;IACnC,UAAU,EAAE;QACV,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE;YACR,IAAI,EAAE,MAAM;YACZ,WAAW,EACT,8FAA8F;YAChG,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,OAAO,EAAE;wBACP,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,iDAAiD;qBAC/D;oBACD,IAAI,EAAE;wBACJ,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,2DAA2D;qBACzE;iBACF;gBACD,QAAQ,EAAE,CAAC,SAAS,CAAC;aACtB;SACF;KACF;IAED,KAAK,CAAC,OAAO,CAAC,IAAI;QAChB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;QAEnD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE;gBAClC,GAAG,EAAE,QAAQ;gBACb,GAAG,EAAE,KAAK;gBACV,MAAM,EAAE,CAAC,iBAAiB,EAAE,SAAS,CAAC;gBACtC,QAAQ,EAAE,EAAE;aACb,CAAC,CAAC;YAEH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,8BAA8B,OAAO,OAAO,QAAQ,EAAE,CAAC;YAChE,CAAC;YAED,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;YAC1D,IAAI,MAAM,GAAG,SAAS,OAAO,CAAC,MAAM,sBAAsB,OAAO,MAAM,CAAC;YACxE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,OAAO,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;gBACtC,MAAM,IAAI,6BAA6B,gBAAgB,GAAG,CAAC;YAC7D,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,8BAA8B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1F,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { ToolHandler } from "../types.js";
2
+ export declare const grepTool: ToolHandler;
@@ -0,0 +1,93 @@
1
+ import { spawn } from "child_process";
2
+ import { MAX_GREP_RESULTS } from "../constants.js";
3
+ export const grepTool = {
4
+ definition: {
5
+ type: "function",
6
+ function: {
7
+ name: "grep",
8
+ description: "Search file contents for a pattern. Uses ripgrep if available, otherwise falls back to grep. Returns matching lines with file paths and line numbers.",
9
+ parameters: {
10
+ type: "object",
11
+ properties: {
12
+ pattern: {
13
+ type: "string",
14
+ description: "Search pattern (regex supported)",
15
+ },
16
+ path: {
17
+ type: "string",
18
+ description: "Directory or file to search in. Default: current directory",
19
+ },
20
+ include: {
21
+ type: "string",
22
+ description: "File glob pattern to include (e.g., '*.ts')",
23
+ },
24
+ maxResults: {
25
+ type: "number",
26
+ description: `Maximum number of results. Default: ${MAX_GREP_RESULTS}`,
27
+ },
28
+ },
29
+ required: ["pattern"],
30
+ },
31
+ },
32
+ },
33
+ async execute(args) {
34
+ const pattern = String(args.pattern);
35
+ const searchPath = String(args.path || ".");
36
+ const include = args.include ? String(args.include) : null;
37
+ const maxResults = Number(args.maxResults) || MAX_GREP_RESULTS;
38
+ const hasRg = await checkCommand("rg");
39
+ let cmd;
40
+ if (hasRg) {
41
+ cmd = `rg --line-number --max-count ${maxResults} --no-heading --glob '!node_modules' --glob '!.git'`;
42
+ if (include)
43
+ cmd += ` --glob '${include}'`;
44
+ cmd += ` -- ${escapeShellArg(pattern)} ${escapeShellArg(searchPath)}`;
45
+ }
46
+ else {
47
+ cmd = `grep -rn --max-count=${maxResults} --exclude-dir=node_modules --exclude-dir=.git`;
48
+ if (include)
49
+ cmd += ` --include='${include}'`;
50
+ cmd += ` -- ${escapeShellArg(pattern)} ${escapeShellArg(searchPath)}`;
51
+ }
52
+ try {
53
+ const { stdout } = await runShell(cmd);
54
+ if (!stdout.trim()) {
55
+ return `No matches found for pattern: ${pattern}`;
56
+ }
57
+ const lines = stdout.trim().split("\n");
58
+ const limited = lines.slice(0, maxResults);
59
+ let result = limited.join("\n");
60
+ if (lines.length > maxResults) {
61
+ result += `\n... (${lines.length - maxResults} more matches)`;
62
+ }
63
+ return result;
64
+ }
65
+ catch (err) {
66
+ return `Error searching: ${err instanceof Error ? err.message : String(err)}`;
67
+ }
68
+ },
69
+ };
70
+ function runShell(cmd) {
71
+ return new Promise((resolve) => {
72
+ const proc = spawn("sh", ["-c", cmd], { stdio: ["ignore", "pipe", "pipe"] });
73
+ let stdout = "";
74
+ let stderr = "";
75
+ proc.stdout.on("data", (d) => { stdout += d.toString(); });
76
+ proc.stderr.on("data", (d) => { stderr += d.toString(); });
77
+ proc.on("close", (code) => resolve({ stdout, stderr, exitCode: code ?? 1 }));
78
+ proc.on("error", (err) => resolve({ stdout: "", stderr: err.message, exitCode: 1 }));
79
+ });
80
+ }
81
+ async function checkCommand(cmd) {
82
+ try {
83
+ const { exitCode } = await runShell(`which ${cmd}`);
84
+ return exitCode === 0;
85
+ }
86
+ catch {
87
+ return false;
88
+ }
89
+ }
90
+ function escapeShellArg(arg) {
91
+ return `'${arg.replace(/'/g, "'\\''")}'`;
92
+ }
93
+ //# sourceMappingURL=grep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../../src/tools/grep.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { ToolHandler } from "../types.js";
2
+ export declare const listDirectoryTool: ToolHandler;
@@ -0,0 +1,90 @@
1
+ import { readdirSync, statSync, existsSync } from "fs";
2
+ import { resolve, join } from "path";
3
+ import { MAX_DIR_ENTRIES, MAX_DIR_DEPTH } from "../constants.js";
4
+ export const listDirectoryTool = {
5
+ definition: {
6
+ type: "function",
7
+ function: {
8
+ name: "listDirectory",
9
+ description: "List the contents of a directory. Shows file names, types, and sizes.",
10
+ parameters: {
11
+ type: "object",
12
+ properties: {
13
+ dirPath: {
14
+ type: "string",
15
+ description: "Path to the directory to list. Default: current directory",
16
+ },
17
+ recursive: {
18
+ type: "boolean",
19
+ description: "List recursively (max depth 3). Default: false",
20
+ },
21
+ },
22
+ },
23
+ },
24
+ },
25
+ async execute(args) {
26
+ const dirPath = resolve(String(args.dirPath || "."));
27
+ const recursive = Boolean(args.recursive);
28
+ if (!existsSync(dirPath)) {
29
+ return `Error: Directory not found: ${dirPath}`;
30
+ }
31
+ try {
32
+ const entries = [];
33
+ listDir(dirPath, "", recursive ? MAX_DIR_DEPTH : 0, entries);
34
+ if (entries.length === 0) {
35
+ return `Directory is empty: ${dirPath}`;
36
+ }
37
+ let result = `Contents of ${dirPath} (${entries.length} entries):\n`;
38
+ result += entries.join("\n");
39
+ if (entries.length >= MAX_DIR_ENTRIES) {
40
+ result += `\n... (limited to ${MAX_DIR_ENTRIES} entries)`;
41
+ }
42
+ return result;
43
+ }
44
+ catch (err) {
45
+ return `Error listing directory: ${err instanceof Error ? err.message : String(err)}`;
46
+ }
47
+ },
48
+ };
49
+ function listDir(basePath, prefix, depth, entries) {
50
+ if (entries.length >= MAX_DIR_ENTRIES)
51
+ return;
52
+ let items;
53
+ try {
54
+ items = readdirSync(join(basePath, prefix));
55
+ }
56
+ catch {
57
+ return;
58
+ }
59
+ items.sort();
60
+ for (const item of items) {
61
+ if (entries.length >= MAX_DIR_ENTRIES)
62
+ return;
63
+ const relPath = prefix ? `${prefix}/${item}` : item;
64
+ const fullPath = join(basePath, relPath);
65
+ try {
66
+ const stat = statSync(fullPath);
67
+ if (stat.isDirectory()) {
68
+ entries.push(`${relPath}/`);
69
+ if (depth > 0) {
70
+ listDir(basePath, relPath, depth - 1, entries);
71
+ }
72
+ }
73
+ else {
74
+ const size = formatSize(stat.size);
75
+ entries.push(`${relPath} (${size})`);
76
+ }
77
+ }
78
+ catch {
79
+ entries.push(`${relPath} (unreadable)`);
80
+ }
81
+ }
82
+ }
83
+ function formatSize(bytes) {
84
+ if (bytes < 1024)
85
+ return `${bytes}B`;
86
+ if (bytes < 1024 * 1024)
87
+ return `${(bytes / 1024).toFixed(1)}KB`;
88
+ return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
89
+ }
90
+ //# sourceMappingURL=list-directory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-directory.js","sourceRoot":"","sources":["../../../src/tools/list-directory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { ToolHandler } from "../types.js";
2
+ export declare const readFileTool: ToolHandler;
@@ -0,0 +1,64 @@
1
+ import { readFileSync, statSync, existsSync } from "fs";
2
+ import { resolve } from "path";
3
+ import { MAX_FILE_SIZE, DEFAULT_LINE_LIMIT } from "../constants.js";
4
+ export const readFileTool = {
5
+ definition: {
6
+ type: "function",
7
+ function: {
8
+ name: "readFile",
9
+ description: "Read the contents of a file with line numbers. Returns line-numbered output. Use offset and limit to read specific portions of large files.",
10
+ parameters: {
11
+ type: "object",
12
+ properties: {
13
+ filePath: {
14
+ type: "string",
15
+ description: "Path to the file to read (absolute or relative to cwd)",
16
+ },
17
+ offset: {
18
+ type: "number",
19
+ description: "Line number to start reading from (1-based). Default: 1",
20
+ },
21
+ limit: {
22
+ type: "number",
23
+ description: `Maximum number of lines to read. Default: ${DEFAULT_LINE_LIMIT}`,
24
+ },
25
+ },
26
+ required: ["filePath"],
27
+ },
28
+ },
29
+ },
30
+ async execute(args) {
31
+ const filePath = resolve(String(args.filePath));
32
+ const offset = Math.max(1, Number(args.offset) || 1);
33
+ const limit = Number(args.limit) || DEFAULT_LINE_LIMIT;
34
+ if (!existsSync(filePath)) {
35
+ return `Error: File not found: ${filePath}`;
36
+ }
37
+ try {
38
+ const stat = statSync(filePath);
39
+ if (stat.isDirectory()) {
40
+ return `Error: Path is a directory, not a file: ${filePath}`;
41
+ }
42
+ if (stat.size > MAX_FILE_SIZE) {
43
+ return `Error: File too large (${(stat.size / 1024 / 1024).toFixed(1)}MB). Use offset/limit to read portions.`;
44
+ }
45
+ const content = readFileSync(filePath, "utf-8");
46
+ const lines = content.split("\n");
47
+ const startIdx = offset - 1;
48
+ const endIdx = Math.min(startIdx + limit, lines.length);
49
+ const slice = lines.slice(startIdx, endIdx);
50
+ const numbered = slice
51
+ .map((line, i) => {
52
+ const lineNum = String(startIdx + i + 1).padStart(4, " ");
53
+ return `${lineNum} | ${line}`;
54
+ })
55
+ .join("\n");
56
+ const header = `File: ${filePath} (${lines.length} lines total, showing ${offset}-${endIdx})`;
57
+ return `${header}\n${numbered}`;
58
+ }
59
+ catch (err) {
60
+ return `Error reading file: ${err instanceof Error ? err.message : String(err)}`;
61
+ }
62
+ },
63
+ };
64
+ //# sourceMappingURL=read-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../../src/tools/read-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ToolDefinition, ToolHandler } from "../types.js";
2
+ export declare function getToolHandler(name: string): ToolHandler | undefined;
3
+ export declare function getAllDefinitions(): ToolDefinition[];
4
+ export declare function executeToolCall(name: string, args: Record<string, unknown>): Promise<string>;
@@ -0,0 +1,32 @@
1
+ import { readFileTool } from "./read-file.js";
2
+ import { writeFileTool } from "./write-file.js";
3
+ import { editFileTool } from "./edit-file.js";
4
+ import { runCommandTool } from "./run-command.js";
5
+ import { grepTool } from "./grep.js";
6
+ import { globTool } from "./glob-tool.js";
7
+ import { listDirectoryTool } from "./list-directory.js";
8
+ const tools = new Map();
9
+ function register(handler) {
10
+ tools.set(handler.definition.function.name, handler);
11
+ }
12
+ register(readFileTool);
13
+ register(writeFileTool);
14
+ register(editFileTool);
15
+ register(runCommandTool);
16
+ register(grepTool);
17
+ register(globTool);
18
+ register(listDirectoryTool);
19
+ export function getToolHandler(name) {
20
+ return tools.get(name);
21
+ }
22
+ export function getAllDefinitions() {
23
+ return Array.from(tools.values()).map((t) => t.definition);
24
+ }
25
+ export function executeToolCall(name, args) {
26
+ const handler = tools.get(name);
27
+ if (!handler) {
28
+ return Promise.resolve(`Error: Unknown tool "${name}"`);
29
+ }
30
+ return handler.execute(args);
31
+ }
32
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/tools/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,KAAK,GAA6B,IAAI,GAAG,EAAE,CAAC;AAElD,SAAS,QAAQ,CAAC,OAAoB;IACpC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACvD,CAAC;AAED,QAAQ,CAAC,YAAY,CAAC,CAAC;AACvB,QAAQ,CAAC,aAAa,CAAC,CAAC;AACxB,QAAQ,CAAC,YAAY,CAAC,CAAC;AACvB,QAAQ,CAAC,cAAc,CAAC,CAAC;AACzB,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACnB,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACnB,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AAE5B,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,IAA6B;IAE7B,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,OAAO,CAAC,OAAO,CAAC,wBAAwB,IAAI,GAAG,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { ToolHandler } from "../types.js";
2
+ export declare const runCommandTool: ToolHandler;
@@ -0,0 +1,98 @@
1
+ import { resolve } from "path";
2
+ import { spawn } from "child_process";
3
+ import { DEFAULT_COMMAND_TIMEOUT, MAX_COMMAND_TIMEOUT, MAX_OUTPUT_BYTES } from "../constants.js";
4
+ export const runCommandTool = {
5
+ definition: {
6
+ type: "function",
7
+ function: {
8
+ name: "runCommand",
9
+ description: "Execute a shell command and return its output. Default timeout is 30s and hard-capped at 45s. Output is truncated at 50KB.",
10
+ parameters: {
11
+ type: "object",
12
+ properties: {
13
+ command: {
14
+ type: "string",
15
+ description: "The shell command to execute",
16
+ },
17
+ cwd: {
18
+ type: "string",
19
+ description: "Working directory for the command. Default: current directory",
20
+ },
21
+ timeout: {
22
+ type: "number",
23
+ description: "Timeout in milliseconds. Default: 30000, max: 45000",
24
+ },
25
+ },
26
+ required: ["command"],
27
+ },
28
+ },
29
+ },
30
+ async execute(args) {
31
+ const command = String(args.command);
32
+ const cwd = args.cwd ? resolve(String(args.cwd)) : process.cwd();
33
+ const requestedTimeout = Number(args.timeout) || DEFAULT_COMMAND_TIMEOUT;
34
+ const timeout = Math.min(Math.max(1_000, requestedTimeout), MAX_COMMAND_TIMEOUT);
35
+ try {
36
+ const { exitCode, stdout, stderr } = await runShell(command, cwd, timeout);
37
+ if (exitCode === 124) {
38
+ return [
39
+ `Exit code: 124`,
40
+ `STDERR:`,
41
+ `Command timed out after ${Math.round(timeout / 1000)}s.`,
42
+ `Tip: use a shorter command, reduce scope, or run background/dev servers manually outside kalcode.`,
43
+ ].join("\n\n");
44
+ }
45
+ let stdoutTrimmed = stdout;
46
+ let stderrTrimmed = stderr;
47
+ if (stdoutTrimmed.length > MAX_OUTPUT_BYTES) {
48
+ stdoutTrimmed = stdoutTrimmed.slice(0, MAX_OUTPUT_BYTES) + "\n... (output truncated)";
49
+ }
50
+ if (stderrTrimmed.length > MAX_OUTPUT_BYTES) {
51
+ stderrTrimmed = stderrTrimmed.slice(0, MAX_OUTPUT_BYTES) + "\n... (output truncated)";
52
+ }
53
+ let result = `Exit code: ${exitCode}`;
54
+ if (stdoutTrimmed.trim())
55
+ result += `\n\nSTDOUT:\n${stdoutTrimmed.trim()}`;
56
+ if (stderrTrimmed.trim())
57
+ result += `\n\nSTDERR:\n${stderrTrimmed.trim()}`;
58
+ return result;
59
+ }
60
+ catch (err) {
61
+ return `Error running command: ${err instanceof Error ? err.message : String(err)}`;
62
+ }
63
+ },
64
+ };
65
+ function runShell(command, cwd, timeout) {
66
+ return new Promise((resolve) => {
67
+ const proc = spawn("sh", ["-c", command], {
68
+ cwd,
69
+ env: { ...process.env },
70
+ stdio: ["ignore", "pipe", "pipe"],
71
+ });
72
+ let stdout = "";
73
+ let stderr = "";
74
+ let timedOut = false;
75
+ const timer = setTimeout(() => {
76
+ timedOut = true;
77
+ try {
78
+ proc.kill("SIGKILL");
79
+ }
80
+ catch { /* already exited */ }
81
+ }, timeout);
82
+ proc.stdout.on("data", (d) => { stdout += d.toString(); });
83
+ proc.stderr.on("data", (d) => { stderr += d.toString(); });
84
+ proc.on("close", (code) => {
85
+ clearTimeout(timer);
86
+ resolve({
87
+ exitCode: timedOut ? 124 : (code ?? 1),
88
+ stdout,
89
+ stderr,
90
+ });
91
+ });
92
+ proc.on("error", (err) => {
93
+ clearTimeout(timer);
94
+ resolve({ exitCode: 1, stdout: "", stderr: err.message });
95
+ });
96
+ });
97
+ }
98
+ //# sourceMappingURL=run-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-command.js","sourceRoot":"","sources":["../../../src/tools/run-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { ToolHandler } from "../types.js";
2
+ export declare const writeFileTool: ToolHandler;
@@ -0,0 +1,39 @@
1
+ import { writeFileSync, mkdirSync } from "fs";
2
+ import { resolve, dirname } from "path";
3
+ export const writeFileTool = {
4
+ definition: {
5
+ type: "function",
6
+ function: {
7
+ name: "writeFile",
8
+ description: "Write content to a file. Creates the file if it doesn't exist. Automatically creates parent directories as needed.",
9
+ parameters: {
10
+ type: "object",
11
+ properties: {
12
+ filePath: {
13
+ type: "string",
14
+ description: "Path to the file to write (absolute or relative to cwd)",
15
+ },
16
+ content: {
17
+ type: "string",
18
+ description: "Content to write to the file",
19
+ },
20
+ },
21
+ required: ["filePath", "content"],
22
+ },
23
+ },
24
+ },
25
+ async execute(args) {
26
+ const filePath = resolve(String(args.filePath));
27
+ const content = String(args.content);
28
+ try {
29
+ mkdirSync(dirname(filePath), { recursive: true });
30
+ writeFileSync(filePath, content);
31
+ const lineCount = content.split("\n").length;
32
+ return `Successfully wrote ${lineCount} lines to ${filePath}`;
33
+ }
34
+ catch (err) {
35
+ return `Error writing file: ${err instanceof Error ? err.message : String(err)}`;
36
+ }
37
+ },
38
+ };
39
+ //# sourceMappingURL=write-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-file.js","sourceRoot":"","sources":["../../../src/tools/write-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAGxC,MAAM,CAAC,MAAM,aAAa,GAAgB;IACxC,UAAU,EAAE;QACV,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE;YACR,IAAI,EAAE,WAAW;YACjB,WAAW,EACT,oHAAoH;YACtH,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,QAAQ,EAAE;wBACR,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,yDAAyD;qBACvE;oBACD,OAAO,EAAE;wBACP,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,8BAA8B;qBAC5C;iBACF;gBACD,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC;aAClC;SACF;KACF;IAED,KAAK,CAAC,OAAO,CAAC,IAAI;QAChB,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAErC,IAAI,CAAC;YACH,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YAC7C,OAAO,sBAAsB,SAAS,aAAa,QAAQ,EAAE,CAAC;QAChE,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,uBAAuB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACnF,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,61 @@
1
+ export interface Config {
2
+ apiKey: string;
3
+ model: string;
4
+ }
5
+ export interface Message {
6
+ role: "system" | "user" | "assistant" | "tool";
7
+ content: string | null;
8
+ tool_calls?: ToolCall[];
9
+ tool_call_id?: string;
10
+ name?: string;
11
+ }
12
+ export interface ToolCall {
13
+ id: string;
14
+ type: "function";
15
+ function: {
16
+ name: string;
17
+ arguments: string;
18
+ };
19
+ }
20
+ export interface ToolDefinition {
21
+ type: "function";
22
+ function: {
23
+ name: string;
24
+ description: string;
25
+ parameters: {
26
+ type: "object";
27
+ properties: Record<string, unknown>;
28
+ required?: string[];
29
+ };
30
+ };
31
+ }
32
+ export interface StreamDelta {
33
+ type: "content" | "tool_call" | "done" | "error";
34
+ content?: string;
35
+ toolCall?: {
36
+ index: number;
37
+ id?: string;
38
+ function?: {
39
+ name?: string;
40
+ arguments?: string;
41
+ };
42
+ };
43
+ error?: string;
44
+ usage?: TokenUsage;
45
+ }
46
+ export interface ToolHandler {
47
+ definition: ToolDefinition;
48
+ execute: (args: Record<string, unknown>) => Promise<string>;
49
+ }
50
+ export interface ToolCallAccumulator {
51
+ id: string;
52
+ function: {
53
+ name: string;
54
+ arguments: string;
55
+ };
56
+ }
57
+ export interface TokenUsage {
58
+ prompt_tokens: number;
59
+ completion_tokens: number;
60
+ total_tokens: number;
61
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ export interface InputController {
2
+ prompt: () => Promise<string>;
3
+ close: () => void;
4
+ }
5
+ export declare function createInput(slashCommands?: string[]): InputController;