codeep 2.13.0 → 2.13.2
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/README.md +9 -1
- package/dist/acp/server.d.ts +41 -0
- package/dist/acp/server.js +38 -155
- package/dist/acp/serverHandlers.d.ts +88 -0
- package/dist/acp/serverHandlers.js +237 -0
- package/dist/acp/session.d.ts +9 -0
- package/dist/acp/session.js +6 -2
- package/dist/config/index.d.ts +2 -2
- package/dist/renderer/App.js +6 -119
- package/dist/renderer/agentExecution.js +2 -0
- package/dist/renderer/commands/registry.d.ts +92 -0
- package/dist/renderer/commands/registry.js +488 -0
- package/dist/renderer/components/Help.d.ts +12 -3
- package/dist/renderer/components/Help.js +14 -176
- package/dist/renderer/components/Settings.d.ts +5 -1
- package/dist/renderer/components/Settings.js +23 -5
- package/dist/renderer/main.js +4 -0
- package/dist/utils/codeepCloud.d.ts +6 -0
- package/dist/utils/gitHookInstaller.js +1 -1
- package/dist/utils/tokenTracker.d.ts +10 -0
- package/dist/utils/tokenTracker.js +9 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -10
|
@@ -1,184 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Help screen component
|
|
2
|
+
* Help screen component.
|
|
3
|
+
*
|
|
4
|
+
* The `/help` layout lives in `../commands/registry.ts` as `HELP_LAYOUT`
|
|
5
|
+
* (single source of truth, alongside the command metadata). This file
|
|
6
|
+
* re-exports it under the historical `helpCategories` name so existing
|
|
7
|
+
* callers (`App.ts`, `handlers.ts`) keep working, and owns the keyboard-
|
|
8
|
+
* shortcuts panel (which is independent of commands). The actual rendering
|
|
9
|
+
* is done by `App.ts`, which iterates `helpCategories` directly.
|
|
3
10
|
*/
|
|
4
|
-
import {
|
|
5
|
-
// Primary color: #f02a30 (Codeep red)
|
|
6
|
-
const PRIMARY_COLOR = fg.rgb(240, 42, 48);
|
|
11
|
+
import { HELP_LAYOUT } from '../commands/registry.js';
|
|
7
12
|
/**
|
|
8
|
-
* Codeep command help data
|
|
13
|
+
* Codeep command help data — re-exported from the registry so there's a
|
|
14
|
+
* single source of truth for both `/help` rendering and `/` autocomplete.
|
|
9
15
|
*/
|
|
10
|
-
export const helpCategories =
|
|
11
|
-
{
|
|
12
|
-
title: 'General',
|
|
13
|
-
items: [
|
|
14
|
-
{ key: '/help', description: 'Show this help' },
|
|
15
|
-
{ key: '/status', description: 'Current status' },
|
|
16
|
-
{ key: '/settings', description: 'Open settings' },
|
|
17
|
-
{ key: '/version', description: 'Show version' },
|
|
18
|
-
{ key: '/update', description: 'Check for updates' },
|
|
19
|
-
{ key: '/stats (/cost)', description: 'Token usage & cost this session' },
|
|
20
|
-
{ key: '/clear', description: 'Clear chat' },
|
|
21
|
-
{ key: '/exit', description: 'Quit application' },
|
|
22
|
-
],
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
title: 'Sessions',
|
|
26
|
-
items: [
|
|
27
|
-
{ key: '/sessions', description: 'List and load sessions' },
|
|
28
|
-
{ key: '/new', description: 'Start new session' },
|
|
29
|
-
{ key: '/rename <name>', description: 'Rename current session' },
|
|
30
|
-
{ key: '/search <term>', description: 'Search the current session' },
|
|
31
|
-
{ key: '/recall <query>', description: 'Search across ALL saved sessions (cross-session)' },
|
|
32
|
-
{ key: '/recall … --resume', description: 'Load the top-matching session directly' },
|
|
33
|
-
{ key: '/recall … --summarize', description: 'LLM recap of what you did across matches' },
|
|
34
|
-
{ key: '/export [md|json|txt]', description: 'Export chat' },
|
|
35
|
-
{ key: '/compact [keepN]', description: 'AI-summarize older messages to free up context (keeps last N)' },
|
|
36
|
-
],
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
title: 'Checkpoints (2.0)',
|
|
40
|
-
items: [
|
|
41
|
-
{ key: '/checkpoint [name]', description: 'Snapshot conversation + provider/model + git HEAD' },
|
|
42
|
-
{ key: '/checkpoints', description: 'List saved checkpoints in this workspace' },
|
|
43
|
-
{ key: '/rewind <id>', description: 'Restore conversation from a checkpoint' },
|
|
44
|
-
{ key: '/checkpoint delete <id>', description: 'Delete a saved checkpoint' },
|
|
45
|
-
],
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
title: 'Agent Mode',
|
|
49
|
-
items: [
|
|
50
|
-
{ key: '/agent <task>', description: 'Run agent with task' },
|
|
51
|
-
{ key: '/agent-dry <task>', description: 'Dry run (no changes)' },
|
|
52
|
-
{ key: '/plan <task>', description: 'Generate a plan first — review before /go executes' },
|
|
53
|
-
{ key: '/go', description: 'Execute the pending plan from /plan' },
|
|
54
|
-
{ key: '/stop', description: 'Stop running agent' },
|
|
55
|
-
{ key: '/undo', description: 'Undo last agent action' },
|
|
56
|
-
{ key: '/undo-all', description: 'Undo all agent actions' },
|
|
57
|
-
{ key: '/history', description: 'Show agent history' },
|
|
58
|
-
{ key: '/changes', description: 'Show session changes' },
|
|
59
|
-
],
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
title: 'Git & Project',
|
|
63
|
-
items: [
|
|
64
|
-
{ key: '/diff', description: 'Review git diff with AI' },
|
|
65
|
-
{ key: '/diff --staged', description: 'Review staged changes' },
|
|
66
|
-
{ key: '/commit (/c)', description: 'Generate commit message' },
|
|
67
|
-
{ key: '/git-commit <msg>', description: 'Commit with message' },
|
|
68
|
-
{ key: '/push (/p)', description: 'Git push' },
|
|
69
|
-
{ key: '/pull', description: 'Git pull' },
|
|
70
|
-
{ key: '/amend', description: 'Amend last commit' },
|
|
71
|
-
{ key: '/branch', description: 'Create/manage branches' },
|
|
72
|
-
{ key: '/stash', description: 'Stash changes' },
|
|
73
|
-
{ key: '/init', description: 'Initialize project (.codeep/ folder)' },
|
|
74
|
-
{ key: '/scan', description: 'Scan project structure' },
|
|
75
|
-
{ key: '/memory <note>', description: 'Add note to project intelligence' },
|
|
76
|
-
{ key: '/memory list', description: 'Show all memory notes' },
|
|
77
|
-
{ key: '/memory remove <n>', description: 'Remove note by index' },
|
|
78
|
-
{ key: '/memory clear', description: 'Clear all memory notes' },
|
|
79
|
-
{ key: '/review', description: 'AI review of unstaged git changes (not full codebase)' },
|
|
80
|
-
{ key: '/review --staged', description: 'AI review of staged git changes' },
|
|
81
|
-
{ key: '/review --static', description: 'Static analysis — changed files, or whole src/ if clean' },
|
|
82
|
-
{ key: '/review <file>', description: 'Static analysis of specific file(s)' },
|
|
83
|
-
],
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
title: 'Code Operations',
|
|
87
|
-
items: [
|
|
88
|
-
{ key: '/copy [n]', description: 'Copy code block to clipboard' },
|
|
89
|
-
{ key: '/paste', description: 'Paste from clipboard' },
|
|
90
|
-
{ key: '/apply', description: 'Apply file changes from AI' },
|
|
91
|
-
{ key: '/add <path>', description: 'Add file to context' },
|
|
92
|
-
{ key: '/drop [path]', description: 'Remove file (or all) from context' },
|
|
93
|
-
{ key: '/multiline', description: 'Toggle multi-line input mode' },
|
|
94
|
-
],
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
title: 'Skills (Shortcuts)',
|
|
98
|
-
items: [
|
|
99
|
-
{ key: '/test (/t)', description: 'Generate/run tests' },
|
|
100
|
-
{ key: '/docs (/d)', description: 'Add documentation' },
|
|
101
|
-
{ key: '/refactor (/r)', description: 'Improve code quality' },
|
|
102
|
-
{ key: '/fix (/f)', description: 'Debug and fix issues' },
|
|
103
|
-
{ key: '/explain (/e)', description: 'Explain code' },
|
|
104
|
-
{ key: '/optimize (/o)', description: 'Optimize performance' },
|
|
105
|
-
{ key: '/debug (/b)', description: 'Debug problems' },
|
|
106
|
-
{ key: '/security', description: 'Security audit (SQLi, XSS, secrets, auth)' },
|
|
107
|
-
{ key: '/coverage', description: 'Run/analyze test coverage' },
|
|
108
|
-
{ key: '/component <name>', description: 'Generate UI component' },
|
|
109
|
-
{ key: '/api <name>', description: 'Generate API endpoint' },
|
|
110
|
-
{ key: '/docker', description: 'Generate Dockerfile + compose' },
|
|
111
|
-
{ key: '/skills', description: 'List all 50+ skills' },
|
|
112
|
-
{ key: '/skills <query>', description: 'Search skills by keyword' },
|
|
113
|
-
],
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
title: 'Settings',
|
|
117
|
-
items: [
|
|
118
|
-
{ key: '/provider', description: 'Change AI provider' },
|
|
119
|
-
{ key: '/model', description: 'Change model' },
|
|
120
|
-
{ key: '/model <name>', description: 'Load saved profile (e.g. /model fast)' },
|
|
121
|
-
{ key: '/protocol', description: 'Switch API protocol' },
|
|
122
|
-
{ key: '/lang', description: 'Set response language' },
|
|
123
|
-
{ key: '/grant', description: 'Grant write permission' },
|
|
124
|
-
{ key: '/login', description: 'Login with API key' },
|
|
125
|
-
{ key: '/logout', description: 'Logout from provider' },
|
|
126
|
-
{ key: '/profile save <name>', description: 'Save current provider+model as profile' },
|
|
127
|
-
{ key: '/profile list', description: 'List saved profiles' },
|
|
128
|
-
{ key: '/openrouter', description: 'OpenRouter routing prefs (prefer/ignore providers, fallbacks, privacy)' },
|
|
129
|
-
{ key: '/personality', description: 'List or switch agent tone (concise / verbose / security / senior-reviewer / …)' },
|
|
130
|
-
{ key: '/personality <name>', description: 'Activate a personality. /personality off to clear.' },
|
|
131
|
-
{ key: '/me', description: 'Your user profile (reply language, style, stack) — adapts the agent to you' },
|
|
132
|
-
{ key: '/me init [project]', description: 'Scaffold a profile template (global, or for this project). /me off to disable' },
|
|
133
|
-
{ key: '/me learn [on|off]', description: 'Learn durable prefs from this session now; on/off toggles auto-learn. /me forget clears it' },
|
|
134
|
-
{ key: '/me sync', description: 'Push your profile to the codeep.dev dashboard (and pull on a fresh machine)' },
|
|
135
|
-
{ key: '/agents', description: 'List sub-agents the agent can delegate to (researcher / reviewer / tester / your own)' },
|
|
136
|
-
{ key: '/insights [--days N]', description: 'Activity summary — runs, files, tools, projects over the last N days (default 7)' },
|
|
137
|
-
],
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
title: 'Extensions & MCP (2.0)',
|
|
141
|
-
items: [
|
|
142
|
-
{ key: '/mcp', description: 'List connected MCP servers + their tools' },
|
|
143
|
-
{ key: '/mcp browse [id]', description: 'Browse marketplace (12 servers) or show one' },
|
|
144
|
-
{ key: '/mcp install <id> [args]', description: 'Install a marketplace server into this project' },
|
|
145
|
-
{ key: '/mcp add <name> <cmd>', description: 'Add a custom MCP server (npx, binary, etc.)' },
|
|
146
|
-
{ key: '/mcp remove <name>', description: 'Remove a project-scoped MCP server' },
|
|
147
|
-
{ key: '/mcp reload', description: 'Re-read .codeep/mcp_servers.json (after manual edit)' },
|
|
148
|
-
{ key: '/mcp resources', description: 'List resources exposed by connected servers' },
|
|
149
|
-
{ key: '/mcp read <uri>', description: 'Read one MCP resource' },
|
|
150
|
-
{ key: '/mcp prompts', description: 'List prompt templates exposed by servers' },
|
|
151
|
-
{ key: '/mcp prompt <server> <name>', description: 'Materialize a prompt with arguments (key=value)' },
|
|
152
|
-
{ key: '/hooks', description: 'List installed lifecycle hooks (.codeep/hooks/<event>.sh)' },
|
|
153
|
-
{ key: '/commands', description: 'List custom slash commands (.codeep/commands/*.md)' },
|
|
154
|
-
],
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
title: 'Context',
|
|
158
|
-
items: [
|
|
159
|
-
{ key: '/context-save', description: 'Save conversation' },
|
|
160
|
-
{ key: '/context-load', description: 'Load conversation' },
|
|
161
|
-
{ key: '/context-clear', description: 'Clear saved context' },
|
|
162
|
-
{ key: '/learn', description: 'Learn code preferences' },
|
|
163
|
-
{ key: '/learn status', description: 'Show learned prefs' },
|
|
164
|
-
{ key: '/learn rule <text>', description: 'Add custom rule' },
|
|
165
|
-
],
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
title: 'Ollama (Local AI)',
|
|
169
|
-
items: [
|
|
170
|
-
{ key: '/provider', description: 'Select "ollama" for local models' },
|
|
171
|
-
{ key: '/settings > Ollama URL', description: 'Set URL (default: http://localhost:11434)' },
|
|
172
|
-
{ key: '/model', description: 'Pick installed Ollama model dynamically' },
|
|
173
|
-
{ key: '/model pull <model>', description: 'Pull an Ollama model (local Ollama only)' },
|
|
174
|
-
{ key: '/model browse', description: 'Browse recommended local coding models and pull one' },
|
|
175
|
-
{ key: '/model rm <model>', description: 'Remove a locally-installed Ollama model (local only)' },
|
|
176
|
-
{ key: 'OLLAMA_HOST=0.0.0.0', description: 'Required env var for remote Ollama access' },
|
|
177
|
-
],
|
|
178
|
-
},
|
|
179
|
-
];
|
|
16
|
+
export const helpCategories = HELP_LAYOUT;
|
|
180
17
|
/**
|
|
181
|
-
* Keyboard shortcuts
|
|
18
|
+
* Keyboard shortcuts (independent of the command registry — raw key
|
|
19
|
+
* bindings, not slash commands).
|
|
182
20
|
*/
|
|
183
21
|
export const keyboardShortcuts = [
|
|
184
22
|
{ key: 'Enter', description: 'Send message' },
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Settings screen component
|
|
3
3
|
*/
|
|
4
|
+
import { type ConfigSchema } from '../../config/index';
|
|
4
5
|
export interface SettingItem {
|
|
5
|
-
key
|
|
6
|
+
/** Must be a known config key — typed as `keyof ConfigSchema` so adding a
|
|
7
|
+
* setting with an unknown key is a compile error, not a silent runtime
|
|
8
|
+
* no-op. */
|
|
9
|
+
key: keyof ConfigSchema;
|
|
6
10
|
label: string;
|
|
7
11
|
getValue: () => string | number | boolean;
|
|
8
12
|
type: 'number' | 'select' | 'text';
|
|
@@ -7,6 +7,24 @@ import { updateRateLimits } from '../../utils/ratelimit.js';
|
|
|
7
7
|
// Primary color: #f02a30 (Codeep red)
|
|
8
8
|
const PRIMARY_COLOR = fg.rgb(240, 42, 48);
|
|
9
9
|
const PRIMARY_BRIGHT = fg.rgb(255, 80, 85);
|
|
10
|
+
/**
|
|
11
|
+
* Write a value to the config for a given setting.
|
|
12
|
+
*
|
|
13
|
+
* This is the single typed write path for the settings screen. The win is on
|
|
14
|
+
* the KEY: `setting.key` is `keyof ConfigSchema` and `config.set` is generic
|
|
15
|
+
* over the key, so a misspelled or unknown setting key is now a compile error
|
|
16
|
+
* (previously every call site used `config.set(setting.key as any, …)`, which
|
|
17
|
+
* suppressed that check too). The VALUE is NOT checked against the specific
|
|
18
|
+
* key's type — because `SettingItem` is heterogeneous, `typeof setting.key`
|
|
19
|
+
* widens to the full key union and `ConfigSchema[typeof setting.key]` collapses
|
|
20
|
+
* to the union of every value type, so the cast here is intentionally wide.
|
|
21
|
+
* Centralising it keeps that one unavoidable cast in a single audited spot
|
|
22
|
+
* instead of seven. (Per-key value safety would need a generic `SettingItem<K>`
|
|
23
|
+
* authored via a `defineSetting<K>` helper — tracked as a follow-up.)
|
|
24
|
+
*/
|
|
25
|
+
function writeSetting(setting, value) {
|
|
26
|
+
config.set(setting.key, value);
|
|
27
|
+
}
|
|
10
28
|
export const SETTINGS = [
|
|
11
29
|
{
|
|
12
30
|
key: 'temperature',
|
|
@@ -308,7 +326,7 @@ export function handleSettingsKey(key, ctrl, state) {
|
|
|
308
326
|
const num = parseFloat(state.editValue);
|
|
309
327
|
if (!isNaN(num)) {
|
|
310
328
|
const clamped = Math.max(setting.min || 0, Math.min(setting.max || Infinity, num));
|
|
311
|
-
|
|
329
|
+
writeSetting(setting, clamped);
|
|
312
330
|
if (setting.key === 'rateLimitApi' || setting.key === 'rateLimitCommands') {
|
|
313
331
|
updateRateLimits();
|
|
314
332
|
}
|
|
@@ -318,7 +336,7 @@ export function handleSettingsKey(key, ctrl, state) {
|
|
|
318
336
|
}
|
|
319
337
|
}
|
|
320
338
|
if (setting.type === 'text' && state.editValue.trim()) {
|
|
321
|
-
|
|
339
|
+
writeSetting(setting, state.editValue.trim());
|
|
322
340
|
newState.editing = false;
|
|
323
341
|
newState.editValue = '';
|
|
324
342
|
return { handled: true, close: false, notify: `${setting.label}: ${state.editValue.trim()}`, newState };
|
|
@@ -358,7 +376,7 @@ export function handleSettingsKey(key, ctrl, state) {
|
|
|
358
376
|
const step = setting.step || 1;
|
|
359
377
|
const delta = key === 'left' ? -step : step;
|
|
360
378
|
const newValue = Math.max(setting.min || 0, Math.min(setting.max || Infinity, current + delta));
|
|
361
|
-
|
|
379
|
+
writeSetting(setting, newValue);
|
|
362
380
|
if (setting.key === 'rateLimitApi' || setting.key === 'rateLimitCommands') {
|
|
363
381
|
updateRateLimits();
|
|
364
382
|
}
|
|
@@ -370,7 +388,7 @@ export function handleSettingsKey(key, ctrl, state) {
|
|
|
370
388
|
const newIdx = key === 'left'
|
|
371
389
|
? (currentIdx - 1 + setting.options.length) % setting.options.length
|
|
372
390
|
: (currentIdx + 1) % setting.options.length;
|
|
373
|
-
|
|
391
|
+
writeSetting(setting, setting.options[newIdx].value);
|
|
374
392
|
return { handled: true, close: false, newState };
|
|
375
393
|
}
|
|
376
394
|
return { handled: true, close: false, newState };
|
|
@@ -386,7 +404,7 @@ export function handleSettingsKey(key, ctrl, state) {
|
|
|
386
404
|
const current = config.get(setting.key);
|
|
387
405
|
const currentIdx = setting.options.findIndex(o => o.value === current);
|
|
388
406
|
const newIdx = (currentIdx + 1) % setting.options.length;
|
|
389
|
-
|
|
407
|
+
writeSetting(setting, setting.options[newIdx].value);
|
|
390
408
|
return {
|
|
391
409
|
handled: true,
|
|
392
410
|
close: false,
|
package/dist/renderer/main.js
CHANGED
|
@@ -203,6 +203,8 @@ async function handleSubmit(message) {
|
|
|
203
203
|
provider: entry.provider,
|
|
204
204
|
inputTokens: entry.promptTokens || undefined,
|
|
205
205
|
outputTokens: entry.completionTokens || undefined,
|
|
206
|
+
cacheCreationTokens: entry.cacheCreationTokens || undefined,
|
|
207
|
+
cacheReadTokens: entry.cacheReadTokens || undefined,
|
|
206
208
|
estimatedCost: entry.estimatedCost || undefined,
|
|
207
209
|
});
|
|
208
210
|
}
|
|
@@ -888,6 +890,8 @@ async function gracefulShutdown() {
|
|
|
888
890
|
projectId,
|
|
889
891
|
inputTokens: tokenStats.totalPromptTokens || undefined,
|
|
890
892
|
outputTokens: tokenStats.totalCompletionTokens || undefined,
|
|
893
|
+
cacheCreationTokens: tokenStats.totalCacheCreationTokens || undefined,
|
|
894
|
+
cacheReadTokens: tokenStats.totalCacheReadTokens || undefined,
|
|
891
895
|
estimatedCost: tokenStats.estimatedCost || undefined,
|
|
892
896
|
}),
|
|
893
897
|
]);
|
|
@@ -25,6 +25,12 @@ export interface StatsPayload {
|
|
|
25
25
|
isGit?: boolean;
|
|
26
26
|
inputTokens?: number;
|
|
27
27
|
outputTokens?: number;
|
|
28
|
+
/** Anthropic prompt caching: tokens written to cache (billed ~1.25× input).
|
|
29
|
+
* Undefined for providers that don't report caching. */
|
|
30
|
+
cacheCreationTokens?: number;
|
|
31
|
+
/** Anthropic prompt caching: tokens read from cache (billed ~0.1× input).
|
|
32
|
+
* Undefined for providers that don't report caching. */
|
|
33
|
+
cacheReadTokens?: number;
|
|
28
34
|
estimatedCost?: number;
|
|
29
35
|
}
|
|
30
36
|
/**
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// issues at/above the threshold are found. Honors .codeep/review.{yml,json}.
|
|
4
4
|
//
|
|
5
5
|
// This is a GIT-hook installer — distinct from the lifecycle SHELL hooks in
|
|
6
|
-
// utils/hooks.ts (.codeep/hooks/<event>.sh)
|
|
6
|
+
// utils/hooks.ts (.codeep/hooks/<event>.sh).
|
|
7
7
|
import { readFileSync, writeFileSync, mkdirSync, chmodSync, rmSync } from 'fs';
|
|
8
8
|
import { join, dirname, isAbsolute } from 'path';
|
|
9
9
|
import { execSync } from 'child_process';
|
|
@@ -19,6 +19,10 @@ export interface SessionTokenStats {
|
|
|
19
19
|
totalTokens: number;
|
|
20
20
|
requestCount: number;
|
|
21
21
|
estimatedCost: number;
|
|
22
|
+
/** Anthropic prompt caching: total tokens written to cache this session. */
|
|
23
|
+
totalCacheCreationTokens: number;
|
|
24
|
+
/** Anthropic prompt caching: total tokens read from cache this session. */
|
|
25
|
+
totalCacheReadTokens: number;
|
|
22
26
|
}
|
|
23
27
|
interface TokenRecord {
|
|
24
28
|
timestamp: number;
|
|
@@ -63,6 +67,12 @@ export interface ProviderCostBreakdown {
|
|
|
63
67
|
model: string;
|
|
64
68
|
promptTokens: number;
|
|
65
69
|
completionTokens: number;
|
|
70
|
+
/** Anthropic prompt caching: tokens written to cache (billed ~1.25× input).
|
|
71
|
+
* 0 for providers that don't report caching. */
|
|
72
|
+
cacheCreationTokens: number;
|
|
73
|
+
/** Anthropic prompt caching: tokens read from cache (billed ~0.1× input).
|
|
74
|
+
* 0 for providers that don't report caching. */
|
|
75
|
+
cacheReadTokens: number;
|
|
66
76
|
estimatedCost: number;
|
|
67
77
|
}
|
|
68
78
|
/**
|
|
@@ -167,9 +167,11 @@ export function getCostBreakdown() {
|
|
|
167
167
|
const grouped = new Map();
|
|
168
168
|
for (const record of records) {
|
|
169
169
|
const key = `${record.provider}/${record.model}`;
|
|
170
|
-
const existing = grouped.get(key) ?? { provider: record.provider, model: record.model, promptTokens: 0, completionTokens: 0, estimatedCost: 0 };
|
|
170
|
+
const existing = grouped.get(key) ?? { provider: record.provider, model: record.model, promptTokens: 0, completionTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0, estimatedCost: 0 };
|
|
171
171
|
existing.promptTokens += record.promptTokens;
|
|
172
172
|
existing.completionTokens += record.completionTokens;
|
|
173
|
+
existing.cacheCreationTokens += record.cacheCreationTokens ?? 0;
|
|
174
|
+
existing.cacheReadTokens += record.cacheReadTokens ?? 0;
|
|
173
175
|
// Cost source priority:
|
|
174
176
|
// 1. Provider-reported USD (OpenRouter, MaxiCloud, etc.) — most accurate.
|
|
175
177
|
// 2. Our MODEL_PRICING table — for built-in providers we maintain rates for.
|
|
@@ -223,10 +225,14 @@ export function getSessionStats() {
|
|
|
223
225
|
let totalPromptTokens = 0;
|
|
224
226
|
let totalCompletionTokens = 0;
|
|
225
227
|
let totalTokens = 0;
|
|
228
|
+
let totalCacheCreationTokens = 0;
|
|
229
|
+
let totalCacheReadTokens = 0;
|
|
226
230
|
for (const record of records) {
|
|
227
231
|
totalPromptTokens += record.promptTokens;
|
|
228
232
|
totalCompletionTokens += record.completionTokens;
|
|
229
233
|
totalTokens += record.totalTokens;
|
|
234
|
+
totalCacheCreationTokens += record.cacheCreationTokens ?? 0;
|
|
235
|
+
totalCacheReadTokens += record.cacheReadTokens ?? 0;
|
|
230
236
|
}
|
|
231
237
|
const estimatedCost = getCostBreakdown().reduce((s, b) => s + b.estimatedCost, 0);
|
|
232
238
|
return {
|
|
@@ -235,6 +241,8 @@ export function getSessionStats() {
|
|
|
235
241
|
totalTokens,
|
|
236
242
|
requestCount: records.length,
|
|
237
243
|
estimatedCost,
|
|
244
|
+
totalCacheCreationTokens,
|
|
245
|
+
totalCacheReadTokens,
|
|
238
246
|
};
|
|
239
247
|
}
|
|
240
248
|
/**
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "2.13.
|
|
1
|
+
export declare const VERSION = "2.13.2";
|
package/dist/version.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// AUTO-GENERATED by scripts/gen-version.js — do not edit by hand.
|
|
2
2
|
// Baked from package.json at build time so the bun-compiled binary reports
|
|
3
3
|
// the right version (it has no package.json on disk to read at runtime).
|
|
4
|
-
export const VERSION = '2.13.
|
|
4
|
+
export const VERSION = '2.13.2';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeep",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.2",
|
|
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",
|
|
@@ -10,9 +10,8 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"dev": "node scripts/gen-version.js && node --import tsx src/renderer/main.ts",
|
|
12
12
|
"prepack": "node scripts/gen-version.js && tsc && node scripts/fix-imports.js",
|
|
13
|
-
"build": "node scripts/gen-version.js && tsc && node scripts/fix-imports.js",
|
|
13
|
+
"build": "node scripts/gen-version.js && rm -rf dist && tsc && node scripts/fix-imports.js",
|
|
14
14
|
"start": "node dist/renderer/main.js",
|
|
15
|
-
"build:binary": "npm run build && pkg dist/renderer/main.js --targets node18-macos-arm64,node18-macos-x64,node18-linux-x64 --output bin/codeep",
|
|
16
15
|
"test": "vitest run",
|
|
17
16
|
"test:watch": "vitest",
|
|
18
17
|
"test:coverage": "vitest run --coverage",
|
|
@@ -39,7 +38,7 @@
|
|
|
39
38
|
"homepage": "https://codeep.dev",
|
|
40
39
|
"dependencies": {
|
|
41
40
|
"clipboardy": "^4.0.0",
|
|
42
|
-
"conf": "^
|
|
41
|
+
"conf": "^13.1.0",
|
|
43
42
|
"js-yaml": "^4.1.0",
|
|
44
43
|
"keytar": "^7.9.0",
|
|
45
44
|
"open": "^10.0.0"
|
|
@@ -48,7 +47,6 @@
|
|
|
48
47
|
"@types/js-yaml": "^4.0.9",
|
|
49
48
|
"@types/node": "^20.10.0",
|
|
50
49
|
"@vitest/coverage-v8": "^4.0.18",
|
|
51
|
-
"pkg": "^5.8.1",
|
|
52
50
|
"tsx": "^4.7.0",
|
|
53
51
|
"typescript": "^6.0.2",
|
|
54
52
|
"vitest": "^4.0.18"
|
|
@@ -67,10 +65,5 @@
|
|
|
67
65
|
],
|
|
68
66
|
"publishConfig": {
|
|
69
67
|
"access": "public"
|
|
70
|
-
},
|
|
71
|
-
"pkg": {
|
|
72
|
-
"assets": [
|
|
73
|
-
"dist/acp/**/*"
|
|
74
|
-
]
|
|
75
68
|
}
|
|
76
69
|
}
|