codeep 1.0.0

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 (103) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +576 -0
  3. package/dist/api/index.d.ts +8 -0
  4. package/dist/api/index.js +421 -0
  5. package/dist/app.d.ts +2 -0
  6. package/dist/app.js +1406 -0
  7. package/dist/components/AgentProgress.d.ts +33 -0
  8. package/dist/components/AgentProgress.js +97 -0
  9. package/dist/components/Export.d.ts +8 -0
  10. package/dist/components/Export.js +27 -0
  11. package/dist/components/Help.d.ts +2 -0
  12. package/dist/components/Help.js +3 -0
  13. package/dist/components/Input.d.ts +9 -0
  14. package/dist/components/Input.js +89 -0
  15. package/dist/components/Loading.d.ts +9 -0
  16. package/dist/components/Loading.js +31 -0
  17. package/dist/components/Login.d.ts +7 -0
  18. package/dist/components/Login.js +77 -0
  19. package/dist/components/Logo.d.ts +8 -0
  20. package/dist/components/Logo.js +89 -0
  21. package/dist/components/LogoutPicker.d.ts +8 -0
  22. package/dist/components/LogoutPicker.js +61 -0
  23. package/dist/components/Message.d.ts +10 -0
  24. package/dist/components/Message.js +234 -0
  25. package/dist/components/MessageList.d.ts +10 -0
  26. package/dist/components/MessageList.js +8 -0
  27. package/dist/components/ProjectPermission.d.ts +7 -0
  28. package/dist/components/ProjectPermission.js +52 -0
  29. package/dist/components/Search.d.ts +10 -0
  30. package/dist/components/Search.js +30 -0
  31. package/dist/components/SessionPicker.d.ts +9 -0
  32. package/dist/components/SessionPicker.js +88 -0
  33. package/dist/components/Sessions.d.ts +12 -0
  34. package/dist/components/Sessions.js +102 -0
  35. package/dist/components/Settings.d.ts +7 -0
  36. package/dist/components/Settings.js +162 -0
  37. package/dist/components/Status.d.ts +2 -0
  38. package/dist/components/Status.js +12 -0
  39. package/dist/config/config.test.d.ts +1 -0
  40. package/dist/config/config.test.js +157 -0
  41. package/dist/config/index.d.ts +121 -0
  42. package/dist/config/index.js +555 -0
  43. package/dist/config/providers.d.ts +43 -0
  44. package/dist/config/providers.js +82 -0
  45. package/dist/config/providers.test.d.ts +1 -0
  46. package/dist/config/providers.test.js +132 -0
  47. package/dist/index.d.ts +2 -0
  48. package/dist/index.js +38 -0
  49. package/dist/utils/agent.d.ts +37 -0
  50. package/dist/utils/agent.js +627 -0
  51. package/dist/utils/codeReview.d.ts +36 -0
  52. package/dist/utils/codeReview.js +390 -0
  53. package/dist/utils/context.d.ts +49 -0
  54. package/dist/utils/context.js +216 -0
  55. package/dist/utils/diffPreview.d.ts +57 -0
  56. package/dist/utils/diffPreview.js +335 -0
  57. package/dist/utils/export.d.ts +19 -0
  58. package/dist/utils/export.js +94 -0
  59. package/dist/utils/git.d.ts +85 -0
  60. package/dist/utils/git.js +399 -0
  61. package/dist/utils/git.test.d.ts +1 -0
  62. package/dist/utils/git.test.js +193 -0
  63. package/dist/utils/history.d.ts +93 -0
  64. package/dist/utils/history.js +348 -0
  65. package/dist/utils/interactive.d.ts +34 -0
  66. package/dist/utils/interactive.js +206 -0
  67. package/dist/utils/keychain.d.ts +17 -0
  68. package/dist/utils/keychain.js +160 -0
  69. package/dist/utils/learning.d.ts +89 -0
  70. package/dist/utils/learning.js +330 -0
  71. package/dist/utils/logger.d.ts +33 -0
  72. package/dist/utils/logger.js +130 -0
  73. package/dist/utils/project.d.ts +86 -0
  74. package/dist/utils/project.js +415 -0
  75. package/dist/utils/project.test.d.ts +1 -0
  76. package/dist/utils/project.test.js +212 -0
  77. package/dist/utils/ratelimit.d.ts +26 -0
  78. package/dist/utils/ratelimit.js +132 -0
  79. package/dist/utils/ratelimit.test.d.ts +1 -0
  80. package/dist/utils/ratelimit.test.js +131 -0
  81. package/dist/utils/retry.d.ts +28 -0
  82. package/dist/utils/retry.js +109 -0
  83. package/dist/utils/retry.test.d.ts +1 -0
  84. package/dist/utils/retry.test.js +163 -0
  85. package/dist/utils/search.d.ts +11 -0
  86. package/dist/utils/search.js +29 -0
  87. package/dist/utils/shell.d.ts +45 -0
  88. package/dist/utils/shell.js +242 -0
  89. package/dist/utils/skills.d.ts +144 -0
  90. package/dist/utils/skills.js +1137 -0
  91. package/dist/utils/smartContext.d.ts +29 -0
  92. package/dist/utils/smartContext.js +441 -0
  93. package/dist/utils/tools.d.ts +224 -0
  94. package/dist/utils/tools.js +731 -0
  95. package/dist/utils/update.d.ts +22 -0
  96. package/dist/utils/update.js +128 -0
  97. package/dist/utils/validation.d.ts +28 -0
  98. package/dist/utils/validation.js +141 -0
  99. package/dist/utils/validation.test.d.ts +1 -0
  100. package/dist/utils/validation.test.js +164 -0
  101. package/dist/utils/verify.d.ts +78 -0
  102. package/dist/utils/verify.js +464 -0
  103. package/package.json +68 -0
@@ -0,0 +1,162 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Box, Text, useInput } from 'ink';
4
+ import { config } from '../config/index';
5
+ import { updateRateLimits } from '../utils/ratelimit';
6
+ const SETTINGS = [
7
+ {
8
+ key: 'temperature',
9
+ label: 'Temperature',
10
+ value: () => config.get('temperature'),
11
+ type: 'number',
12
+ min: 0,
13
+ max: 2,
14
+ step: 0.1,
15
+ },
16
+ {
17
+ key: 'maxTokens',
18
+ label: 'Max Tokens',
19
+ value: () => config.get('maxTokens'),
20
+ type: 'number',
21
+ min: 256,
22
+ max: 32768,
23
+ step: 256,
24
+ },
25
+ {
26
+ key: 'apiTimeout',
27
+ label: 'API Timeout (ms)',
28
+ value: () => config.get('apiTimeout'),
29
+ type: 'number',
30
+ min: 5000,
31
+ max: 120000,
32
+ step: 5000,
33
+ },
34
+ {
35
+ key: 'rateLimitApi',
36
+ label: 'API Rate Limit (/min)',
37
+ value: () => config.get('rateLimitApi'),
38
+ type: 'number',
39
+ min: 1,
40
+ max: 300,
41
+ step: 5,
42
+ },
43
+ {
44
+ key: 'rateLimitCommands',
45
+ label: 'Command Rate Limit (/min)',
46
+ value: () => config.get('rateLimitCommands'),
47
+ type: 'number',
48
+ min: 10,
49
+ max: 1000,
50
+ step: 10,
51
+ },
52
+ {
53
+ key: 'autoSave',
54
+ label: 'Auto Save Sessions',
55
+ value: () => config.get('autoSave') ? 'On' : 'Off',
56
+ type: 'select',
57
+ options: [
58
+ { value: true, label: 'On' },
59
+ { value: false, label: 'Off' },
60
+ ],
61
+ },
62
+ {
63
+ key: 'agentMode',
64
+ label: 'Agent Mode',
65
+ value: () => config.get('agentMode') === 'auto' ? 'Auto' : 'Manual',
66
+ type: 'select',
67
+ options: [
68
+ { value: 'auto', label: 'Auto' },
69
+ { value: 'manual', label: 'Manual' },
70
+ ],
71
+ },
72
+ ];
73
+ export const Settings = ({ onClose, notify }) => {
74
+ const [selected, setSelected] = useState(0);
75
+ const [editing, setEditing] = useState(false);
76
+ const [editValue, setEditValue] = useState('');
77
+ useInput((input, key) => {
78
+ if (key.escape) {
79
+ if (editing) {
80
+ setEditing(false);
81
+ setEditValue('');
82
+ }
83
+ else {
84
+ onClose();
85
+ }
86
+ return;
87
+ }
88
+ if (editing) {
89
+ // Handle editing mode
90
+ if (key.return) {
91
+ const setting = SETTINGS[selected];
92
+ if (setting.type === 'number') {
93
+ const num = parseFloat(editValue);
94
+ if (!isNaN(num)) {
95
+ const clamped = Math.max(setting.min || 0, Math.min(setting.max || Infinity, num));
96
+ config.set(setting.key, clamped);
97
+ // Update rate limiters if changed
98
+ if (setting.key === 'rateLimitApi' || setting.key === 'rateLimitCommands') {
99
+ updateRateLimits();
100
+ }
101
+ notify(`${setting.label}: ${clamped}`);
102
+ }
103
+ }
104
+ setEditing(false);
105
+ setEditValue('');
106
+ }
107
+ else if (key.backspace || key.delete) {
108
+ setEditValue(v => v.slice(0, -1));
109
+ }
110
+ else if (/^[0-9.]$/.test(input)) {
111
+ setEditValue(v => v + input);
112
+ }
113
+ return;
114
+ }
115
+ // Navigation mode
116
+ if (key.upArrow) {
117
+ setSelected(s => Math.max(0, s - 1));
118
+ }
119
+ else if (key.downArrow) {
120
+ setSelected(s => Math.min(SETTINGS.length - 1, s + 1));
121
+ }
122
+ else if (key.leftArrow || key.rightArrow) {
123
+ // Adjust value with arrows
124
+ const setting = SETTINGS[selected];
125
+ if (setting.type === 'number') {
126
+ const current = setting.value();
127
+ const step = setting.step || 1;
128
+ const delta = key.leftArrow ? -step : step;
129
+ const newValue = Math.max(setting.min || 0, Math.min(setting.max || Infinity, current + delta));
130
+ config.set(setting.key, newValue);
131
+ // Update rate limiters if changed
132
+ if (setting.key === 'rateLimitApi' || setting.key === 'rateLimitCommands') {
133
+ updateRateLimits();
134
+ }
135
+ }
136
+ else if (setting.type === 'select' && setting.options) {
137
+ const current = config.get(setting.key);
138
+ const currentIdx = setting.options.findIndex(o => o.value === current);
139
+ const newIdx = key.leftArrow
140
+ ? Math.max(0, currentIdx - 1)
141
+ : Math.min(setting.options.length - 1, currentIdx + 1);
142
+ config.set(setting.key, setting.options[newIdx].value);
143
+ }
144
+ }
145
+ else if (key.return) {
146
+ const setting = SETTINGS[selected];
147
+ if (setting.type === 'number') {
148
+ setEditing(true);
149
+ setEditValue(String(setting.value()));
150
+ }
151
+ else if (setting.type === 'select' && setting.options) {
152
+ // Toggle select options
153
+ const current = config.get(setting.key);
154
+ const currentIdx = setting.options.findIndex(o => o.value === current);
155
+ const newIdx = (currentIdx + 1) % setting.options.length;
156
+ config.set(setting.key, setting.options[newIdx].value);
157
+ notify(`${setting.label}: ${setting.options[newIdx].label}`);
158
+ }
159
+ }
160
+ });
161
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#f02a30", padding: 1, children: [_jsx(Text, { color: "#f02a30", bold: true, children: "Settings" }), _jsx(Text, { children: " " }), SETTINGS.map((setting, i) => (_jsx(Box, { children: _jsxs(Text, { children: [i === selected ? _jsx(Text, { color: "#f02a30", children: "\u25B8 " }) : ' ', _jsxs(Text, { color: i === selected ? '#f02a30' : undefined, children: [setting.label, ":"] }), _jsx(Text, { children: " " }), editing && i === selected ? (_jsx(Text, { color: "cyan", inverse: true, children: editValue || ' ' })) : (_jsx(Text, { color: "green", children: setting.value() })), i === selected && setting.type === 'number' && !editing && (_jsx(Text, { children: " (\u2190/\u2192 adjust, Enter to type)" })), i === selected && setting.type === 'select' && (_jsx(Text, { children: " (\u2190/\u2192 or Enter to toggle)" }))] }) }, setting.key))), _jsx(Text, { children: " " }), _jsx(Text, { children: "\u2191/\u2193 Navigate | \u2190/\u2192 Adjust | Enter Edit | Esc Close" })] }));
162
+ };
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const Status: React.FC;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Text, Box } from 'ink';
3
+ import { config, getMaskedApiKey, getModelsForCurrentProvider, getCurrentProvider, PROTOCOLS, LANGUAGES } from '../config/index';
4
+ export const Status = () => {
5
+ const model = config.get('model');
6
+ const protocol = config.get('protocol');
7
+ const plan = config.get('plan');
8
+ const language = config.get('language');
9
+ const provider = getCurrentProvider();
10
+ const models = getModelsForCurrentProvider();
11
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#f02a30", padding: 1, 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: "API Key:" }), " ", getMaskedApiKey()] })] }));
12
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,157 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { mkdirSync, rmSync, writeFileSync, existsSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { tmpdir } from 'os';
5
+ // We need to test the config functions
6
+ // Since config uses Conf which has side effects, we'll test the utility functions
7
+ describe('config utilities', () => {
8
+ const TEST_DIR = join(tmpdir(), 'codeep-config-test-' + Date.now());
9
+ const SESSIONS_DIR = join(TEST_DIR, '.codeep', 'sessions');
10
+ beforeEach(() => {
11
+ mkdirSync(SESSIONS_DIR, { recursive: true });
12
+ });
13
+ afterEach(() => {
14
+ try {
15
+ rmSync(TEST_DIR, { recursive: true, force: true });
16
+ }
17
+ catch { }
18
+ });
19
+ describe('session file operations', () => {
20
+ it('should create sessions directory structure', () => {
21
+ expect(existsSync(SESSIONS_DIR)).toBe(true);
22
+ });
23
+ it('should handle session JSON files', () => {
24
+ const sessionId = 'test-session';
25
+ const sessionFile = join(SESSIONS_DIR, `${sessionId}.json`);
26
+ const sessionData = {
27
+ name: sessionId,
28
+ history: [
29
+ { role: 'user', content: 'Hello' },
30
+ { role: 'assistant', content: 'Hi there!' },
31
+ ],
32
+ createdAt: new Date().toISOString(),
33
+ };
34
+ writeFileSync(sessionFile, JSON.stringify(sessionData, null, 2));
35
+ expect(existsSync(sessionFile)).toBe(true);
36
+ });
37
+ });
38
+ describe('language codes', () => {
39
+ const LANGUAGES = {
40
+ 'auto': 'Auto-detect',
41
+ 'en': 'English',
42
+ 'zh': 'Chinese (中文)',
43
+ 'es': 'Spanish (Español)',
44
+ 'hi': 'Hindi (हिन्दी)',
45
+ 'ar': 'Arabic (العربية)',
46
+ 'pt': 'Portuguese (Português)',
47
+ 'fr': 'French (Français)',
48
+ 'de': 'German (Deutsch)',
49
+ 'ja': 'Japanese (日本語)',
50
+ 'ru': 'Russian (Русский)',
51
+ 'hr': 'Croatian (Hrvatski)',
52
+ };
53
+ it('should have all supported languages', () => {
54
+ expect(Object.keys(LANGUAGES)).toContain('auto');
55
+ expect(Object.keys(LANGUAGES)).toContain('en');
56
+ expect(Object.keys(LANGUAGES)).toContain('hr');
57
+ });
58
+ it('should have display names for all languages', () => {
59
+ for (const [code, name] of Object.entries(LANGUAGES)) {
60
+ expect(typeof name).toBe('string');
61
+ expect(name.length).toBeGreaterThan(0);
62
+ }
63
+ });
64
+ });
65
+ describe('protocols', () => {
66
+ const PROTOCOLS = {
67
+ 'openai': 'OpenAI Compatible',
68
+ 'anthropic': 'Anthropic Protocol',
69
+ };
70
+ it('should support openai protocol', () => {
71
+ expect(PROTOCOLS['openai']).toBe('OpenAI Compatible');
72
+ });
73
+ it('should support anthropic protocol', () => {
74
+ expect(PROTOCOLS['anthropic']).toBe('Anthropic Protocol');
75
+ });
76
+ });
77
+ describe('config schema validation', () => {
78
+ it('should have valid default values', () => {
79
+ const defaults = {
80
+ apiKey: '',
81
+ provider: 'z.ai',
82
+ model: 'glm-4.7',
83
+ protocol: 'openai',
84
+ plan: 'lite',
85
+ language: 'en',
86
+ autoSave: true,
87
+ currentSessionId: '',
88
+ temperature: 0.7,
89
+ maxTokens: 4096,
90
+ apiTimeout: 30000,
91
+ rateLimitApi: 30,
92
+ rateLimitCommands: 100,
93
+ projectPermissions: [],
94
+ providerApiKeys: [],
95
+ };
96
+ // Validate types
97
+ expect(typeof defaults.apiKey).toBe('string');
98
+ expect(typeof defaults.provider).toBe('string');
99
+ expect(typeof defaults.model).toBe('string');
100
+ expect(['openai', 'anthropic']).toContain(defaults.protocol);
101
+ expect(['lite', 'pro', 'max']).toContain(defaults.plan);
102
+ expect(typeof defaults.autoSave).toBe('boolean');
103
+ expect(typeof defaults.temperature).toBe('number');
104
+ expect(defaults.temperature).toBeGreaterThanOrEqual(0);
105
+ expect(defaults.temperature).toBeLessThanOrEqual(2);
106
+ expect(typeof defaults.maxTokens).toBe('number');
107
+ expect(defaults.maxTokens).toBeGreaterThan(0);
108
+ expect(typeof defaults.apiTimeout).toBe('number');
109
+ expect(defaults.apiTimeout).toBeGreaterThan(0);
110
+ expect(typeof defaults.rateLimitApi).toBe('number');
111
+ expect(typeof defaults.rateLimitCommands).toBe('number');
112
+ expect(Array.isArray(defaults.projectPermissions)).toBe(true);
113
+ expect(Array.isArray(defaults.providerApiKeys)).toBe(true);
114
+ });
115
+ });
116
+ describe('project permissions structure', () => {
117
+ it('should validate permission structure', () => {
118
+ const permission = {
119
+ path: '/Users/test/project',
120
+ readPermission: true,
121
+ writePermission: false,
122
+ grantedAt: new Date().toISOString(),
123
+ };
124
+ expect(typeof permission.path).toBe('string');
125
+ expect(typeof permission.readPermission).toBe('boolean');
126
+ expect(typeof permission.writePermission).toBe('boolean');
127
+ expect(typeof permission.grantedAt).toBe('string');
128
+ // Validate ISO date string
129
+ expect(() => new Date(permission.grantedAt)).not.toThrow();
130
+ });
131
+ });
132
+ describe('provider API keys structure', () => {
133
+ it('should validate API key structure', () => {
134
+ const apiKey = {
135
+ providerId: 'z.ai',
136
+ apiKey: 'test-api-key-123',
137
+ };
138
+ expect(typeof apiKey.providerId).toBe('string');
139
+ expect(typeof apiKey.apiKey).toBe('string');
140
+ expect(apiKey.providerId.length).toBeGreaterThan(0);
141
+ expect(apiKey.apiKey.length).toBeGreaterThan(0);
142
+ });
143
+ });
144
+ describe('message structure', () => {
145
+ it('should validate message structure', () => {
146
+ const userMessage = { role: 'user', content: 'Hello' };
147
+ const assistantMessage = { role: 'assistant', content: 'Hi!' };
148
+ const systemMessage = { role: 'system', content: 'You are a helpful assistant' };
149
+ expect(['user', 'assistant', 'system']).toContain(userMessage.role);
150
+ expect(['user', 'assistant', 'system']).toContain(assistantMessage.role);
151
+ expect(['user', 'assistant', 'system']).toContain(systemMessage.role);
152
+ expect(typeof userMessage.content).toBe('string');
153
+ expect(typeof assistantMessage.content).toBe('string');
154
+ expect(typeof systemMessage.content).toBe('string');
155
+ });
156
+ });
157
+ });
@@ -0,0 +1,121 @@
1
+ import Conf from 'conf';
2
+ export interface Message {
3
+ role: 'user' | 'assistant' | 'system';
4
+ content: string;
5
+ }
6
+ type LanguageCode = 'auto' | 'en' | 'zh' | 'es' | 'hi' | 'ar' | 'pt' | 'fr' | 'de' | 'ja' | 'ru' | 'hr';
7
+ interface ProjectPermission {
8
+ path: string;
9
+ readPermission: boolean;
10
+ writePermission: boolean;
11
+ grantedAt: string;
12
+ }
13
+ interface ProviderApiKey {
14
+ providerId: string;
15
+ apiKey: string;
16
+ }
17
+ type AgentMode = 'auto' | 'manual';
18
+ interface ConfigSchema {
19
+ apiKey: string;
20
+ provider: string;
21
+ model: string;
22
+ protocol: 'openai' | 'anthropic';
23
+ plan: 'lite' | 'pro' | 'max';
24
+ language: LanguageCode;
25
+ autoSave: boolean;
26
+ currentSessionId: string;
27
+ temperature: number;
28
+ maxTokens: number;
29
+ apiTimeout: number;
30
+ rateLimitApi: number;
31
+ rateLimitCommands: number;
32
+ agentMode: AgentMode;
33
+ agentConfirmation: 'always' | 'dangerous' | 'never';
34
+ agentAutoCommit: boolean;
35
+ agentAutoCommitBranch: boolean;
36
+ agentAutoVerify: boolean;
37
+ agentMaxFixAttempts: number;
38
+ projectPermissions: ProjectPermission[];
39
+ providerApiKeys: ProviderApiKey[];
40
+ }
41
+ export type { AgentMode };
42
+ export type { LanguageCode };
43
+ export declare const config: Conf<ConfigSchema>;
44
+ export declare const LANGUAGES: Record<string, string>;
45
+ export declare const PROTOCOLS: Record<string, string>;
46
+ /**
47
+ * Load API key from config into cache
48
+ */
49
+ export declare function loadApiKey(providerId?: string): Promise<string>;
50
+ /**
51
+ * Load API keys for ALL providers into cache
52
+ * Should be called at app startup
53
+ */
54
+ export declare function loadAllApiKeys(): Promise<void>;
55
+ /**
56
+ * Get API key synchronously from cache (must call loadAllApiKeys first)
57
+ */
58
+ export declare function getApiKey(providerId?: string): string;
59
+ /**
60
+ * Set API key - stores in config file
61
+ */
62
+ export declare function setApiKey(key: string, providerId?: string): void;
63
+ export declare function getMaskedApiKey(providerId?: string): string;
64
+ /**
65
+ * Get list of providers that have API keys configured
66
+ */
67
+ export declare function getConfiguredProviders(): {
68
+ id: string;
69
+ name: string;
70
+ }[];
71
+ /**
72
+ * Clear API key for a specific provider
73
+ */
74
+ export declare function clearApiKey(providerId: string): void;
75
+ export declare function isConfiguredAsync(providerId?: string): Promise<boolean>;
76
+ export declare function isConfigured(providerId?: string): boolean;
77
+ export declare function getCurrentProvider(): {
78
+ id: string;
79
+ name: string;
80
+ };
81
+ export declare function setProvider(providerId: string): boolean;
82
+ export declare function getModelsForCurrentProvider(): Record<string, string>;
83
+ export { PROVIDERS } from './providers';
84
+ export declare function getCurrentSessionId(): string;
85
+ export declare function startNewSession(): string;
86
+ export declare function autoSaveSession(history: Message[], projectPath?: string): boolean;
87
+ export declare function flushAutoSave(): boolean;
88
+ export declare function saveSession(name: string, history: Message[], projectPath?: string): boolean;
89
+ export declare function loadSession(name: string, projectPath?: string): Message[] | null;
90
+ export declare function listSessions(projectPath?: string): string[];
91
+ export declare function deleteSession(name: string, projectPath?: string): boolean;
92
+ export declare function renameSession(oldName: string, newName: string, projectPath?: string): boolean;
93
+ export declare function getSessionInfo(name: string, projectPath?: string): {
94
+ name: string;
95
+ createdAt: string;
96
+ messageCount: number;
97
+ } | null;
98
+ export interface SessionInfo {
99
+ name: string;
100
+ createdAt: string;
101
+ messageCount: number;
102
+ fileSize: number;
103
+ }
104
+ /**
105
+ * List all sessions with metadata, sorted by date (newest first)
106
+ */
107
+ export declare function listSessionsWithInfo(projectPath?: string): SessionInfo[];
108
+ /**
109
+ * Get project permission from local .codeep/config.json
110
+ */
111
+ export declare function getProjectPermission(projectPath: string): ProjectPermission | null;
112
+ /**
113
+ * Set project permission in local .codeep/config.json
114
+ */
115
+ export declare function setProjectPermission(projectPath: string, read: boolean, write: boolean): void;
116
+ /**
117
+ * Remove project permission from local .codeep/config.json
118
+ */
119
+ export declare function removeProjectPermission(projectPath: string): boolean;
120
+ export declare function hasReadPermission(projectPath: string): boolean;
121
+ export declare function hasWritePermission(projectPath: string): boolean;