codemaxxing 1.0.0 → 1.0.2

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 (47) hide show
  1. package/README.md +18 -12
  2. package/dist/agent.d.ts +4 -0
  3. package/dist/agent.js +91 -16
  4. package/dist/commands/git.d.ts +2 -0
  5. package/dist/commands/git.js +50 -0
  6. package/dist/commands/ollama.d.ts +27 -0
  7. package/dist/commands/ollama.js +171 -0
  8. package/dist/commands/output.d.ts +2 -0
  9. package/dist/commands/output.js +18 -0
  10. package/dist/commands/registry.d.ts +2 -0
  11. package/dist/commands/registry.js +8 -0
  12. package/dist/commands/skills.d.ts +18 -0
  13. package/dist/commands/skills.js +121 -0
  14. package/dist/commands/types.d.ts +5 -0
  15. package/dist/commands/types.js +1 -0
  16. package/dist/commands/ui.d.ts +16 -0
  17. package/dist/commands/ui.js +79 -0
  18. package/dist/config.d.ts +9 -0
  19. package/dist/config.js +13 -3
  20. package/dist/exec.js +4 -1
  21. package/dist/index.js +75 -401
  22. package/dist/tools/files.js +58 -3
  23. package/dist/utils/context.js +6 -0
  24. package/dist/utils/mcp.d.ts +7 -2
  25. package/dist/utils/mcp.js +34 -6
  26. package/package.json +8 -5
  27. package/src/agent.ts +0 -894
  28. package/src/auth-cli.ts +0 -287
  29. package/src/cli.ts +0 -37
  30. package/src/config.ts +0 -352
  31. package/src/exec.ts +0 -183
  32. package/src/index.tsx +0 -2647
  33. package/src/skills/registry.ts +0 -1436
  34. package/src/themes.ts +0 -335
  35. package/src/tools/files.ts +0 -374
  36. package/src/utils/auth.ts +0 -606
  37. package/src/utils/context.ts +0 -174
  38. package/src/utils/git.ts +0 -117
  39. package/src/utils/hardware.ts +0 -131
  40. package/src/utils/lint.ts +0 -116
  41. package/src/utils/mcp.ts +0 -307
  42. package/src/utils/models.ts +0 -218
  43. package/src/utils/ollama.ts +0 -352
  44. package/src/utils/repomap.ts +0 -220
  45. package/src/utils/sessions.ts +0 -254
  46. package/src/utils/skills.ts +0 -241
  47. package/tsconfig.json +0 -16
@@ -1,352 +0,0 @@
1
- import { execSync, spawn } from "child_process";
2
- import { existsSync } from "fs";
3
- import { join } from "path";
4
-
5
- /** Get known Ollama binary paths for Windows */
6
- function getWindowsOllamaPaths(): string[] {
7
- const paths: string[] = [];
8
- const localAppData = process.env.LOCALAPPDATA || join(process.env.USERPROFILE || "", "AppData", "Local");
9
- const programFiles = process.env.ProgramFiles || "C:\\Program Files";
10
- paths.push(join(localAppData, "Programs", "Ollama", "ollama.exe"));
11
- paths.push(join(programFiles, "Ollama", "ollama.exe"));
12
- paths.push(join(localAppData, "Ollama", "ollama.exe"));
13
- return paths;
14
- }
15
-
16
- /** Check if ollama binary exists on PATH, known install locations, or server is running */
17
- export function isOllamaInstalled(): boolean {
18
- // Check PATH first
19
- try {
20
- const cmd = process.platform === "win32" ? "where ollama" : "which ollama";
21
- execSync(cmd, { stdio: ["pipe", "pipe", "pipe"], timeout: 3000 });
22
- return true;
23
- } catch {}
24
-
25
- // Check known install paths on Windows
26
- if (process.platform === "win32") {
27
- if (getWindowsOllamaPaths().some(p => existsSync(p))) return true;
28
- }
29
-
30
- // Check if the server is responding (if server is running, Ollama is definitely installed)
31
- try {
32
- execSync("curl -s http://localhost:11434/api/tags", {
33
- stdio: ["pipe", "pipe", "pipe"],
34
- timeout: 3000,
35
- });
36
- return true;
37
- } catch {}
38
-
39
- // Check if ollama process is running (Windows)
40
- if (process.platform === "win32") {
41
- try {
42
- const result = execSync("tasklist /fi \"imagename eq ollama app.exe\" /fo csv /nh", {
43
- stdio: ["pipe", "pipe", "pipe"],
44
- timeout: 3000,
45
- });
46
- if (result.toString().toLowerCase().includes("ollama")) return true;
47
- } catch {}
48
- }
49
-
50
- return false;
51
- }
52
-
53
- /** Check if ollama server is responding */
54
- export async function isOllamaRunning(): Promise<boolean> {
55
- try {
56
- const controller = new AbortController();
57
- const timeout = setTimeout(() => controller.abort(), 2000);
58
- const res = await fetch("http://localhost:11434/api/tags", { signal: controller.signal });
59
- clearTimeout(timeout);
60
- return res.ok;
61
- } catch {
62
- return false;
63
- }
64
- }
65
-
66
- /** Get the install command for the user's OS */
67
- export function getOllamaInstallCommand(os: "macos" | "linux" | "windows"): string {
68
- switch (os) {
69
- case "macos": return "brew install ollama";
70
- case "linux": return "curl -fsSL https://ollama.com/install.sh | sh";
71
- case "windows": return "winget install Ollama.Ollama";
72
- }
73
- }
74
-
75
- /** Find the ollama binary path */
76
- function findOllamaBinary(): string {
77
- // Try PATH first
78
- try {
79
- const cmd = process.platform === "win32" ? "where ollama" : "which ollama";
80
- return execSync(cmd, { stdio: ["pipe", "pipe", "pipe"], timeout: 3000 }).toString().trim().split("\n")[0];
81
- } catch {}
82
- // Check known Windows paths
83
- if (process.platform === "win32") {
84
- for (const p of getWindowsOllamaPaths()) {
85
- if (existsSync(p)) return p;
86
- }
87
- }
88
- return "ollama"; // fallback, hope for the best
89
- }
90
-
91
- /** Start ollama serve in background */
92
- export function startOllama(): void {
93
- const bin = findOllamaBinary();
94
- const child = spawn(bin, ["serve"], {
95
- detached: true,
96
- stdio: "ignore",
97
- });
98
- child.unref();
99
- }
100
-
101
- export interface PullProgress {
102
- status: string;
103
- total?: number;
104
- completed?: number;
105
- percent: number;
106
- }
107
-
108
- /**
109
- * Pull a model from Ollama registry via HTTP API.
110
- * Falls back to CLI if API fails.
111
- * Calls onProgress with download updates.
112
- */
113
- export function pullModel(
114
- modelId: string,
115
- onProgress?: (progress: PullProgress) => void
116
- ): Promise<void> {
117
- // Try HTTP API first (works even when CLI isn't on PATH)
118
- return pullModelViaAPI(modelId, onProgress).catch(() => {
119
- // Fallback to CLI
120
- return pullModelViaCLI(modelId, onProgress);
121
- });
122
- }
123
-
124
- function pullModelViaAPI(
125
- modelId: string,
126
- onProgress?: (progress: PullProgress) => void
127
- ): Promise<void> {
128
- return new Promise(async (resolve, reject) => {
129
- try {
130
- const res = await fetch("http://localhost:11434/api/pull", {
131
- method: "POST",
132
- headers: { "Content-Type": "application/json" },
133
- body: JSON.stringify({ name: modelId, stream: true }),
134
- });
135
- if (!res.ok || !res.body) {
136
- reject(new Error(`Ollama API returned ${res.status}`));
137
- return;
138
- }
139
- const reader = res.body.getReader();
140
- const decoder = new TextDecoder();
141
- let buffer = "";
142
- while (true) {
143
- const { done, value } = await reader.read();
144
- if (done) break;
145
- buffer += decoder.decode(value, { stream: true });
146
- const lines = buffer.split("\n");
147
- buffer = lines.pop() || "";
148
- for (const line of lines) {
149
- if (!line.trim()) continue;
150
- try {
151
- const data = JSON.parse(line);
152
- if (data.status === "success") {
153
- onProgress?.({ status: "success", percent: 100 });
154
- resolve();
155
- return;
156
- }
157
- if (data.total && data.completed) {
158
- const percent = Math.round((data.completed / data.total) * 100);
159
- onProgress?.({ status: "downloading", total: data.total, completed: data.completed, percent });
160
- } else {
161
- onProgress?.({ status: data.status || "working...", percent: 0 });
162
- }
163
- } catch {}
164
- }
165
- }
166
- resolve();
167
- } catch (err: any) {
168
- reject(err);
169
- }
170
- });
171
- }
172
-
173
- function pullModelViaCLI(
174
- modelId: string,
175
- onProgress?: (progress: PullProgress) => void
176
- ): Promise<void> {
177
- return new Promise((resolve, reject) => {
178
- const bin = findOllamaBinary();
179
- const child = spawn(bin, ["pull", modelId], {
180
- stdio: ["pipe", "pipe", "pipe"],
181
- });
182
-
183
- let lastOutput = "";
184
-
185
- const parseLine = (data: string) => {
186
- lastOutput = data;
187
- // Ollama pull output looks like:
188
- // pulling manifest
189
- // pulling abc123... 58% ▕██████████░░░░░░░░░░▏ 2.9 GB/5.0 GB
190
- // verifying sha256 digest
191
- // writing manifest
192
- // success
193
-
194
- // Try to parse percentage
195
- const pctMatch = data.match(/(\d+)%/);
196
- const sizeMatch = data.match(/([\d.]+)\s*GB\s*\/\s*([\d.]+)\s*GB/);
197
-
198
- if (pctMatch) {
199
- const percent = parseInt(pctMatch[1]);
200
- let completed: number | undefined;
201
- let total: number | undefined;
202
- if (sizeMatch) {
203
- completed = parseFloat(sizeMatch[1]) * 1024 * 1024 * 1024;
204
- total = parseFloat(sizeMatch[2]) * 1024 * 1024 * 1024;
205
- }
206
- onProgress?.({ status: "downloading", total, completed, percent });
207
- } else if (data.includes("pulling manifest")) {
208
- onProgress?.({ status: "pulling manifest", percent: 0 });
209
- } else if (data.includes("verifying")) {
210
- onProgress?.({ status: "verifying", percent: 100 });
211
- } else if (data.includes("writing manifest")) {
212
- onProgress?.({ status: "writing manifest", percent: 100 });
213
- } else if (data.includes("success")) {
214
- onProgress?.({ status: "success", percent: 100 });
215
- }
216
- };
217
-
218
- child.stdout?.on("data", (data: Buffer) => {
219
- parseLine(data.toString().trim());
220
- });
221
-
222
- child.stderr?.on("data", (data: Buffer) => {
223
- // Ollama writes progress to stderr
224
- parseLine(data.toString().trim());
225
- });
226
-
227
- child.on("close", (code) => {
228
- if (code === 0) {
229
- resolve();
230
- } else {
231
- reject(new Error(`ollama pull failed (exit ${code}): ${lastOutput}`));
232
- }
233
- });
234
-
235
- child.on("error", (err) => {
236
- reject(new Error(`Failed to run ollama pull: ${err.message}`));
237
- });
238
- });
239
- }
240
-
241
- export interface OllamaModelInfo {
242
- name: string;
243
- size: number; // bytes
244
- modified_at: string;
245
- digest: string;
246
- }
247
-
248
- /** List models installed in Ollama with detailed info */
249
- export async function listInstalledModelsDetailed(): Promise<OllamaModelInfo[]> {
250
- try {
251
- const controller = new AbortController();
252
- const timeout = setTimeout(() => controller.abort(), 3000);
253
- const res = await fetch("http://localhost:11434/api/tags", { signal: controller.signal });
254
- clearTimeout(timeout);
255
- if (res.ok) {
256
- const data = (await res.json()) as { models?: Array<{ name: string; size: number; modified_at: string; digest: string }> };
257
- return (data.models ?? []).map((m) => ({
258
- name: m.name,
259
- size: m.size,
260
- modified_at: m.modified_at,
261
- digest: m.digest,
262
- }));
263
- }
264
- } catch { /* not running */ }
265
- return [];
266
- }
267
-
268
- /** List models installed in Ollama */
269
- export async function listInstalledModels(): Promise<string[]> {
270
- const models = await listInstalledModelsDetailed();
271
- return models.map((m) => m.name);
272
- }
273
-
274
- /** Stop all loaded models (frees VRAM) and kill the Ollama server process */
275
- export async function stopOllama(): Promise<{ ok: boolean; message: string }> {
276
- try {
277
- // First unload all models from memory
278
- try {
279
- const bin = findOllamaBinary();
280
- const { spawnSync } = require("child_process");
281
- spawnSync(bin, ["stop"], { stdio: "pipe", timeout: 5000 });
282
- } catch { /* may fail if no models loaded */ }
283
-
284
- // Kill the server process
285
- if (process.platform === "win32") {
286
- execSync("taskkill /f /im ollama.exe", { stdio: ["pipe", "pipe", "pipe"], timeout: 5000 });
287
- } else if (process.platform === "darwin") {
288
- // Try launchctl first (Ollama app), then pkill
289
- try {
290
- execSync("launchctl stop com.ollama.ollama", { stdio: ["pipe", "pipe", "pipe"], timeout: 3000 });
291
- } catch {
292
- try {
293
- execSync("pkill ollama", { stdio: ["pipe", "pipe", "pipe"], timeout: 3000 });
294
- } catch { /* already stopped */ }
295
- }
296
- } else {
297
- // Linux
298
- try {
299
- execSync("systemctl stop ollama", { stdio: ["pipe", "pipe", "pipe"], timeout: 3000 });
300
- } catch {
301
- try {
302
- execSync("pkill ollama", { stdio: ["pipe", "pipe", "pipe"], timeout: 3000 });
303
- } catch { /* already stopped */ }
304
- }
305
- }
306
-
307
- // Verify it stopped
308
- await new Promise(r => setTimeout(r, 500));
309
- const stillRunning = await isOllamaRunning();
310
- if (stillRunning) {
311
- return { ok: false, message: "Ollama is still running. Try killing it manually." };
312
- }
313
- return { ok: true, message: "Ollama stopped." };
314
- } catch (err: any) {
315
- return { ok: false, message: `Failed to stop Ollama: ${err.message}` };
316
- }
317
- }
318
-
319
- /** Delete a model from disk */
320
- export function deleteModel(modelId: string): { ok: boolean; message: string } {
321
- try {
322
- const bin = findOllamaBinary();
323
- execSync(`"${bin}" rm ${modelId}`, { stdio: ["pipe", "pipe", "pipe"], timeout: 30000 });
324
- return { ok: true, message: `Deleted ${modelId}` };
325
- } catch (err: any) {
326
- return { ok: false, message: `Failed to delete ${modelId}: ${err.stderr?.toString().trim() || err.message}` };
327
- }
328
- }
329
-
330
- /** Get GPU memory usage info (best-effort) */
331
- export function getGPUMemoryUsage(): string | null {
332
- try {
333
- if (process.platform === "darwin") {
334
- // Apple Silicon — check memory pressure
335
- const raw = execSync("memory_pressure", { encoding: "utf-8", timeout: 3000, stdio: ["pipe", "pipe", "pipe"] });
336
- const match = raw.match(/System-wide memory free percentage:\s*(\d+)%/);
337
- if (match) {
338
- return `${100 - parseInt(match[1])}% system memory in use`;
339
- }
340
- return null;
341
- }
342
- // NVIDIA GPU
343
- const raw = execSync("nvidia-smi --query-gpu=memory.used,memory.total --format=csv,noheader,nounits", {
344
- encoding: "utf-8", timeout: 3000, stdio: ["pipe", "pipe", "pipe"],
345
- });
346
- const parts = raw.trim().split(",").map(s => s.trim());
347
- if (parts.length === 2) {
348
- return `${parts[0]} MiB / ${parts[1]} MiB GPU memory`;
349
- }
350
- } catch { /* no GPU info available */ }
351
- return null;
352
- }
@@ -1,220 +0,0 @@
1
- import { readFileSync, readdirSync, statSync } from "fs";
2
- import { join, extname, relative } from "path";
3
-
4
- const IGNORE_DIRS = new Set([
5
- "node_modules", ".git", "dist", ".next", "__pycache__", ".pytest_cache",
6
- "target", "build", "out", ".cache", ".parcel-cache", ".nuxt", ".svelte-kit",
7
- "vendor", "venv", ".venv", "env", ".env", "coverage", ".nyc_output",
8
- ]);
9
-
10
- const IGNORE_FILES = new Set([
11
- ".DS_Store", "package-lock.json", "yarn.lock", "pnpm-lock.yaml",
12
- ]);
13
-
14
- const MAX_FILE_SIZE = 100 * 1024;
15
- const MAX_MAP_SIZE = 15 * 1024;
16
-
17
- // ── Per-line regex patterns (no /g flag!) ──
18
-
19
- interface LangPatterns {
20
- patterns: Array<{ kind: string; regex: RegExp; format: (m: RegExpMatchArray) => string }>;
21
- }
22
-
23
- const LANGS: Record<string, LangPatterns> = {
24
- javascript: {
25
- patterns: [
26
- { kind: "fn", regex: /^(?:export\s+)?(?:export\s+default\s+)?(?:async\s+)?function\s+(\w+)\s*\(/, format: (m) => `function ${m[1]}(...)` },
27
- { kind: "arrow", regex: /^(?:export\s+)?(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\(/, format: (m) => `const ${m[1]} = (...)` },
28
- { kind: "cls", regex: /^(?:export\s+)?(?:export\s+default\s+)?class\s+(\w+)/, format: (m) => `class ${m[1]}` },
29
- ],
30
- },
31
- typescript: {
32
- patterns: [
33
- { kind: "fn", regex: /^(?:export\s+)?(?:export\s+default\s+)?(?:async\s+)?function\s+(\w+)/, format: (m) => `function ${m[1]}(...)` },
34
- { kind: "arrow", regex: /^(?:export\s+)?(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\(/, format: (m) => `const ${m[1]} = (...)` },
35
- { kind: "cls", regex: /^(?:export\s+)?(?:export\s+default\s+)?class\s+(\w+)/, format: (m) => `class ${m[1]}` },
36
- { kind: "iface", regex: /^(?:export\s+)?interface\s+(\w+)/, format: (m) => `interface ${m[1]}` },
37
- { kind: "type", regex: /^(?:export\s+)?type\s+(\w+)\s*[=<]/, format: (m) => `type ${m[1]}` },
38
- { kind: "enum", regex: /^(?:export\s+)?enum\s+(\w+)/, format: (m) => `enum ${m[1]}` },
39
- ],
40
- },
41
- python: {
42
- patterns: [
43
- { kind: "fn", regex: /^def\s+(\w+)\s*\(/, format: (m) => `def ${m[1]}(...)` },
44
- { kind: "method", regex: /^\s{2,}def\s+(\w+)\s*\(/, format: (m) => ` def ${m[1]}(...)` },
45
- { kind: "cls", regex: /^class\s+(\w+)/, format: (m) => `class ${m[1]}` },
46
- ],
47
- },
48
- go: {
49
- patterns: [
50
- { kind: "fn", regex: /^func\s+(\w+)\s*\(/, format: (m) => `func ${m[1]}(...)` },
51
- { kind: "method", regex: /^func\s+\((\w+)\s+\*?(\w+)\)\s+(\w+)\s*\(/, format: (m) => `func (${m[2]}) ${m[3]}(...)` },
52
- { kind: "struct", regex: /^type\s+(\w+)\s+struct/, format: (m) => `type ${m[1]} struct` },
53
- { kind: "iface", regex: /^type\s+(\w+)\s+interface/, format: (m) => `type ${m[1]} interface` },
54
- ],
55
- },
56
- rust: {
57
- patterns: [
58
- { kind: "fn", regex: /^(?:pub\s+)?(?:async\s+)?fn\s+(\w+)/, format: (m) => `fn ${m[1]}(...)` },
59
- { kind: "struct", regex: /^(?:pub\s+)?struct\s+(\w+)/, format: (m) => `struct ${m[1]}` },
60
- { kind: "enum", regex: /^(?:pub\s+)?enum\s+(\w+)/, format: (m) => `enum ${m[1]}` },
61
- { kind: "trait", regex: /^(?:pub\s+)?trait\s+(\w+)/, format: (m) => `trait ${m[1]}` },
62
- { kind: "impl", regex: /^impl(?:<[^>]*>)?\s+(?:(\w+)\s+for\s+)?(\w+)/, format: (m) => m[1] ? `impl ${m[1]} for ${m[2]}` : `impl ${m[2]}` },
63
- { kind: "mod", regex: /^(?:pub\s+)?mod\s+(\w+)/, format: (m) => `mod ${m[1]}` },
64
- ],
65
- },
66
- };
67
-
68
- /**
69
- * Get language from extension
70
- */
71
- function getLang(ext: string): string | null {
72
- const map: Record<string, string> = {
73
- ".js": "javascript", ".jsx": "javascript", ".mjs": "javascript", ".cjs": "javascript",
74
- ".ts": "typescript", ".tsx": "typescript",
75
- ".py": "python",
76
- ".go": "go",
77
- ".rs": "rust",
78
- };
79
- return map[ext.toLowerCase()] || null;
80
- }
81
-
82
- /**
83
- * Extract signatures from file content
84
- */
85
- function extractSignatures(content: string, lang: string): string[] {
86
- const sigs: string[] = [];
87
- const langDef = LANGS[lang];
88
- if (!langDef) return sigs;
89
-
90
- const lines = content.split("\n");
91
- const seen = new Set<string>();
92
-
93
- for (const line of lines) {
94
- for (const pattern of langDef.patterns) {
95
- const match = line.match(pattern.regex);
96
- if (match) {
97
- const sig = pattern.format(match);
98
- if (!seen.has(sig)) {
99
- seen.add(sig);
100
- sigs.push(sig);
101
- }
102
- break; // Only match one pattern per line
103
- }
104
- }
105
- }
106
-
107
- return sigs;
108
- }
109
-
110
- /**
111
- * Scan directory for supported files
112
- */
113
- function getFiles(cwd: string): string[] {
114
- const files: string[] = [];
115
-
116
- function walk(dir: string, depth: number) {
117
- if (depth > 5) return;
118
- try {
119
- for (const entry of readdirSync(dir)) {
120
- if (IGNORE_FILES.has(entry) || entry.startsWith(".")) continue;
121
- if (IGNORE_DIRS.has(entry)) continue;
122
- const full = join(dir, entry);
123
-
124
- const stat = statSync(full);
125
- if (stat.isDirectory()) {
126
- walk(full, depth + 1);
127
- } else if (stat.isFile() && stat.size < MAX_FILE_SIZE) {
128
- if (getLang(extname(entry))) files.push(full);
129
- }
130
- }
131
- } catch { /* skip */ }
132
- }
133
-
134
- walk(cwd, 0);
135
- return files;
136
- }
137
-
138
- // ── Cache ──
139
- let cachedMap = "";
140
- let cachedCwd = "";
141
- let cachedTime = 0;
142
- const CACHE_TTL = 60_000;
143
-
144
- /**
145
- * Build the repo map — cached for 1 min
146
- */
147
- export async function buildRepoMap(cwd: string): Promise<string> {
148
- const now = Date.now();
149
- if (cachedMap && cachedCwd === cwd && now - cachedTime < CACHE_TTL) {
150
- return cachedMap;
151
- }
152
-
153
- const files = getFiles(cwd);
154
- const lines: string[] = [];
155
-
156
- for (const file of files) {
157
- const ext = extname(file);
158
- const lang = getLang(ext);
159
- if (!lang) continue;
160
-
161
- try {
162
- const content = readFileSync(file, "utf-8");
163
- const sigs = extractSignatures(content, lang);
164
-
165
- if (sigs.length > 0) {
166
- const relPath = relative(cwd, file);
167
- lines.push(`${relPath}:`);
168
- for (const sig of sigs) {
169
- lines.push(` ${sig}`);
170
- }
171
- lines.push("");
172
-
173
- // Size guard
174
- if (lines.join("\n").length > MAX_MAP_SIZE) {
175
- lines.push(`... (truncated)`);
176
- break;
177
- }
178
- }
179
- } catch { /* skip */ }
180
- }
181
-
182
- const map = lines.length > 0 ? lines.join("\n") : "(no signatures found)";
183
-
184
- cachedMap = map;
185
- cachedCwd = cwd;
186
- cachedTime = now;
187
-
188
- return map;
189
- }
190
-
191
- /**
192
- * Get cached map without rebuilding
193
- */
194
- export function getCachedMap(): string {
195
- return cachedMap;
196
- }
197
-
198
- /**
199
- * Clear the cache
200
- */
201
- export function clearMapCache(): void {
202
- cachedMap = "";
203
- cachedCwd = "";
204
- cachedTime = 0;
205
- }
206
-
207
- /**
208
- * Check if file is supported
209
- */
210
- export function isSupportedFile(filePath: string): boolean {
211
- return !!getLang(extname(filePath).toLowerCase());
212
- }
213
-
214
- export function getSupportedExtensions(): string[] {
215
- return [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".py", ".go", ".rs"];
216
- }
217
-
218
- export function getLanguageForExt(ext: string): string | null {
219
- return getLang(ext);
220
- }