codeep 1.0.87 → 1.0.89

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 (2) hide show
  1. package/dist/app.js +21 -34
  2. package/package.json +1 -1
package/dist/app.js CHANGED
@@ -1,5 +1,5 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import React, { useState, useEffect, useCallback } from 'react';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect, useCallback } from 'react';
3
3
  import { Box, Text, useApp, useInput, useStdout } from 'ink';
4
4
  import clipboardy from 'clipboardy';
5
5
  import { logger } from './utils/logger.js';
@@ -37,20 +37,21 @@ import { learnFromProject, addCustomRule, getLearningStatus } from './utils/lear
37
37
  import { getAllSkills, findSkill, formatSkillsList, formatSkillHelp, generateSkillPrompt, saveCustomSkill, deleteCustomSkill, parseSkillChain, parseSkillArgs, searchSkills, trackSkillUsage, getSkillStats } from './utils/skills.js';
38
38
  import { AgentProgress, AgentSummary, LiveCodeStream } from './components/AgentProgress.js';
39
39
  import { createActionLog } from './utils/tools.js';
40
- // Modal wrapper component that clears terminal on mount
41
- const ModalScreen = ({ children }) => {
42
- const { stdout } = useStdout();
43
- React.useEffect(() => {
44
- // Full terminal reset - clears screen and scrollback
45
- stdout?.write('\x1Bc');
46
- }, [stdout]);
47
- return _jsx(Box, { flexDirection: "column", children: children });
40
+ // Modal overlay component - renders modal content on top of chat
41
+ const ModalOverlay = ({ children, onClose }) => {
42
+ useInput((input, key) => {
43
+ if (key.escape) {
44
+ onClose();
45
+ }
46
+ });
47
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#f02a30", padding: 1, marginTop: 2, marginBottom: 2, children: [children, _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "cyan", children: "Press Escape to close" }) })] }));
48
48
  };
49
49
  export const App = () => {
50
50
  const { exit } = useApp();
51
51
  const { stdout } = useStdout();
52
52
  // Start with 'chat' screen, will switch to login if needed after loading API key
53
53
  const [screen, setScreen] = useState('chat');
54
+ const [modalScreen, setModalScreen] = useState(null);
54
55
  const [messages, setMessages] = useState([]);
55
56
  const [inputHistory, setInputHistory] = useState([]);
56
57
  const [isLoading, setIsLoading] = useState(false);
@@ -61,7 +62,6 @@ export const App = () => {
61
62
  const [sessionId, setSessionId] = useState(getCurrentSessionId());
62
63
  const [showIntro, setShowIntro] = useState(true);
63
64
  const [clearInputTrigger, setClearInputTrigger] = useState(0);
64
- const [screenRenderKey, setScreenRenderKey] = useState(0);
65
65
  // Project context
66
66
  const [projectPath] = useState(process.cwd());
67
67
  // Log application startup and set project path for logging
@@ -173,24 +173,14 @@ export const App = () => {
173
173
  return () => clearTimeout(timer);
174
174
  }
175
175
  }, [notification, notificationDuration]);
176
- // Clear input when opening command modals and increment render key when returning to chat
176
+ // Clear input when opening modals
177
177
  useEffect(() => {
178
- const commandModals = ['help', 'status', 'sessions', 'sessions-delete', 'model', 'protocol', 'language', 'settings', 'provider', 'search', 'export', 'logout'];
179
- if (commandModals.includes(screen)) {
178
+ if (modalScreen !== null) {
180
179
  setClearInputTrigger(prev => prev + 1);
181
180
  }
182
- else if (screen === 'chat') {
183
- // Increment render key to force re-render when returning to chat
184
- setScreenRenderKey(prev => prev + 1);
185
- }
186
- }, [screen]);
181
+ }, [modalScreen]);
187
182
  // Handle keyboard shortcuts
188
183
  useInput((input, key) => {
189
- // ? to open help (only from chat screen)
190
- if (input === '?' && screen === 'chat' && !isLoading) {
191
- setScreen('help');
192
- return;
193
- }
194
184
  // Ctrl+L to clear chat (F5 doesn't work reliably in all terminals)
195
185
  if (key.ctrl && input === 'l') {
196
186
  if (!isLoading && screen === 'chat') {
@@ -548,10 +538,10 @@ export const App = () => {
548
538
  exit();
549
539
  break;
550
540
  case '/help':
551
- setScreen('help');
541
+ setModalScreen('help');
552
542
  break;
553
543
  case '/status':
554
- setScreen('status');
544
+ setModalScreen('status');
555
545
  break;
556
546
  case '/version': {
557
547
  const version = getCurrentVersion();
@@ -639,7 +629,7 @@ export const App = () => {
639
629
  }
640
630
  break;
641
631
  case '/settings':
642
- setScreen('settings');
632
+ setModalScreen('settings');
643
633
  break;
644
634
  case '/grant': {
645
635
  // Always open permission dialog to allow users to manage permissions
@@ -1331,10 +1321,10 @@ export const App = () => {
1331
1321
  return (_jsx(ProjectPermission, { projectPath: projectPath, onComplete: handlePermissionComplete }));
1332
1322
  }
1333
1323
  if (screen === 'help') {
1334
- return _jsxs(ModalScreen, { children: [_jsx(Help, {}), _jsx(Text, { children: "Press Escape to close" })] });
1324
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Help, {}), _jsx(Text, { children: "Press Escape to close" })] }, "help-screen"));
1335
1325
  }
1336
1326
  if (screen === 'status') {
1337
- return _jsxs(ModalScreen, { children: [_jsx(Status, {}), _jsx(Text, { children: "Press Escape to close" })] });
1327
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Status, {}), _jsx(Text, { children: "Press Escape to close" })] }, "status-screen"));
1338
1328
  }
1339
1329
  if (screen === 'session-picker') {
1340
1330
  return (_jsx(SessionPicker, { projectPath: projectPath, onSelect: (loadedMessages, sessionName) => {
@@ -1416,14 +1406,11 @@ export const App = () => {
1416
1406
  // If we got here, we're in an unknown state - default to chat
1417
1407
  return null;
1418
1408
  }
1419
- // Wrap chat in ModalScreen when returning from modal to clear terminal
1420
- const ChatContent = (_jsxs(_Fragment, { children: [messages.length === 0 && !isLoading && _jsx(Logo, {}), messages.length === 0 && !isLoading && (_jsx(Box, { justifyContent: "center", children: _jsxs(Text, { children: ["Connected to ", _jsx(Text, { color: "#f02a30", children: config.get('model') }), ". Type ", _jsx(Text, { color: "#f02a30", children: "/help" }), " for commands."] }) })), _jsx(MessageList, { messages: messages, streamingContent: streamingContent, scrollOffset: 0, terminalHeight: stdout.rows || 24 }, sessionId), isLoading && !isAgentRunning && _jsx(Loading, { isStreaming: !!streamingContent }), isAgentRunning && (_jsx(LiveCodeStream, { actions: agentActions, isRunning: true, terminalWidth: stdout?.columns || 80 })), isAgentRunning && (_jsx(AgentProgress, { isRunning: true, iteration: agentIteration, maxIterations: 50, actions: agentActions, currentThinking: agentThinking, dryRun: agentDryRun })), !isAgentRunning && agentResult && (_jsx(AgentSummary, { success: agentResult.success, iterations: agentResult.iterations, actions: agentActions, error: agentResult.error, aborted: agentResult.aborted })), pendingFileChanges.length > 0 && !isLoading && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#f02a30", padding: 1, marginY: 1, children: [_jsxs(Text, { color: "#f02a30", bold: true, children: ["\u2713 Detected ", pendingFileChanges.length, " file change(s):"] }), pendingFileChanges.map((change, i) => {
1409
+ return (_jsxs(Box, { flexDirection: "column", children: [messages.length === 0 && !isLoading && _jsx(Logo, {}), messages.length === 0 && !isLoading && (_jsx(Box, { justifyContent: "center", children: _jsxs(Text, { children: ["Connected to ", _jsx(Text, { color: "#f02a30", children: config.get('model') }), ". Type ", _jsx(Text, { color: "#f02a30", children: "/help" }), " for commands."] }) })), _jsx(MessageList, { messages: messages, streamingContent: streamingContent, scrollOffset: 0, terminalHeight: stdout.rows || 24 }, sessionId), isLoading && !isAgentRunning && _jsx(Loading, { isStreaming: !!streamingContent }), isAgentRunning && (_jsx(LiveCodeStream, { actions: agentActions, isRunning: true, terminalWidth: stdout?.columns || 80 })), isAgentRunning && (_jsx(AgentProgress, { isRunning: true, iteration: agentIteration, maxIterations: 50, actions: agentActions, currentThinking: agentThinking, dryRun: agentDryRun })), !isAgentRunning && agentResult && (_jsx(AgentSummary, { success: agentResult.success, iterations: agentResult.iterations, actions: agentActions, error: agentResult.error, aborted: agentResult.aborted })), pendingFileChanges.length > 0 && !isLoading && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#f02a30", padding: 1, marginY: 1, children: [_jsxs(Text, { color: "#f02a30", bold: true, children: ["\u2713 Detected ", pendingFileChanges.length, " file change(s):"] }), pendingFileChanges.map((change, i) => {
1421
1410
  const actionColor = change.action === 'delete' ? 'red' : change.action === 'edit' ? 'yellow' : 'green';
1422
1411
  const actionLabel = change.action === 'delete' ? 'DELETE' : change.action === 'edit' ? 'EDIT' : 'CREATE';
1423
1412
  return (_jsxs(Text, { children: ["\u2022 ", _jsxs(Text, { color: actionColor, children: ["[", actionLabel, "]"] }), " ", change.path, change.action !== 'delete' && change.content.includes('\n') && ` (${change.content.split('\n').length} lines)`] }, i));
1424
- }), _jsx(Text, { children: " " }), _jsxs(Text, { children: ["Apply changes? ", _jsx(Text, { color: "#f02a30", bold: true, children: "[Y/n]" })] }), _jsx(Text, { color: "cyan", children: "Press Y to apply, N or Esc to reject" })] })), notification && (_jsx(Box, { justifyContent: "center", children: _jsx(Text, { color: "cyan", children: notification }) })), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "#f02a30", children: '─'.repeat(Math.max(20, stdout?.columns || 80)) }), _jsx(Box, { paddingX: 1, children: _jsx(ChatInput, { onSubmit: handleSubmit, disabled: isLoading || isAgentRunning || pendingFileChanges.length > 0, history: inputHistory, clearTrigger: clearInputTrigger }) }), _jsx(Text, { color: "#f02a30", children: '─'.repeat(Math.max(20, stdout?.columns || 80)) })] }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", bold: true, children: "Ctrl+V" }), _jsx(Text, { children: " Paste " }), _jsx(Text, { color: "#f02a30", bold: true, children: "Ctrl+L" }), _jsx(Text, { children: " Clear " }), _jsx(Text, { color: "#f02a30", bold: true, children: "Esc" }), _jsx(Text, { children: " Cancel " }), _jsx(Text, { color: "#f02a30", bold: true, children: "\u2191\u2193" }), _jsx(Text, { children: " History " }), _jsx(Text, { color: "#f02a30", bold: true, children: "/help" }), _jsx(Text, { children: " Commands" })] }) }), _jsx(Box, { children: config.get('agentMode') === 'on' ? (hasWriteAccess && projectContext ? (_jsx(Text, { color: "green", children: "Agent: ON \u2713" })) : (_jsx(Text, { color: "yellow", children: "Agent: ON (no permission - use /grant)" }))) : (_jsx(Text, { color: "cyan", children: "Agent: Manual (use /agent)" })) })] })] }));
1425
- // Use ModalScreen wrapper when returning from modal (screenRenderKey changes)
1426
- return screenRenderKey > 0 ? (_jsx(ModalScreen, { children: ChatContent }, screenRenderKey)) : (_jsx(Box, { flexDirection: "column", children: ChatContent }));
1413
+ }), _jsx(Text, { children: " " }), _jsxs(Text, { children: ["Apply changes? ", _jsx(Text, { color: "#f02a30", bold: true, children: "[Y/n]" })] }), _jsx(Text, { color: "cyan", children: "Press Y to apply, N or Esc to reject" })] })), notification && (_jsx(Box, { justifyContent: "center", children: _jsx(Text, { color: "cyan", children: notification }) })), modalScreen === 'help' && (_jsx(ModalOverlay, { onClose: () => setModalScreen(null), children: _jsx(Help, {}) })), modalScreen === 'status' && (_jsx(ModalOverlay, { onClose: () => setModalScreen(null), children: _jsx(Status, {}) })), modalScreen === 'settings' && (_jsx(ModalOverlay, { onClose: () => setModalScreen(null), children: _jsx(Settings, { onClose: () => setModalScreen(null), notify: notify, hasWriteAccess: hasWriteAccess, hasProjectContext: !!projectContext }) })), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "#f02a30", children: '─'.repeat(Math.max(20, stdout?.columns || 80)) }), _jsx(Box, { paddingX: 1, children: _jsx(ChatInput, { onSubmit: handleSubmit, disabled: isLoading || isAgentRunning || pendingFileChanges.length > 0, history: inputHistory, clearTrigger: clearInputTrigger }) }), _jsx(Text, { color: "#f02a30", children: '─'.repeat(Math.max(20, stdout?.columns || 80)) })] }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", bold: true, children: "Ctrl+V" }), _jsx(Text, { children: " Paste " }), _jsx(Text, { color: "#f02a30", bold: true, children: "Ctrl+L" }), _jsx(Text, { children: " Clear " }), _jsx(Text, { color: "#f02a30", bold: true, children: "Esc" }), _jsx(Text, { children: " Cancel " }), _jsx(Text, { color: "#f02a30", bold: true, children: "\u2191\u2193" }), _jsx(Text, { children: " History " }), _jsx(Text, { color: "#f02a30", bold: true, children: "/help" }), _jsx(Text, { children: " Commands" })] }) }), _jsx(Box, { children: config.get('agentMode') === 'on' ? (hasWriteAccess && projectContext ? (_jsx(Text, { color: "green", children: "Agent: ON \u2713" })) : (_jsx(Text, { color: "yellow", children: "Agent: ON (no permission - use /grant)" }))) : (_jsx(Text, { color: "cyan", children: "Agent: Manual (use /agent)" })) })] })] }, "chat-screen"));
1427
1414
  };
1428
1415
  // Model selection component
1429
1416
  const ModelSelect = ({ onClose, notify }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "1.0.87",
3
+ "version": "1.0.89",
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",