codeep 1.0.122 → 1.0.124
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/app.js +8 -8
- package/dist/components/AgentProgress.js +13 -6
- package/dist/components/Help.d.ts +5 -1
- package/dist/components/Help.js +5 -3
- package/dist/config/index.js +80 -11
- package/dist/utils/project.d.ts +35 -0
- package/dist/utils/project.js +139 -0
- package/package.json +1 -1
package/dist/app.js
CHANGED
|
@@ -21,7 +21,7 @@ import { MessageList } from './components/MessageList.js';
|
|
|
21
21
|
import { chat } from './api/index.js';
|
|
22
22
|
import { config, loadApiKey, loadAllApiKeys, PROTOCOLS, LANGUAGES, autoSaveSession, startNewSession, getCurrentSessionId, renameSession, deleteSession, hasReadPermission, hasWritePermission, setProjectPermission, setProvider, getCurrentProvider, getModelsForCurrentProvider, PROVIDERS } from './config/index.js';
|
|
23
23
|
import { getProviderList } from './config/providers.js';
|
|
24
|
-
import { isProjectDirectory, getProjectContext, detectFilePaths, readProjectFile, parseFileChanges, writeProjectFile, deleteProjectFile } from './utils/project.js';
|
|
24
|
+
import { isProjectDirectory, getProjectContext, detectFilePaths, readProjectFile, parseFileChanges, writeProjectFile, deleteProjectFile, getProjectTip } from './utils/project.js';
|
|
25
25
|
import { logStartup, setLogProjectPath } from './utils/logger.js';
|
|
26
26
|
import { searchMessages } from './utils/search.js';
|
|
27
27
|
import { exportMessages, saveExport } from './utils/export.js';
|
|
@@ -1264,14 +1264,14 @@ export const App = () => {
|
|
|
1264
1264
|
if (permanent) {
|
|
1265
1265
|
// Save permission to local .codeep/config.json
|
|
1266
1266
|
setProjectPermission(projectPath, true, writeGranted);
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1267
|
+
}
|
|
1268
|
+
// Show project tip with type and suggested commands
|
|
1269
|
+
const tip = getProjectTip(projectPath);
|
|
1270
|
+
if (tip) {
|
|
1271
|
+
notify(tip, 5000);
|
|
1270
1272
|
}
|
|
1271
1273
|
else {
|
|
1272
|
-
notify(writeGranted
|
|
1273
|
-
? 'Project access granted (read + write, this session)'
|
|
1274
|
-
: 'Project access granted (read-only, this session)');
|
|
1274
|
+
notify(writeGranted ? 'Project access granted (read + write)' : 'Project access granted (read-only)');
|
|
1275
1275
|
}
|
|
1276
1276
|
// Warn user if Agent Mode is ON but write access was not granted
|
|
1277
1277
|
const agentMode = config.get('agentMode');
|
|
@@ -1323,7 +1323,7 @@ export const App = () => {
|
|
|
1323
1323
|
const actionColor = change.action === 'delete' ? 'red' : change.action === 'edit' ? 'yellow' : 'green';
|
|
1324
1324
|
const actionLabel = change.action === 'delete' ? 'DELETE' : change.action === 'edit' ? 'EDIT' : 'CREATE';
|
|
1325
1325
|
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));
|
|
1326
|
-
}), _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 }) })), !isInlineMenu && (_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)) })] })), isInlineMenu && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "#f02a30", children: '─'.repeat(stdout?.columns || 80) }), screen === 'help' && _jsx(Help, {}), screen === 'status' && _jsx(Status, {}), screen === 'settings' && (_jsx(Settings, { onClose: () => setScreen('chat'), notify: notify, hasWriteAccess: hasWriteAccess, hasProjectContext: !!projectContext })), screen === 'sessions' && (_jsx(Sessions, { history: messages, onLoad: handleSessionLoad, onClose: () => setScreen('chat'), projectPath: projectPath })), screen === 'sessions-delete' && (_jsx(Sessions, { history: messages, onLoad: handleSessionLoad, onClose: () => setScreen('chat'), onDelete: (name) => {
|
|
1326
|
+
}), _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 }) })), !isInlineMenu && (_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)) })] })), isInlineMenu && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "#f02a30", children: '─'.repeat(stdout?.columns || 80) }), screen === 'help' && _jsx(Help, { projectPath: projectPath }), screen === 'status' && _jsx(Status, {}), screen === 'settings' && (_jsx(Settings, { onClose: () => setScreen('chat'), notify: notify, hasWriteAccess: hasWriteAccess, hasProjectContext: !!projectContext })), screen === 'sessions' && (_jsx(Sessions, { history: messages, onLoad: handleSessionLoad, onClose: () => setScreen('chat'), projectPath: projectPath })), screen === 'sessions-delete' && (_jsx(Sessions, { history: messages, onLoad: handleSessionLoad, onClose: () => setScreen('chat'), onDelete: (name) => {
|
|
1327
1327
|
notify(`Deleted: ${name}`);
|
|
1328
1328
|
setScreen('chat');
|
|
1329
1329
|
}, deleteMode: true, projectPath: projectPath })), screen === 'logout' && (_jsx(LogoutPicker, { onLogout: (providerId) => {
|
|
@@ -145,11 +145,13 @@ const isSectionBreak = (line, prevLine) => {
|
|
|
145
145
|
}
|
|
146
146
|
return false;
|
|
147
147
|
};
|
|
148
|
-
const MAX_PREVIEW_LINES =
|
|
148
|
+
const MAX_PREVIEW_LINES = 12; // Code preview lines for live streaming
|
|
149
149
|
export const LiveCodeStream = memo(({ actions, isRunning, terminalWidth = 80 }) => {
|
|
150
|
-
// Find the current write/edit action for live preview
|
|
150
|
+
// Find the current write/edit action for live preview (skip read actions)
|
|
151
151
|
const currentAction = actions.length > 0 ? actions[actions.length - 1] : null;
|
|
152
152
|
const isCodeAction = currentAction && (currentAction.type === 'write' || currentAction.type === 'edit');
|
|
153
|
+
// Skip rendering for read actions - no preview needed
|
|
154
|
+
const isReadAction = currentAction && currentAction.type === 'read';
|
|
153
155
|
// ALL HOOKS MUST BE CALLED BEFORE ANY EARLY RETURNS (Rules of Hooks)
|
|
154
156
|
// Calculate statistics from all actions
|
|
155
157
|
const stats = useMemo(() => {
|
|
@@ -205,12 +207,17 @@ export const LiveCodeStream = memo(({ actions, isRunning, terminalWidth = 80 })
|
|
|
205
207
|
? line.slice(0, boxWidth - 13) + '...'
|
|
206
208
|
: line;
|
|
207
209
|
return (_jsxs(Text, { children: [_jsxs(Text, { color: "gray", dimColor: true, children: [String(lineNum).padStart(3), " "] }), _jsx(Text, { color: getCodeColor(line, ext), children: displayLine || ' ' })] }, i));
|
|
208
|
-
})
|
|
210
|
+
})] })] }));
|
|
209
211
|
}
|
|
210
|
-
// RUNNING STATE but not a code action: show simple status
|
|
211
|
-
|
|
212
|
+
// RUNNING STATE but not a code action (and not read): show simple status
|
|
213
|
+
// Skip showing box for read actions - they don't need preview
|
|
214
|
+
if (isRunning && currentAction && !isReadAction) {
|
|
212
215
|
const boxWidth = Math.min(terminalWidth - 4, 76);
|
|
213
|
-
return (
|
|
216
|
+
return (_jsx(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", marginBottom: 1, width: boxWidth, children: _jsxs(Box, { paddingX: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "\u25E6 " }), _jsxs(Text, { color: getActionColor(currentAction.type), children: [getActionLabel(currentAction.type), " "] }), _jsx(Text, { color: "white", children: formatTarget(currentAction.target) })] }) }));
|
|
217
|
+
}
|
|
218
|
+
// For read actions while running, don't show anything
|
|
219
|
+
if (isRunning && isReadAction) {
|
|
220
|
+
return null;
|
|
214
221
|
}
|
|
215
222
|
// FINISHED STATE: Show summary statistics (same height as live preview)
|
|
216
223
|
const boxWidth = Math.min(terminalWidth - 4, 76);
|
package/dist/components/Help.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Text, Box } from 'ink';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { detectProjectFeatures } from '../utils/project.js';
|
|
4
|
+
export const Help = ({ projectPath }) => {
|
|
5
|
+
const features = projectPath ? detectProjectFeatures(projectPath) : null;
|
|
6
|
+
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"] })] })] }), features && (features.hasGit || features.hasPackageJson || features.hasPython || features.hasCargo || features.hasGoMod) && (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsx(Text, { color: "green", bold: true, children: "Suggested for this project:" }), _jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [features.hasGit && (_jsxs(Text, { children: [_jsx(Text, { color: "green", children: "/diff" }), " - Review your uncommitted changes"] })), features.hasGit && (_jsxs(Text, { children: [_jsx(Text, { color: "green", children: "/commit" }), " - AI-generated commit message"] })), features.hasPackageJson && (_jsxs(Text, { children: [_jsx(Text, { color: "green", children: "/agent npm run build" }), " - Build Node.js project"] })), features.hasPython && (_jsxs(Text, { children: [_jsx(Text, { color: "green", children: "/agent pytest" }), " - Run Python tests"] })), features.hasCargo && (_jsxs(Text, { children: [_jsx(Text, { color: "green", children: "/agent cargo build" }), " - Build Rust project"] })), features.hasGoMod && (_jsxs(Text, { children: [_jsx(Text, { color: "green", children: "/agent go build" }), " - Build Go project"] }))] })] })), _jsx(Text, { children: " " }), _jsx(Text, { color: "cyan", children: "Type / to see autocomplete. Docs: github.com/VladoIvankovic/Codeep" })] }));
|
|
5
7
|
};
|
package/dist/config/index.js
CHANGED
|
@@ -48,21 +48,55 @@ function isProjectDirectory(path) {
|
|
|
48
48
|
];
|
|
49
49
|
return projectFiles.some(file => existsSync(join(path, file)));
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Get fallback config directory if standard location is not writable
|
|
53
|
+
* Falls back to .codeep in current working directory
|
|
54
|
+
*/
|
|
55
|
+
function getFallbackConfigDir() {
|
|
56
|
+
const cwdConfig = join(process.cwd(), '.codeep');
|
|
57
|
+
try {
|
|
58
|
+
if (!existsSync(cwdConfig)) {
|
|
59
|
+
mkdirSync(cwdConfig, { recursive: true });
|
|
60
|
+
}
|
|
61
|
+
return cwdConfig;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check if a directory is writable
|
|
69
|
+
*/
|
|
70
|
+
function isWritable(dir) {
|
|
71
|
+
try {
|
|
72
|
+
const testFile = join(dir, '.write-test');
|
|
73
|
+
writeFileSync(testFile, 'test');
|
|
74
|
+
unlinkSync(testFile);
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Create config with fallback logic
|
|
83
|
+
* 1. Try standard Conf location (~/.config/codeep-nodejs on Linux, etc.)
|
|
84
|
+
* 2. If not writable, use .codeep in current working directory
|
|
85
|
+
*/
|
|
86
|
+
function createConfig() {
|
|
87
|
+
const defaults = {
|
|
54
88
|
apiKey: '',
|
|
55
89
|
provider: 'z.ai',
|
|
56
90
|
model: 'glm-4.7',
|
|
57
91
|
agentMode: 'on',
|
|
58
|
-
agentConfirmation: 'dangerous',
|
|
92
|
+
agentConfirmation: 'dangerous',
|
|
59
93
|
agentAutoCommit: false,
|
|
60
94
|
agentAutoCommitBranch: false,
|
|
61
|
-
agentAutoVerify: true,
|
|
95
|
+
agentAutoVerify: true,
|
|
62
96
|
agentMaxFixAttempts: 3,
|
|
63
97
|
agentMaxIterations: 100,
|
|
64
|
-
agentMaxDuration: 20,
|
|
65
|
-
agentApiTimeout: 180000,
|
|
98
|
+
agentMaxDuration: 20,
|
|
99
|
+
agentApiTimeout: 180000,
|
|
66
100
|
protocol: 'openai',
|
|
67
101
|
plan: 'lite',
|
|
68
102
|
language: 'en',
|
|
@@ -71,12 +105,47 @@ export const config = new Conf({
|
|
|
71
105
|
temperature: 0.7,
|
|
72
106
|
maxTokens: 8192,
|
|
73
107
|
apiTimeout: 60000,
|
|
74
|
-
rateLimitApi: 30,
|
|
75
|
-
rateLimitCommands: 100,
|
|
108
|
+
rateLimitApi: 30,
|
|
109
|
+
rateLimitCommands: 100,
|
|
76
110
|
projectPermissions: [],
|
|
77
111
|
providerApiKeys: [],
|
|
78
|
-
}
|
|
79
|
-
|
|
112
|
+
};
|
|
113
|
+
// First try standard location
|
|
114
|
+
try {
|
|
115
|
+
const standardConfig = new Conf({
|
|
116
|
+
projectName: 'codeep',
|
|
117
|
+
defaults,
|
|
118
|
+
});
|
|
119
|
+
// Test if we can write to the config directory
|
|
120
|
+
const configDir = dirname(standardConfig.path);
|
|
121
|
+
if (isWritable(configDir)) {
|
|
122
|
+
return standardConfig;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Standard location failed, try fallback
|
|
127
|
+
}
|
|
128
|
+
// Fallback: use .codeep in current working directory
|
|
129
|
+
const fallbackDir = getFallbackConfigDir();
|
|
130
|
+
if (fallbackDir) {
|
|
131
|
+
try {
|
|
132
|
+
return new Conf({
|
|
133
|
+
projectName: 'codeep',
|
|
134
|
+
cwd: fallbackDir,
|
|
135
|
+
defaults,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// Even fallback failed
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Last resort: use standard config anyway (may fail on write)
|
|
143
|
+
return new Conf({
|
|
144
|
+
projectName: 'codeep',
|
|
145
|
+
defaults,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
export const config = createConfig();
|
|
80
149
|
// Migrate old 'auto' value to 'on'
|
|
81
150
|
if (config.get('agentMode') === 'auto') {
|
|
82
151
|
config.set('agentMode', 'on');
|
package/dist/utils/project.d.ts
CHANGED
|
@@ -84,3 +84,38 @@ export declare function getProjectSummary(dir?: string): {
|
|
|
84
84
|
fileCount: number;
|
|
85
85
|
hasReadme: boolean;
|
|
86
86
|
} | null;
|
|
87
|
+
/**
|
|
88
|
+
* Project feature detection
|
|
89
|
+
*/
|
|
90
|
+
export interface ProjectFeatures {
|
|
91
|
+
hasGit: boolean;
|
|
92
|
+
hasPackageJson: boolean;
|
|
93
|
+
hasTypescript: boolean;
|
|
94
|
+
hasPython: boolean;
|
|
95
|
+
hasDocker: boolean;
|
|
96
|
+
hasTests: boolean;
|
|
97
|
+
hasCargo: boolean;
|
|
98
|
+
hasGoMod: boolean;
|
|
99
|
+
projectType: string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Suggested command based on project features
|
|
103
|
+
*/
|
|
104
|
+
export interface ProjectSuggestion {
|
|
105
|
+
command: string;
|
|
106
|
+
description: string;
|
|
107
|
+
reason: string;
|
|
108
|
+
priority: number;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Detect project features
|
|
112
|
+
*/
|
|
113
|
+
export declare function detectProjectFeatures(dir?: string): ProjectFeatures;
|
|
114
|
+
/**
|
|
115
|
+
* Get smart suggestions based on project type
|
|
116
|
+
*/
|
|
117
|
+
export declare function getProjectSuggestions(dir?: string): ProjectSuggestion[];
|
|
118
|
+
/**
|
|
119
|
+
* Get a brief tip message for the project type
|
|
120
|
+
*/
|
|
121
|
+
export declare function getProjectTip(dir?: string): string | null;
|
package/dist/utils/project.js
CHANGED
|
@@ -414,3 +414,142 @@ export function getProjectSummary(dir = process.cwd()) {
|
|
|
414
414
|
return null;
|
|
415
415
|
}
|
|
416
416
|
}
|
|
417
|
+
/**
|
|
418
|
+
* Detect project features
|
|
419
|
+
*/
|
|
420
|
+
export function detectProjectFeatures(dir = process.cwd()) {
|
|
421
|
+
return {
|
|
422
|
+
hasGit: existsSync(join(dir, '.git')),
|
|
423
|
+
hasPackageJson: existsSync(join(dir, 'package.json')),
|
|
424
|
+
hasTypescript: existsSync(join(dir, 'tsconfig.json')),
|
|
425
|
+
hasPython: existsSync(join(dir, 'requirements.txt')) || existsSync(join(dir, 'setup.py')) || existsSync(join(dir, 'pyproject.toml')),
|
|
426
|
+
hasDocker: existsSync(join(dir, 'Dockerfile')) || existsSync(join(dir, 'docker-compose.yml')),
|
|
427
|
+
hasTests: existsSync(join(dir, 'jest.config.js')) || existsSync(join(dir, 'jest.config.ts')) ||
|
|
428
|
+
existsSync(join(dir, 'pytest.ini')) || existsSync(join(dir, 'test')) || existsSync(join(dir, 'tests')) ||
|
|
429
|
+
existsSync(join(dir, '__tests__')) || existsSync(join(dir, 'spec')),
|
|
430
|
+
hasCargo: existsSync(join(dir, 'Cargo.toml')),
|
|
431
|
+
hasGoMod: existsSync(join(dir, 'go.mod')),
|
|
432
|
+
projectType: getProjectType(dir),
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Get smart suggestions based on project type
|
|
437
|
+
*/
|
|
438
|
+
export function getProjectSuggestions(dir = process.cwd()) {
|
|
439
|
+
const features = detectProjectFeatures(dir);
|
|
440
|
+
const suggestions = [];
|
|
441
|
+
// Git suggestions
|
|
442
|
+
if (features.hasGit) {
|
|
443
|
+
suggestions.push({
|
|
444
|
+
command: '/diff',
|
|
445
|
+
description: 'Review uncommitted changes',
|
|
446
|
+
reason: 'Git repository detected',
|
|
447
|
+
priority: 1,
|
|
448
|
+
});
|
|
449
|
+
suggestions.push({
|
|
450
|
+
command: '/commit',
|
|
451
|
+
description: 'Generate commit message',
|
|
452
|
+
reason: 'Git repository detected',
|
|
453
|
+
priority: 2,
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
// Node.js/TypeScript suggestions
|
|
457
|
+
if (features.hasPackageJson) {
|
|
458
|
+
suggestions.push({
|
|
459
|
+
command: '/agent npm run build',
|
|
460
|
+
description: 'Build the project',
|
|
461
|
+
reason: 'Node.js project detected',
|
|
462
|
+
priority: 3,
|
|
463
|
+
});
|
|
464
|
+
if (features.hasTests) {
|
|
465
|
+
suggestions.push({
|
|
466
|
+
command: '/agent npm test',
|
|
467
|
+
description: 'Run tests',
|
|
468
|
+
reason: 'Test configuration found',
|
|
469
|
+
priority: 4,
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
// Python suggestions
|
|
474
|
+
if (features.hasPython) {
|
|
475
|
+
suggestions.push({
|
|
476
|
+
command: '/agent pip install -r requirements.txt',
|
|
477
|
+
description: 'Install dependencies',
|
|
478
|
+
reason: 'Python project detected',
|
|
479
|
+
priority: 3,
|
|
480
|
+
});
|
|
481
|
+
if (features.hasTests) {
|
|
482
|
+
suggestions.push({
|
|
483
|
+
command: '/agent pytest',
|
|
484
|
+
description: 'Run tests',
|
|
485
|
+
reason: 'Python tests detected',
|
|
486
|
+
priority: 4,
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
// Rust suggestions
|
|
491
|
+
if (features.hasCargo) {
|
|
492
|
+
suggestions.push({
|
|
493
|
+
command: '/agent cargo build',
|
|
494
|
+
description: 'Build the project',
|
|
495
|
+
reason: 'Rust project detected',
|
|
496
|
+
priority: 3,
|
|
497
|
+
});
|
|
498
|
+
suggestions.push({
|
|
499
|
+
command: '/agent cargo test',
|
|
500
|
+
description: 'Run tests',
|
|
501
|
+
reason: 'Rust project detected',
|
|
502
|
+
priority: 4,
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
// Go suggestions
|
|
506
|
+
if (features.hasGoMod) {
|
|
507
|
+
suggestions.push({
|
|
508
|
+
command: '/agent go build',
|
|
509
|
+
description: 'Build the project',
|
|
510
|
+
reason: 'Go project detected',
|
|
511
|
+
priority: 3,
|
|
512
|
+
});
|
|
513
|
+
suggestions.push({
|
|
514
|
+
command: '/agent go test ./...',
|
|
515
|
+
description: 'Run tests',
|
|
516
|
+
reason: 'Go project detected',
|
|
517
|
+
priority: 4,
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
// Docker suggestions
|
|
521
|
+
if (features.hasDocker) {
|
|
522
|
+
suggestions.push({
|
|
523
|
+
command: '/agent docker build',
|
|
524
|
+
description: 'Build Docker image',
|
|
525
|
+
reason: 'Dockerfile detected',
|
|
526
|
+
priority: 5,
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
// Always suggest agent for code tasks
|
|
530
|
+
suggestions.push({
|
|
531
|
+
command: '/agent',
|
|
532
|
+
description: 'Run autonomous agent for any task',
|
|
533
|
+
reason: 'Project access granted',
|
|
534
|
+
priority: 10,
|
|
535
|
+
});
|
|
536
|
+
// Sort by priority
|
|
537
|
+
return suggestions.sort((a, b) => a.priority - b.priority);
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Get a brief tip message for the project type
|
|
541
|
+
*/
|
|
542
|
+
export function getProjectTip(dir = process.cwd()) {
|
|
543
|
+
const features = detectProjectFeatures(dir);
|
|
544
|
+
const tips = [];
|
|
545
|
+
if (features.hasGit) {
|
|
546
|
+
tips.push('/diff, /commit');
|
|
547
|
+
}
|
|
548
|
+
if (features.hasPackageJson || features.hasCargo || features.hasGoMod || features.hasPython) {
|
|
549
|
+
tips.push('/agent for tasks');
|
|
550
|
+
}
|
|
551
|
+
if (tips.length === 0)
|
|
552
|
+
return null;
|
|
553
|
+
const projectName = features.projectType !== 'Unknown' ? features.projectType : 'project';
|
|
554
|
+
return `${projectName} • Try: ${tips.join(' • ')}`;
|
|
555
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeep",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.124",
|
|
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",
|