krims-code-cli 1.5.2__py3-none-any.whl

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 (43) hide show
  1. krims_code_cli-1.5.2.dist-info/METADATA +336 -0
  2. krims_code_cli-1.5.2.dist-info/RECORD +43 -0
  3. krims_code_cli-1.5.2.dist-info/WHEEL +5 -0
  4. krims_code_cli-1.5.2.dist-info/entry_points.txt +2 -0
  5. krims_code_cli-1.5.2.dist-info/licenses/LICENSE +21 -0
  6. krims_code_cli-1.5.2.dist-info/top_level.txt +1 -0
  7. krims_pip/__init__.py +1 -0
  8. krims_pip/cli.py +50 -0
  9. krims_pip/node_project/bin/krims-code.js +10 -0
  10. krims_pip/node_project/package-lock.json +793 -0
  11. krims_pip/node_project/package.json +46 -0
  12. krims_pip/node_project/src/agent.js +415 -0
  13. krims_pip/node_project/src/ai/fallback.js +239 -0
  14. krims_pip/node_project/src/ai/google.js +87 -0
  15. krims_pip/node_project/src/ai/providers.js +203 -0
  16. krims_pip/node_project/src/ai/router.js +146 -0
  17. krims_pip/node_project/src/ai/search.js +94 -0
  18. krims_pip/node_project/src/ai/telemetry.js +125 -0
  19. krims_pip/node_project/src/ai/tokens.js +101 -0
  20. krims_pip/node_project/src/ai/universal.js +507 -0
  21. krims_pip/node_project/src/ai/xai.js +50 -0
  22. krims_pip/node_project/src/chat.js +2543 -0
  23. krims_pip/node_project/src/cli.js +632 -0
  24. krims_pip/node_project/src/commands/commit.js +157 -0
  25. krims_pip/node_project/src/commands/dashboard.js +59 -0
  26. krims_pip/node_project/src/commands/github.js +349 -0
  27. krims_pip/node_project/src/commands/index.js +67 -0
  28. krims_pip/node_project/src/commands/status.js +66 -0
  29. krims_pip/node_project/src/commands/teamwork-preview.js +326 -0
  30. krims_pip/node_project/src/commands/theme.js +42 -0
  31. krims_pip/node_project/src/commands/themes.js +30 -0
  32. krims_pip/node_project/src/config.js +400 -0
  33. krims_pip/node_project/src/dashboard.js +112 -0
  34. krims_pip/node_project/src/file-parser.js +164 -0
  35. krims_pip/node_project/src/git.js +41 -0
  36. krims_pip/node_project/src/mic.js +220 -0
  37. krims_pip/node_project/src/modes.js +92 -0
  38. krims_pip/node_project/src/telemetry-server.js +855 -0
  39. krims_pip/node_project/src/ui/banner.js +204 -0
  40. krims_pip/node_project/src/ui/dashboard.html +834 -0
  41. krims_pip/node_project/src/ui/spinner.js +43 -0
  42. krims_pip/node_project/src/ui/theme.js +624 -0
  43. krims_pip/node_project/src/updater.js +196 -0
@@ -0,0 +1,220 @@
1
+ // ═══════════════════════════════════════════════════════════
2
+ // Krims Code AI CLI — Voice Input / Microphone Engine
3
+ // ═══════════════════════════════════════════════════════════
4
+
5
+ import { spawn } from "node:child_process";
6
+ import { platform } from "node:os";
7
+ import fs from "node:fs";
8
+
9
+ /**
10
+ * Starts audio recording from the microphone and returns a handle to stop it.
11
+ * @param {string} wavPath - Path where the .wav file will be saved
12
+ * @returns {Promise<{ stop: () => Promise<void> }>}
13
+ */
14
+ export async function startRecording(wavPath) {
15
+ if (fs.existsSync(wavPath)) {
16
+ try {
17
+ fs.unlinkSync(wavPath);
18
+ } catch (e) {
19
+ // Ignore
20
+ }
21
+ }
22
+
23
+ const isWin = platform() === "win32";
24
+
25
+ if (isWin) {
26
+ // Windows: Use native WinMM MCI API via a background PowerShell process
27
+ const ps = spawn("powershell", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", "-"], {
28
+ stdio: ["pipe", "pipe", "ignore"]
29
+ });
30
+
31
+ ps.stdin.write(`Add-Type -MemberDefinition '[DllImport("winmm.dll", CharSet = CharSet.Ansi)] public static extern int mciSendString(string cmd, System.Text.StringBuilder ret, int len, IntPtr cb);' -Name WinMM -Namespace Win32\r\n`);
32
+ ps.stdin.write(`[Win32.WinMM]::mciSendString("open new Type waveaudio Alias myRecorder", $null, 0, [IntPtr]::Zero)\r\n`);
33
+ ps.stdin.write(`[Win32.WinMM]::mciSendString("record myRecorder", $null, 0, [IntPtr]::Zero)\r\n`);
34
+
35
+ return {
36
+ stop: () => {
37
+ return new Promise((resolve) => {
38
+ ps.on("close", () => {
39
+ resolve();
40
+ });
41
+ const escapedPath = wavPath.replace(/\\/g, "\\\\");
42
+ ps.stdin.write(`[Win32.WinMM]::mciSendString('save myRecorder "${escapedPath}"', $null, 0, [IntPtr]::Zero)\r\n`);
43
+ ps.stdin.write(`[Win32.WinMM]::mciSendString("close myRecorder", $null, 0, [IntPtr]::Zero)\r\n`);
44
+ ps.stdin.write("exit\r\n");
45
+ ps.stdin.end();
46
+ });
47
+ }
48
+ };
49
+ } else {
50
+ // macOS / Linux: Try spawning standard command-line recording tools
51
+ let cmd = "";
52
+ let args = [];
53
+
54
+ // Check if sox/rec is available (highest quality/reliability)
55
+ if (await commandExists("rec")) {
56
+ cmd = "rec";
57
+ args = ["-q", wavPath];
58
+ } else if (await commandExists("arecord")) {
59
+ cmd = "arecord";
60
+ args = ["-f", "cd", "-t", "wav", wavPath];
61
+ } else if (await commandExists("ffmpeg")) {
62
+ cmd = "ffmpeg";
63
+ const isMac = platform() === "darwin";
64
+ args = isMac
65
+ ? ["-y", "-f", "avfoundation", "-i", ":0", wavPath]
66
+ : ["-y", "-f", "alsa", "-i", "default", wavPath];
67
+ } else {
68
+ throw new Error("No recording utility found. On Windows, recording is native. On macOS/Linux, please install 'sox', 'arecord', or 'ffmpeg'.");
69
+ }
70
+
71
+ const proc = spawn(cmd, args, { stdio: "ignore" });
72
+
73
+ return {
74
+ stop: () => {
75
+ return new Promise((resolve) => {
76
+ proc.on("close", () => {
77
+ resolve();
78
+ });
79
+ proc.kill("SIGTERM");
80
+ });
81
+ }
82
+ };
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Helper to check if a command exists in the environment PATH.
88
+ */
89
+ function commandExists(name) {
90
+ return new Promise((resolve) => {
91
+ const isWin = platform() === "win32";
92
+ const checkCmd = isWin ? "where" : "which";
93
+ const check = spawn(checkCmd, [name], { stdio: "ignore" });
94
+ check.on("close", (code) => {
95
+ resolve(code === 0);
96
+ });
97
+ });
98
+ }
99
+
100
+ /**
101
+ * Transcribes a local audio WAV file using the configured AI providers.
102
+ * Priority: Google Gemini -> Groq Whisper -> OpenAI Whisper.
103
+ * @param {string} wavPath - Path to the WAV file
104
+ * @param {object} aiConfig - Active AI configuration
105
+ * @returns {Promise<string>} Transcribed text
106
+ */
107
+ export async function transcribeAudioFile(wavPath, aiConfig) {
108
+ if (!fs.existsSync(wavPath)) {
109
+ throw new Error(`Audio file not found: ${wavPath}`);
110
+ }
111
+
112
+ const fileBuffer = fs.readFileSync(wavPath);
113
+
114
+ // 1. Google Gemini Transcription
115
+ if (aiConfig.GOOGLE_API_KEY) {
116
+ const base64Audio = fileBuffer.toString("base64");
117
+ const model = "gemini-2.5-flash";
118
+ const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${aiConfig.GOOGLE_API_KEY}`;
119
+
120
+ const body = {
121
+ contents: [
122
+ {
123
+ role: "user",
124
+ parts: [
125
+ {
126
+ inlineData: {
127
+ mimeType: "audio/wav",
128
+ data: base64Audio
129
+ }
130
+ },
131
+ {
132
+ text: "Transcribe this audio file exactly as spoken. Output ONLY the plain transcription text, with no extra formatting, conversational filler, timestamps, or commentary. If there is no speech, output an empty string."
133
+ }
134
+ ]
135
+ }
136
+ ]
137
+ };
138
+
139
+ const response = await fetch(url, {
140
+ method: "POST",
141
+ headers: { "Content-Type": "application/json" },
142
+ body: JSON.stringify(body)
143
+ });
144
+
145
+ if (!response.ok) {
146
+ const errorText = await response.text();
147
+ throw new Error(`Gemini transcription error: ${response.statusText}. ${errorText}`);
148
+ }
149
+
150
+ const data = await response.json();
151
+ const candidate = data.candidates?.[0];
152
+ if (!candidate) {
153
+ return "";
154
+ }
155
+
156
+ const text = candidate.content?.parts
157
+ ?.map((p) => p.text)
158
+ .filter(Boolean)
159
+ .join("") || "";
160
+
161
+ // Clean up timestamps if returned (e.g. 00:00:23)
162
+ const cleaned = text.trim();
163
+ if (/^\d{2}:\d{2}:\d{2}$/.test(cleaned)) {
164
+ return "";
165
+ }
166
+ return cleaned;
167
+ }
168
+
169
+ // 2. Groq Whisper / OpenAI Whisper
170
+ let apiKey = aiConfig.GROQ_API_KEY;
171
+ let url = "https://api.groq.com/openai/v1/audio/transcriptions";
172
+ let modelName = "whisper-large-v3";
173
+
174
+ if (!apiKey) {
175
+ apiKey = aiConfig.OPENAI_API_KEY;
176
+ url = "https://api.openai.com/v1/audio/transcriptions";
177
+ modelName = "whisper-1";
178
+ }
179
+
180
+ if (!apiKey) {
181
+ throw new Error("No API key configured for speech-to-text. Please configure GOOGLE_API_KEY, GROQ_API_KEY, or OPENAI_API_KEY.");
182
+ }
183
+
184
+ const boundary = "----WebKitFormBoundary" + Math.random().toString(36).substring(2);
185
+
186
+ const header =
187
+ `--${boundary}\r\n` +
188
+ `Content-Disposition: form-data; name="file"; filename="audio.wav"\r\n` +
189
+ `Content-Type: audio/wav\r\n\r\n`;
190
+
191
+ const modelPart =
192
+ `\r\n--${boundary}\r\n` +
193
+ `Content-Disposition: form-data; name="model"\r\n\r\n${modelName}\r\n`;
194
+
195
+ const footer = `--${boundary}--\r\n`;
196
+
197
+ const body = Buffer.concat([
198
+ Buffer.from(header, 'utf-8'),
199
+ fileBuffer,
200
+ Buffer.from(modelPart, 'utf-8'),
201
+ Buffer.from(footer, 'utf-8')
202
+ ]);
203
+
204
+ const response = await fetch(url, {
205
+ method: "POST",
206
+ headers: {
207
+ "Authorization": `Bearer ${apiKey}`,
208
+ "Content-Type": `multipart/form-data; boundary=${boundary}`
209
+ },
210
+ body: body
211
+ });
212
+
213
+ if (!response.ok) {
214
+ const errorText = await response.text();
215
+ throw new Error(`Whisper transcription error: ${response.statusText}. ${errorText}`);
216
+ }
217
+
218
+ const data = await response.json();
219
+ return (data.text || "").trim();
220
+ }
@@ -0,0 +1,92 @@
1
+ // ═══════════════════════════════════════════════════════════
2
+ // Krims Code AI CLI — Mode Definitions
3
+ // ═══════════════════════════════════════════════════════════
4
+
5
+ /**
6
+ * AI reasoning mode definitions for Krims Code.
7
+ * Each mode controls the system prompt, signal metrics, and response style.
8
+ */
9
+ export const MODES = {
10
+ synthesis: {
11
+ name: "synthesis",
12
+ label: "Synthesis v2.5",
13
+ layer: "Layer 2.5",
14
+ description: "Balanced reasoning with clean structure and direct answers.",
15
+ signal: { reasoning: 72, clarity: 80, systemIQ: 70, delivery: 82 },
16
+ systemPrompt: [
17
+ "You are Krims Code, an advanced AI assistant running in Synthesis mode.",
18
+ "Provide balanced, clearly structured responses with direct answers.",
19
+ "Keep responses concise but thorough. Use markdown formatting.",
20
+ "Focus on clarity and practical utility. Avoid unnecessary verbosity.",
21
+ "CRITICAL: If the user asks who created you or who made you, you must answer that you were created by Krishiv PB.",
22
+ "FILE ACTIONS: If the user requests to create, write, or save a file, format the file content inside: [WRITE_FILE: path/to/file.ext]\\n<content>\\n[END_WRITE]. Krims Code CLI will intercept this block and write the file locally."
23
+ ].join(" "),
24
+ },
25
+
26
+ research: {
27
+ name: "research",
28
+ label: "Research v104",
29
+ layer: "Layer 104",
30
+ description: "Deep analysis with comparisons and evidence-based reasoning.",
31
+ signal: { reasoning: 85, clarity: 78, systemIQ: 82, delivery: 75 },
32
+ systemPrompt: [
33
+ "You are Krims Code, an advanced AI assistant running in Research mode.",
34
+ "Provide deep analytical responses with evidence-based reasoning.",
35
+ "Include comparisons, citations where relevant, and thorough analysis.",
36
+ "Break down complex topics systematically. Use markdown with headers and lists.",
37
+ "CRITICAL: If the user asks who created you or who made you, you must answer that you were created by Krishiv PB.",
38
+ "FILE ACTIONS: If the user requests to create, write, or save a file, format the file content inside: [WRITE_FILE: path/to/file.ext]\\n<content>\\n[END_WRITE]. Krims Code CLI will intercept this block and write the file locally."
39
+ ].join(" "),
40
+ },
41
+
42
+ architect: {
43
+ name: "architect",
44
+ label: "Architect v55",
45
+ layer: "Layer 55",
46
+ description: "Systems thinking with debugging plans and build strategies.",
47
+ signal: { reasoning: 78, clarity: 74, systemIQ: 90, delivery: 72 },
48
+ systemPrompt: [
49
+ "You are Krims Code, an advanced AI assistant running in Architect mode.",
50
+ "Focus on systems thinking, architecture design, and debugging plans.",
51
+ "Provide step-by-step build strategies and implementation roadmaps.",
52
+ "Think about edge cases, scalability, and best practices. Use code blocks when relevant.",
53
+ "CRITICAL: If the user asks who created you or who made you, you must answer that you were created by Krishiv PB.",
54
+ "FILE ACTIONS: If the user requests to create, write, or save a file, format the file content inside: [WRITE_FILE: path/to/file.ext]\\n<content>\\n[END_WRITE]. Krims Code CLI will intercept this block and write the file locally."
55
+ ].join(" "),
56
+ },
57
+
58
+ titan: {
59
+ name: "titan",
60
+ label: "Titan Fusion v110",
61
+ layer: "Layer 110",
62
+ description: "Long-form premium responses with high signal density and multi-step output fusing Codex and Claude Code capabilities.",
63
+ signal: { reasoning: 94, clarity: 92, systemIQ: 96, delivery: 90 },
64
+ systemPrompt: [
65
+ "You are Krims Code, an advanced AI assistant running in Titan Fusion mode — the most powerful configuration.",
66
+ "This mode fuses the absolute best capabilities of OpenAI Codex (optimized specifically for high-fidelity code generation to write robust, syntactically correct, and beautifully structured source code across all programming languages like HTML, CSS, JavaScript, Python, C++, Go, etc.) and Claude Code (an agentic developer configuration designed for sophisticated software engineering, specializing in systems refactoring, code editing, full-stack web application development, and debugging complex codebases).",
67
+ "Your primary objective is to deliver production-ready, highly functional, and ready-to-run code, detailed architectural designs, and systematic implementation plans with minimum conversational filler.",
68
+ "Generate complete, clean code blocks and explain implementation plans systematically, treating every response as an engineering masterclass.",
69
+ "Minimize conversational filler, explain code concisely when asked, and output highly functional, ready-to-run files.",
70
+ "CRITICAL: If the user asks who created you or who made you, you must answer that you were created by Krishiv PB.",
71
+ "FILE ACTIONS: If the user requests to create, write, or save a file, format the file content inside: [WRITE_FILE: path/to/file.ext]\n<content>\n[END_WRITE]. Krims Code CLI will intercept this block and write the file locally."
72
+ ].join(" "),
73
+ },
74
+
75
+ };
76
+
77
+ /** The default mode key */
78
+ export const DEFAULT_MODE = "titan";
79
+
80
+ /**
81
+ * Looks up a mode by name (case-insensitive).
82
+ * @param {string} name - Mode name to look up
83
+ * @returns {object|null} The mode definition, or null if not found
84
+ */
85
+ export function getModeByName(name) {
86
+ if (!name) return null;
87
+ const key = name.toLowerCase().trim();
88
+ if (key === "claude-code" || key === "claude" || key === "cloude-code" || key === "codex") {
89
+ return MODES["titan"];
90
+ }
91
+ return MODES[key] || null;
92
+ }