codemaxxing 0.4.6 โ†’ 0.4.8

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/dist/index.js CHANGED
@@ -1465,34 +1465,40 @@ function App() {
1465
1465
  if (key.return) {
1466
1466
  // Auto-install Ollama if not present
1467
1467
  if (!isOllamaInstalled()) {
1468
- addMsg("info", "๐Ÿ“ฆ Installing Ollama... (this may take a minute)");
1468
+ setWizardPullProgress({ status: "Installing Ollama...", percent: 0 });
1469
+ setWizardScreen("pulling");
1470
+ // Run install async so the UI can update
1469
1471
  const installCmd = getOllamaInstallCommand(wizardHardware?.os ?? "linux");
1470
- try {
1471
- // Use pipe instead of inherit โ€” Ink TUI conflicts with inherit stdio
1472
- const parts = installCmd.split(" ");
1473
- const result = _require("child_process").spawnSync(parts[0], parts.slice(1), {
1474
- stdio: "pipe",
1475
- timeout: 180000,
1476
- shell: true,
1477
- encoding: "utf-8",
1478
- });
1479
- if (result.status === 0) {
1480
- addMsg("info", "โœ… Ollama installed!");
1472
+ (async () => {
1473
+ try {
1474
+ const { execFile } = _require("child_process");
1475
+ const parts = installCmd.split(" ");
1476
+ await new Promise((resolve, reject) => {
1477
+ execFile(parts[0], parts.slice(1), { shell: true, timeout: 180000 }, (err, _stdout, stderr) => {
1478
+ if (err)
1479
+ reject(new Error(stderr || err.message));
1480
+ else
1481
+ resolve();
1482
+ });
1483
+ });
1484
+ addMsg("info", "โœ… Ollama installed! Proceeding to model download...");
1485
+ // Small delay for PATH to update on Windows
1486
+ await new Promise(r => setTimeout(r, 2000));
1487
+ // Go back to models screen so user can pick and it'll proceed to pull
1488
+ setWizardScreen("models");
1489
+ setWizardPullProgress(null);
1481
1490
  }
1482
- else {
1483
- const errMsg = (result.stderr || result.stdout || "").trim().split("\n").pop() || "Unknown error";
1484
- addMsg("error", `Install failed: ${errMsg}`);
1491
+ catch (e) {
1492
+ addMsg("error", `Install failed: ${e.message}`);
1485
1493
  addMsg("info", `Try manually in a separate terminal: ${installCmd}`);
1486
- return;
1494
+ setWizardScreen("install-ollama");
1495
+ setWizardPullProgress(null);
1487
1496
  }
1488
- }
1489
- catch (e) {
1490
- addMsg("error", `Install failed: ${e.message}`);
1491
- addMsg("info", `Try manually in a separate terminal: ${installCmd}`);
1492
- return;
1493
- }
1497
+ })();
1498
+ return;
1494
1499
  }
1495
- if (isOllamaInstalled()) {
1500
+ // Ollama already installed โ€” proceed to pull
1501
+ {
1496
1502
  const selected = wizardSelectedModel;
1497
1503
  if (selected) {
1498
1504
  setWizardScreen("pulling");
@@ -1820,7 +1826,7 @@ function App() {
1820
1826
  { key: "openrouter", icon: "\uD83C\uDF10", label: "OpenRouter", desc: "200+ cloud models, browser login" },
1821
1827
  { key: "apikey", icon: "\uD83D\uDD11", label: "Enter API key manually", desc: "" },
1822
1828
  { key: "existing", icon: "\u2699\uFE0F", label: "I already have a server running", desc: "" },
1823
- ].map((item, i) => (_jsxs(Text, { children: [i === wizardIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: " \u25B8 " }) : _jsx(Text, { children: " " }), _jsxs(Text, { color: i === wizardIndex ? theme.colors.suggestion : theme.colors.primary, bold: true, children: [item.icon, " ", item.label] }), item.desc ? _jsxs(Text, { color: theme.colors.muted, children: [" (", item.desc, ")"] }) : null] }, item.key))), _jsx(Text, { children: "" }), _jsx(Text, { dimColor: true, children: " \u2191\u2193 navigate \u00B7 Enter to select" })] })), wizardScreen === "models" && wizardHardware && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.border, paddingX: 1, marginBottom: 0, children: [_jsx(Text, { bold: true, color: theme.colors.secondary, children: "Your hardware:" }), _jsxs(Text, { color: theme.colors.muted, children: [" CPU: ", wizardHardware.cpu.name, " (", wizardHardware.cpu.cores, " cores)"] }), _jsxs(Text, { color: theme.colors.muted, children: [" RAM: ", formatBytes(wizardHardware.ram)] }), wizardHardware.gpu ? (_jsxs(Text, { color: theme.colors.muted, children: [" GPU: ", wizardHardware.gpu.name, wizardHardware.gpu.vram > 0 ? ` (${formatBytes(wizardHardware.gpu.vram)})` : ""] })) : (_jsx(Text, { color: theme.colors.muted, children: " GPU: none detected" })), !isLlmfitAvailable() && (_jsx(Text, { dimColor: true, children: " Tip: Install llmfit for smarter recommendations: brew install llmfit" })), _jsx(Text, { children: "" }), _jsx(Text, { bold: true, color: theme.colors.secondary, children: "Recommended models:" }), _jsx(Text, { children: "" }), wizardModels.map((m, i) => (_jsxs(Text, { children: [i === wizardIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: " \u25B8 " }) : _jsx(Text, { children: " " }), _jsxs(Text, { children: [getFitIcon(m.fit), " "] }), _jsx(Text, { color: i === wizardIndex ? theme.colors.suggestion : theme.colors.primary, bold: true, children: m.name }), _jsxs(Text, { color: theme.colors.muted, children: [" ~", m.size, " GB \u00B7 ", m.quality === "best" ? "Best" : m.quality === "great" ? "Great" : "Good", " quality \u00B7 ", m.speed] })] }, m.ollamaId))), wizardModels.length === 0 && (_jsx(Text, { color: theme.colors.error, children: " No suitable models found for your hardware." })), _jsx(Text, { children: "" }), _jsx(Text, { dimColor: true, children: " \u2191\u2193 navigate \u00B7 Enter to install \u00B7 Esc back" })] })), wizardScreen === "install-ollama" && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.warning, paddingX: 1, marginBottom: 0, children: [_jsx(Text, { bold: true, color: theme.colors.warning, children: "Ollama is required for local models." }), _jsx(Text, { children: "" }), _jsx(Text, { color: theme.colors.primary, children: " Press Enter to install Ollama automatically" }), _jsxs(Text, { dimColor: true, children: [" Or install manually: ", _jsx(Text, { children: getOllamaInstallCommand(wizardHardware?.os ?? "linux") })] }), _jsx(Text, { children: "" }), _jsx(Text, { dimColor: true, children: " Enter to install ยท Esc to go back" })] })), wizardScreen === "pulling" && wizardSelectedModel && (_jsx(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.border, paddingX: 1, marginBottom: 0, children: wizardPullError ? (_jsxs(_Fragment, { children: [_jsxs(Text, { color: theme.colors.error, bold: true, children: [" \u274C Error: ", wizardPullError] }), _jsx(Text, { children: "" }), _jsx(Text, { dimColor: true, children: " Press Enter to retry \u00B7 Esc to go back" })] })) : wizardPullProgress ? (_jsxs(_Fragment, { children: [_jsxs(Text, { bold: true, color: theme.colors.secondary, children: [" Downloading ", wizardSelectedModel.name, "..."] }), wizardPullProgress.status === "downloading" || wizardPullProgress.percent > 0 ? (_jsx(_Fragment, { children: _jsxs(Text, { children: [" ", _jsxs(Text, { color: theme.colors.primary, children: ["\u2588".repeat(Math.floor(wizardPullProgress.percent / 5)), "\u2591".repeat(20 - Math.floor(wizardPullProgress.percent / 5))] }), " ", _jsxs(Text, { bold: true, children: [wizardPullProgress.percent, "%"] }), wizardPullProgress.completed != null && wizardPullProgress.total != null ? (_jsxs(Text, { color: theme.colors.muted, children: [" \u00B7 ", formatBytes(wizardPullProgress.completed), " / ", formatBytes(wizardPullProgress.total)] })) : null] }) })) : (_jsxs(Text, { color: theme.colors.muted, children: [" ", wizardPullProgress.status, "..."] }))] })) : null })), showSuggestions && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.muted, paddingX: 1, marginBottom: 0, children: [cmdMatches.slice(0, 6).map((c, i) => (_jsxs(Text, { children: [i === cmdIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: "โ–ธ " }) : _jsx(Text, { children: " " }), _jsx(Text, { color: i === cmdIndex ? theme.colors.suggestion : theme.colors.primary, bold: true, children: c.cmd }), _jsxs(Text, { color: theme.colors.muted, children: [" โ€” ", c.desc] })] }, i))), _jsx(Text, { dimColor: true, children: " โ†‘โ†“ navigate ยท Tab select" })] })), _jsxs(Box, { borderStyle: "single", borderColor: approval ? theme.colors.warning : theme.colors.border, paddingX: 1, children: [_jsx(Text, { color: theme.colors.secondary, bold: true, children: "> " }), approval ? (_jsx(Text, { color: theme.colors.warning, children: "waiting for approval..." })) : ready && !loading ? (_jsxs(Box, { children: [pastedChunks.map((p) => (_jsxs(Text, { color: theme.colors.muted, children: ["[Pasted text #", p.id, " +", p.lines, " lines]"] }, p.id))), _jsx(TextInput, { value: input, onChange: (v) => { setInput(v); setCmdIndex(0); }, onSubmit: handleSubmit }, inputKey)] })) : (_jsx(Text, { dimColor: true, children: loading ? "waiting for response..." : "initializing..." }))] }), agent && (_jsx(Box, { paddingX: 2, children: _jsxs(Text, { dimColor: true, children: ["๐Ÿ’ฌ ", agent.getContextLength(), " messages ยท ~", (() => {
1829
+ ].map((item, i) => (_jsxs(Text, { children: [i === wizardIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: " \u25B8 " }) : _jsx(Text, { children: " " }), _jsxs(Text, { color: i === wizardIndex ? theme.colors.suggestion : theme.colors.primary, bold: true, children: [item.icon, " ", item.label] }), item.desc ? _jsxs(Text, { color: theme.colors.muted, children: [" (", item.desc, ")"] }) : null] }, item.key))), _jsx(Text, { children: "" }), _jsx(Text, { dimColor: true, children: " \u2191\u2193 navigate \u00B7 Enter to select" })] })), wizardScreen === "models" && wizardHardware && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.border, paddingX: 1, marginBottom: 0, children: [_jsx(Text, { bold: true, color: theme.colors.secondary, children: "Your hardware:" }), _jsxs(Text, { color: theme.colors.muted, children: [" CPU: ", wizardHardware.cpu.name, " (", wizardHardware.cpu.cores, " cores)"] }), _jsxs(Text, { color: theme.colors.muted, children: [" RAM: ", formatBytes(wizardHardware.ram)] }), wizardHardware.gpu ? (_jsxs(Text, { color: theme.colors.muted, children: [" GPU: ", wizardHardware.gpu.name, wizardHardware.gpu.vram > 0 ? ` (${formatBytes(wizardHardware.gpu.vram)})` : ""] })) : (_jsx(Text, { color: theme.colors.muted, children: " GPU: none detected" })), !isLlmfitAvailable() && (_jsx(Text, { dimColor: true, children: " Tip: Install llmfit for smarter recommendations: brew install llmfit" })), _jsx(Text, { children: "" }), _jsx(Text, { bold: true, color: theme.colors.secondary, children: "Recommended models:" }), _jsx(Text, { children: "" }), wizardModels.map((m, i) => (_jsxs(Text, { children: [i === wizardIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: " \u25B8 " }) : _jsx(Text, { children: " " }), _jsxs(Text, { children: [getFitIcon(m.fit), " "] }), _jsx(Text, { color: i === wizardIndex ? theme.colors.suggestion : theme.colors.primary, bold: true, children: m.name }), _jsxs(Text, { color: theme.colors.muted, children: [" ~", m.size, " GB \u00B7 ", m.quality === "best" ? "Best" : m.quality === "great" ? "Great" : "Good", " quality \u00B7 ", m.speed] })] }, m.ollamaId))), wizardModels.length === 0 && (_jsx(Text, { color: theme.colors.error, children: " No suitable models found for your hardware." })), _jsx(Text, { children: "" }), _jsx(Text, { dimColor: true, children: " \u2191\u2193 navigate \u00B7 Enter to install \u00B7 Esc back" })] })), wizardScreen === "install-ollama" && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.warning, paddingX: 1, marginBottom: 0, children: [_jsx(Text, { bold: true, color: theme.colors.warning, children: "Ollama is required for local models." }), _jsx(Text, { children: "" }), _jsx(Text, { color: theme.colors.primary, children: " Press Enter to install Ollama automatically" }), _jsxs(Text, { dimColor: true, children: [" Or install manually: ", _jsx(Text, { children: getOllamaInstallCommand(wizardHardware?.os ?? "linux") })] }), _jsx(Text, { children: "" }), _jsx(Text, { dimColor: true, children: " Enter to install ยท Esc to go back" })] })), wizardScreen === "pulling" && (wizardSelectedModel || wizardPullProgress) && (_jsx(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.border, paddingX: 1, marginBottom: 0, children: wizardPullError ? (_jsxs(_Fragment, { children: [_jsxs(Text, { color: theme.colors.error, bold: true, children: [" \u274C Error: ", wizardPullError] }), _jsx(Text, { children: "" }), _jsx(Text, { dimColor: true, children: " Press Enter to retry \u00B7 Esc to go back" })] })) : wizardPullProgress ? (_jsxs(_Fragment, { children: [_jsxs(Text, { bold: true, color: theme.colors.secondary, children: [" ", wizardSelectedModel ? `Downloading ${wizardSelectedModel.name}...` : wizardPullProgress?.status || "Working..."] }), wizardPullProgress.status === "downloading" || wizardPullProgress.percent > 0 ? (_jsx(_Fragment, { children: _jsxs(Text, { children: [" ", _jsxs(Text, { color: theme.colors.primary, children: ["\u2588".repeat(Math.floor(wizardPullProgress.percent / 5)), "\u2591".repeat(20 - Math.floor(wizardPullProgress.percent / 5))] }), " ", _jsxs(Text, { bold: true, children: [wizardPullProgress.percent, "%"] }), wizardPullProgress.completed != null && wizardPullProgress.total != null ? (_jsxs(Text, { color: theme.colors.muted, children: [" \u00B7 ", formatBytes(wizardPullProgress.completed), " / ", formatBytes(wizardPullProgress.total)] })) : null] }) })) : (_jsxs(Text, { color: theme.colors.muted, children: [" ", wizardPullProgress.status, "..."] }))] })) : null })), showSuggestions && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.muted, paddingX: 1, marginBottom: 0, children: [cmdMatches.slice(0, 6).map((c, i) => (_jsxs(Text, { children: [i === cmdIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: "โ–ธ " }) : _jsx(Text, { children: " " }), _jsx(Text, { color: i === cmdIndex ? theme.colors.suggestion : theme.colors.primary, bold: true, children: c.cmd }), _jsxs(Text, { color: theme.colors.muted, children: [" โ€” ", c.desc] })] }, i))), _jsx(Text, { dimColor: true, children: " โ†‘โ†“ navigate ยท Tab select" })] })), _jsxs(Box, { borderStyle: "single", borderColor: approval ? theme.colors.warning : theme.colors.border, paddingX: 1, children: [_jsx(Text, { color: theme.colors.secondary, bold: true, children: "> " }), approval ? (_jsx(Text, { color: theme.colors.warning, children: "waiting for approval..." })) : ready && !loading && !wizardScreen ? (_jsxs(Box, { children: [pastedChunks.map((p) => (_jsxs(Text, { color: theme.colors.muted, children: ["[Pasted text #", p.id, " +", p.lines, " lines]"] }, p.id))), _jsx(TextInput, { value: input, onChange: (v) => { setInput(v); setCmdIndex(0); }, onSubmit: handleSubmit }, inputKey)] })) : (_jsx(Text, { dimColor: true, children: loading ? "waiting for response..." : "initializing..." }))] }), agent && (_jsx(Box, { paddingX: 2, children: _jsxs(Text, { dimColor: true, children: ["๐Ÿ’ฌ ", agent.getContextLength(), " messages ยท ~", (() => {
1824
1830
  const tokens = agent.estimateTokens();
1825
1831
  return tokens >= 1000 ? `${(tokens / 1000).toFixed(1)}k` : String(tokens);
1826
1832
  })(), " tokens", (() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codemaxxing",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
4
4
  "description": "Open-source terminal coding agent. Connect any LLM. Max your code.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/src/index.tsx CHANGED
@@ -1489,32 +1489,38 @@ function App() {
1489
1489
  if (key.return) {
1490
1490
  // Auto-install Ollama if not present
1491
1491
  if (!isOllamaInstalled()) {
1492
- addMsg("info", "๐Ÿ“ฆ Installing Ollama... (this may take a minute)");
1492
+ setWizardPullProgress({ status: "Installing Ollama...", percent: 0 });
1493
+ setWizardScreen("pulling");
1494
+
1495
+ // Run install async so the UI can update
1493
1496
  const installCmd = getOllamaInstallCommand(wizardHardware?.os ?? "linux");
1494
- try {
1495
- // Use pipe instead of inherit โ€” Ink TUI conflicts with inherit stdio
1496
- const parts = installCmd.split(" ");
1497
- const result = _require("child_process").spawnSync(parts[0], parts.slice(1), {
1498
- stdio: "pipe",
1499
- timeout: 180000,
1500
- shell: true,
1501
- encoding: "utf-8",
1502
- });
1503
- if (result.status === 0) {
1504
- addMsg("info", "โœ… Ollama installed!");
1505
- } else {
1506
- const errMsg = (result.stderr || result.stdout || "").trim().split("\n").pop() || "Unknown error";
1507
- addMsg("error", `Install failed: ${errMsg}`);
1497
+ (async () => {
1498
+ try {
1499
+ const { execFile } = _require("child_process");
1500
+ const parts = installCmd.split(" ");
1501
+ await new Promise<void>((resolve, reject) => {
1502
+ execFile(parts[0], parts.slice(1), { shell: true, timeout: 180000 }, (err: any, _stdout: string, stderr: string) => {
1503
+ if (err) reject(new Error(stderr || err.message));
1504
+ else resolve();
1505
+ });
1506
+ });
1507
+ addMsg("info", "โœ… Ollama installed! Proceeding to model download...");
1508
+ // Small delay for PATH to update on Windows
1509
+ await new Promise(r => setTimeout(r, 2000));
1510
+ // Go back to models screen so user can pick and it'll proceed to pull
1511
+ setWizardScreen("models");
1512
+ setWizardPullProgress(null);
1513
+ } catch (e: any) {
1514
+ addMsg("error", `Install failed: ${e.message}`);
1508
1515
  addMsg("info", `Try manually in a separate terminal: ${installCmd}`);
1509
- return;
1516
+ setWizardScreen("install-ollama");
1517
+ setWizardPullProgress(null);
1510
1518
  }
1511
- } catch (e: any) {
1512
- addMsg("error", `Install failed: ${e.message}`);
1513
- addMsg("info", `Try manually in a separate terminal: ${installCmd}`);
1514
- return;
1515
- }
1519
+ })();
1520
+ return;
1516
1521
  }
1517
- if (isOllamaInstalled()) {
1522
+ // Ollama already installed โ€” proceed to pull
1523
+ {
1518
1524
  const selected = wizardSelectedModel;
1519
1525
  if (selected) {
1520
1526
  setWizardScreen("pulling");
@@ -2178,7 +2184,7 @@ function App() {
2178
2184
  </Box>
2179
2185
  )}
2180
2186
 
2181
- {wizardScreen === "pulling" && wizardSelectedModel && (
2187
+ {wizardScreen === "pulling" && (wizardSelectedModel || wizardPullProgress) && (
2182
2188
  <Box flexDirection="column" borderStyle="single" borderColor={theme.colors.border} paddingX={1} marginBottom={0}>
2183
2189
  {wizardPullError ? (
2184
2190
  <>
@@ -2188,7 +2194,7 @@ function App() {
2188
2194
  </>
2189
2195
  ) : wizardPullProgress ? (
2190
2196
  <>
2191
- <Text bold color={theme.colors.secondary}>{" Downloading "}{wizardSelectedModel.name}{"..."}</Text>
2197
+ <Text bold color={theme.colors.secondary}>{" "}{wizardSelectedModel ? `Downloading ${wizardSelectedModel.name}...` : wizardPullProgress?.status || "Working..."}</Text>
2192
2198
  {wizardPullProgress.status === "downloading" || wizardPullProgress.percent > 0 ? (
2193
2199
  <>
2194
2200
  <Text>
@@ -2230,7 +2236,7 @@ function App() {
2230
2236
  <Text color={theme.colors.secondary} bold>{"> "}</Text>
2231
2237
  {approval ? (
2232
2238
  <Text color={theme.colors.warning}>waiting for approval...</Text>
2233
- ) : ready && !loading ? (
2239
+ ) : ready && !loading && !wizardScreen ? (
2234
2240
  <Box>
2235
2241
  {pastedChunks.map((p) => (
2236
2242
  <Text key={p.id} color={theme.colors.muted}>[Pasted text #{p.id} +{p.lines} lines]</Text>