codeep 1.0.114 → 1.0.116

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.
@@ -147,6 +147,10 @@ const isSectionBreak = (line, prevLine) => {
147
147
  };
148
148
  const MAX_PREVIEW_LINES = 8; // Code preview lines (total box will be ~10 with header/footer)
149
149
  export const LiveCodeStream = memo(({ actions, isRunning, terminalWidth = 80 }) => {
150
+ // Find the current write/edit action for live preview
151
+ const currentAction = actions.length > 0 ? actions[actions.length - 1] : null;
152
+ const isCodeAction = currentAction && (currentAction.type === 'write' || currentAction.type === 'edit');
153
+ // ALL HOOKS MUST BE CALLED BEFORE ANY EARLY RETURNS (Rules of Hooks)
150
154
  // Calculate statistics from all actions
151
155
  const stats = useMemo(() => {
152
156
  const filesCreated = actions.filter(a => a.type === 'write' && a.result === 'success');
@@ -174,19 +178,16 @@ export const LiveCodeStream = memo(({ actions, isRunning, terminalWidth = 80 })
174
178
  editedFiles: filesEdited.map(a => a.target.split('/').pop() || a.target),
175
179
  };
176
180
  }, [actions]);
177
- // Find the current write/edit action for live preview
178
- const currentAction = actions.length > 0 ? actions[actions.length - 1] : null;
179
- const isCodeAction = currentAction && (currentAction.type === 'write' || currentAction.type === 'edit');
180
- // Don't render anything if no actions yet (agent just started)
181
- if (actions.length === 0) {
182
- return null;
183
- }
184
181
  // Get code lines for preview
185
182
  const codeLines = useMemo(() => {
186
183
  if (!isCodeAction || !currentAction?.details)
187
184
  return [];
188
185
  return currentAction.details.split('\n');
189
186
  }, [isCodeAction, currentAction?.details]);
187
+ // Don't render anything if no actions yet (agent just started)
188
+ if (actions.length === 0) {
189
+ return null;
190
+ }
190
191
  const filename = currentAction?.target.split('/').pop() || '';
191
192
  const ext = getFileExtension(filename);
192
193
  const langLabel = getLanguageLabel(ext);
@@ -1,8 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Box, Text, useInput } from 'ink';
2
+ import { useState, useEffect } from 'react';
3
+ import { Box, Text, useInput, useStdout } from 'ink';
4
4
  export const Export = ({ onExport, onCancel }) => {
5
+ const { stdout } = useStdout();
5
6
  const [selectedIndex, setSelectedIndex] = useState(0);
7
+ useEffect(() => {
8
+ stdout?.write('\x1b[2J\x1b[H');
9
+ }, [stdout]);
6
10
  const formats = [
7
11
  { id: 'md', name: 'Markdown', description: 'Formatted with headers and separators' },
8
12
  { id: 'json', name: 'JSON', description: 'Structured data format' },
@@ -1,3 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Text, Box } from 'ink';
3
- export const Help = () => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "#f02a30", bold: true, children: "Available Commands" }), _jsx(Text, { children: " " }), _jsxs(Box, { flexDirection: "row", gap: 2, children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/help" }), " - Show this help"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/status" }), " - Current status"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/settings" }), " - Adjust settings"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/sessions" }), " - Manage sessions"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/grant" }), " - Grant permissions"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/agent" }), " ", '<task>', " - Run agent"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/clear" }), " - Clear chat"] })] }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/model" }), " - Switch model"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/provider" }), " - Switch provider"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/diff" }), " - Review git changes"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/commit" }), " - Generate commit msg"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/export" }), " - Export chat"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/copy" }), " [n] - Copy code block"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/exit" }), " - Quit"] })] })] }), _jsx(Text, { children: " " }), _jsx(Text, { color: "cyan", children: "Type / to see autocomplete. Docs: github.com/VladoIvankovic/Codeep" })] }));
2
+ import { useEffect } from 'react';
3
+ import { Text, Box, useStdout } from 'ink';
4
+ export const Help = () => {
5
+ const { stdout } = useStdout();
6
+ // Clear screen on mount to show fullscreen view
7
+ useEffect(() => {
8
+ stdout?.write('\x1b[2J\x1b[H');
9
+ }, [stdout]);
10
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "#f02a30", bold: true, children: "Available Commands" }), _jsx(Text, { children: " " }), _jsxs(Box, { flexDirection: "row", gap: 2, children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/help" }), " - Show this help"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/status" }), " - Current status"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/settings" }), " - Adjust settings"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/sessions" }), " - Manage sessions"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/grant" }), " - Grant permissions"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/agent" }), " ", '<task>', " - Run agent"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/clear" }), " - Clear chat"] })] }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/model" }), " - Switch model"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/provider" }), " - Switch provider"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/diff" }), " - Review git changes"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/commit" }), " - Generate commit msg"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/export" }), " - Export chat"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/copy" }), " [n] - Copy code block"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "/exit" }), " - Quit"] })] })] }), _jsx(Text, { children: " " }), _jsx(Text, { color: "cyan", children: "Type / to see autocomplete. Docs: github.com/VladoIvankovic/Codeep" })] }));
11
+ };
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Text, Box, useInput } from 'ink';
2
+ import { useState, useEffect } from 'react';
3
+ import { Text, Box, useInput, useStdout } from 'ink';
4
4
  import TextInput from 'ink-text-input';
5
5
  import open from 'open';
6
6
  import { setApiKey, setProvider } from '../config/index.js';
@@ -12,11 +12,15 @@ const PROVIDER_URLS = {
12
12
  'minimax': 'https://platform.minimax.io/subscribe/coding-plan?code=2lWvoWUhrp&source=link',
13
13
  };
14
14
  export const Login = ({ onLogin, onCancel }) => {
15
+ const { stdout } = useStdout();
15
16
  const [step, setStep] = useState('provider');
16
17
  const [selectedProvider, setSelectedProvider] = useState(0);
17
18
  const [apiKey, setApiKeyState] = useState('');
18
19
  const [error, setError] = useState('');
19
20
  const [validating, setValidating] = useState(false);
21
+ useEffect(() => {
22
+ stdout?.write('\x1b[2J\x1b[H');
23
+ }, [stdout]);
20
24
  const providers = getProviderList();
21
25
  const currentProvider = providers[selectedProvider];
22
26
  // Handle keyboard input
@@ -1,11 +1,15 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Text, Box, useInput } from 'ink';
2
+ import { useState, useEffect } from 'react';
3
+ import { Text, Box, useInput, useStdout } from 'ink';
4
4
  import { getConfiguredProviders, clearApiKey, getCurrentProvider } from '../config/index.js';
5
5
  export const LogoutPicker = ({ onLogout, onLogoutAll, onCancel }) => {
6
+ const { stdout } = useStdout();
6
7
  const providers = getConfiguredProviders();
7
8
  const currentProvider = getCurrentProvider();
8
9
  const [selectedIndex, setSelectedIndex] = useState(0);
10
+ useEffect(() => {
11
+ stdout?.write('\x1b[2J\x1b[H');
12
+ }, [stdout]);
9
13
  // Options: individual providers + "All" + "Cancel"
10
14
  const options = [
11
15
  ...providers.map(p => ({
@@ -1,11 +1,15 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Box, Text, useInput } from 'ink';
2
+ import { useState, useEffect } from 'react';
3
+ import { Box, Text, useInput, useStdout } from 'ink';
4
4
  import { setProjectPermission } from '../config/index.js';
5
5
  import { getProjectSummary } from '../utils/project.js';
6
6
  export const ProjectPermission = ({ projectPath, onComplete }) => {
7
+ const { stdout } = useStdout();
7
8
  const [step, setStep] = useState('read');
8
9
  const [readGranted, setReadGranted] = useState(false);
10
+ useEffect(() => {
11
+ stdout?.write('\x1b[2J\x1b[H');
12
+ }, [stdout]);
9
13
  const summary = getProjectSummary(projectPath);
10
14
  const projectName = summary?.name || projectPath.split('/').pop() || 'Unknown';
11
15
  useInput((input, key) => {
@@ -1,8 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Box, Text, useInput } from 'ink';
2
+ import { useState, useEffect } from 'react';
3
+ import { Box, Text, useInput, useStdout } from 'ink';
4
4
  export const Search = ({ results, searchTerm, onClose, onSelectMessage }) => {
5
+ const { stdout } = useStdout();
5
6
  const [selectedIndex, setSelectedIndex] = useState(0);
7
+ useEffect(() => {
8
+ stdout?.write('\x1b[2J\x1b[H');
9
+ }, [stdout]);
6
10
  useInput((input, key) => {
7
11
  if (key.escape) {
8
12
  onClose();
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useMemo } from 'react';
3
- import { Text, Box, useInput } from 'ink';
2
+ import { useState, useMemo, useEffect } from 'react';
3
+ import { Text, Box, useInput, useStdout } from 'ink';
4
4
  import { listSessionsWithInfo, loadSession, startNewSession } from '../config/index.js';
5
5
  /**
6
6
  * Format relative time (e.g., "today", "yesterday", "3 days ago")
@@ -39,8 +39,12 @@ function truncateName(name, maxLength = 25) {
39
39
  return name.substring(0, maxLength - 3) + '...';
40
40
  }
41
41
  export const SessionPicker = ({ onSelect, onNewSession, projectPath }) => {
42
+ const { stdout } = useStdout();
42
43
  const sessions = useMemo(() => listSessionsWithInfo(projectPath), [projectPath]);
43
44
  const [selectedIndex, setSelectedIndex] = useState(0);
45
+ useEffect(() => {
46
+ stdout?.write('\x1b[2J\x1b[H');
47
+ }, [stdout]);
44
48
  useInput((input, key) => {
45
49
  // N = New session
46
50
  if (input === 'n' || input === 'N') {
@@ -1,14 +1,18 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Text, Box, useInput } from 'ink';
2
+ import { useState, useEffect } from 'react';
3
+ import { Text, Box, useInput, useStdout } from 'ink';
4
4
  import TextInput from 'ink-text-input';
5
5
  import { listSessions, saveSession, loadSession, deleteSession } from '../config/index.js';
6
6
  export const Sessions = ({ history, onLoad, onClose, onDelete, deleteMode = false, projectPath }) => {
7
+ const { stdout } = useStdout();
7
8
  const [name, setName] = useState('');
8
9
  const [message, setMessage] = useState(deleteMode ? 'Select a session to delete (D or Enter)' : '');
9
10
  const [sessions, setSessions] = useState(listSessions(projectPath));
10
11
  const [selectedIndex, setSelectedIndex] = useState(0);
11
12
  const [confirmDelete, setConfirmDelete] = useState(null);
13
+ useEffect(() => {
14
+ stdout?.write('\x1b[2J\x1b[H');
15
+ }, [stdout]);
12
16
  useInput((input, key) => {
13
17
  // Handle delete confirmation
14
18
  if (confirmDelete) {
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Box, Text, useInput } from 'ink';
2
+ import { useState, useEffect } from 'react';
3
+ import { Box, Text, useInput, useStdout } from 'ink';
4
4
  import { config } from '../config/index.js';
5
5
  import { updateRateLimits } from '../utils/ratelimit.js';
6
6
  const SETTINGS = [
@@ -98,9 +98,14 @@ const SETTINGS = [
98
98
  },
99
99
  ];
100
100
  export const Settings = ({ onClose, notify, hasWriteAccess = false, hasProjectContext = false }) => {
101
+ const { stdout } = useStdout();
101
102
  const [selected, setSelected] = useState(0);
102
103
  const [editing, setEditing] = useState(false);
103
104
  const [editValue, setEditValue] = useState('');
105
+ // Clear screen on mount to show fullscreen view
106
+ useEffect(() => {
107
+ stdout?.write('\x1b[2J\x1b[H');
108
+ }, [stdout]);
104
109
  useInput((input, key) => {
105
110
  if (key.escape) {
106
111
  if (editing) {
@@ -1,7 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Text, Box } from 'ink';
2
+ import { useEffect } from 'react';
3
+ import { Text, Box, useStdout } from 'ink';
3
4
  import { config, getMaskedApiKey, getModelsForCurrentProvider, getCurrentProvider, PROTOCOLS, LANGUAGES } from '../config/index.js';
4
5
  export const Status = () => {
6
+ const { stdout } = useStdout();
5
7
  const model = config.get('model');
6
8
  const protocol = config.get('protocol');
7
9
  const plan = config.get('plan');
@@ -9,5 +11,9 @@ export const Status = () => {
9
11
  const agentMode = config.get('agentMode');
10
12
  const provider = getCurrentProvider();
11
13
  const models = getModelsForCurrentProvider();
14
+ // Clear screen on mount to show fullscreen view
15
+ useEffect(() => {
16
+ stdout?.write('\x1b[2J\x1b[H');
17
+ }, [stdout]);
12
18
  return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "#f02a30", bold: true, children: "Status" }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "Provider:" }), " ", provider.name] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "Model:" }), " ", models[model] || model] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "Protocol:" }), " ", PROTOCOLS[protocol] || protocol] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "Language:" }), " ", LANGUAGES[language] || language] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "Plan:" }), " ", plan.toUpperCase()] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "Agent Mode:" }), " ", agentMode === 'on' ? 'ON' : 'Manual'] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "API Key:" }), " ", getMaskedApiKey()] })] }));
13
19
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "1.0.114",
3
+ "version": "1.0.116",
4
4
  "description": "AI-powered coding assistant built for the terminal. Multiple LLM providers, project-aware context, and a seamless development workflow.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",