codeep 2.9.0 → 2.10.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.
- package/dist/acp/commands.js +29 -1
- package/dist/acp/server.js +3 -0
- package/dist/renderer/App.js +2 -2
- package/dist/renderer/commands.js +57 -9
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/acp/commands.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Slash command handler for ACP sessions.
|
|
3
3
|
// Mirrors CLI commands from renderer/commands.ts but returns plain text
|
|
4
4
|
// responses (no TUI) suitable for streaming back via session/update.
|
|
5
|
-
import { config, getCurrentProvider, getModelsForCurrentProvider, setProvider, setApiKey, isConfigured, listSessionsWithInfo, startNewSession, loadSession, saveSession, initializeAsProject, isManuallyInitializedProject, setProjectPermission, hasWritePermission, hasReadPermission, isTelemetryEnabled, telemetryForcedOffByEnv, } from '../config/index.js';
|
|
5
|
+
import { config, getCurrentProvider, getModelsForCurrentProvider, setProvider, setApiKey, isConfigured, listSessionsWithInfo, startNewSession, loadSession, saveSession, initializeAsProject, isManuallyInitializedProject, setProjectPermission, hasWritePermission, hasReadPermission, isTelemetryEnabled, telemetryForcedOffByEnv, isKeySyncEnabled, keySyncForcedOffByEnv, } from '../config/index.js';
|
|
6
6
|
import { getProviderList, getProvider } from '../config/providers.js';
|
|
7
7
|
import { getProjectContext } from '../utils/project.js';
|
|
8
8
|
import { loadCustomCommands } from '../utils/customCommands.js';
|
|
@@ -237,6 +237,34 @@ export async function handleCommand(input, session, onChunk, abortSignal) {
|
|
|
237
237
|
lines.push('', 'Toggle with `/telemetry on` | `/telemetry off`. Controls automatic uploads of usage stats, session transcripts, progress, and memory notes.');
|
|
238
238
|
return { handled: true, response: lines.join('\n') };
|
|
239
239
|
}
|
|
240
|
+
case 'keysync': {
|
|
241
|
+
const sub = args[0]?.toLowerCase();
|
|
242
|
+
const envOff = keySyncForcedOffByEnv();
|
|
243
|
+
if (sub === 'on' || sub === 'off') {
|
|
244
|
+
if (envOff) {
|
|
245
|
+
return { handled: true, response: 'Cloud key sync is forced **off** by the `CODEEP_NO_KEY_SYNC` env var — unset it to change this. The config flag can\'t override an env var.' };
|
|
246
|
+
}
|
|
247
|
+
config.set('syncKeysToCloud', sub === 'on');
|
|
248
|
+
return {
|
|
249
|
+
handled: true,
|
|
250
|
+
response: sub === 'on'
|
|
251
|
+
? 'Cloud key sync **on** — `codeep account push`/`sync` will now upload/download API keys. Note: synced keys are stored server-readable on codeep.dev.'
|
|
252
|
+
: 'Cloud key sync **off** — API keys stay in your OS keychain only. (`codeep account purge-keys` wipes any keys already on the server.)',
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
if (sub && sub !== 'status') {
|
|
256
|
+
return { handled: true, response: 'Usage: `/keysync` · `/keysync on` · `/keysync off`' };
|
|
257
|
+
}
|
|
258
|
+
const flag = config.get('syncKeysToCloud') === true;
|
|
259
|
+
const lines = [
|
|
260
|
+
`**Cloud key sync:** ${isKeySyncEnabled() ? 'on' : 'off'}`,
|
|
261
|
+
`- Config flag \`syncKeysToCloud\`: ${flag}`,
|
|
262
|
+
];
|
|
263
|
+
if (envOff)
|
|
264
|
+
lines.push('- Forced **off** by `CODEEP_NO_KEY_SYNC` (env overrides the flag).');
|
|
265
|
+
lines.push('', 'OFF by default — API keys live only in your OS keychain unless enabled. When on, `codeep account push`/`sync` move keys, stored **server-readable** on codeep.dev.');
|
|
266
|
+
return { handled: true, response: lines.join('\n') };
|
|
267
|
+
}
|
|
240
268
|
case 'login': {
|
|
241
269
|
const [providerId, apiKey] = args;
|
|
242
270
|
if (!providerId || !apiKey) {
|
package/dist/acp/server.js
CHANGED
|
@@ -67,6 +67,9 @@ const AVAILABLE_COMMANDS = [
|
|
|
67
67
|
{ name: 'learn', description: 'Learn coding preferences from project files' },
|
|
68
68
|
{ name: 'memory', description: 'Project memory notes — add / list / remove / clear', input: { hint: '<note> | list | remove <n> | clear' } },
|
|
69
69
|
{ name: 'profile', description: 'Save / load / delete provider+model presets', input: { hint: 'save | load | delete | list | <name>' } },
|
|
70
|
+
// Privacy toggles
|
|
71
|
+
{ name: 'telemetry', description: 'Show or toggle automatic cloud telemetry', input: { hint: '[on|off]' } },
|
|
72
|
+
{ name: 'keysync', description: 'Show or toggle syncing API keys to codeep.dev (off by default)', input: { hint: '[on|off]' } },
|
|
70
73
|
// Skills + custom commands
|
|
71
74
|
{ name: 'skills', description: 'List/create/share skill bundles. Subcommands: bundles, create-bundle, show, publish, install, browse, unpublish', input: { hint: '[query] | bundles | create-bundle <name> | show <name> | publish <slug> [--public] | install <owner>/<slug> | browse [q] | unpublish <owner>/<slug>' } },
|
|
72
75
|
{ name: 'commands', description: 'List user-authored commands from .codeep/commands/*.md' },
|
package/dist/renderer/App.js
CHANGED
|
@@ -80,7 +80,7 @@ const COMMAND_DESCRIPTIONS = {
|
|
|
80
80
|
'learn': 'Learn code preferences',
|
|
81
81
|
'cost': 'Show session cost and token usage',
|
|
82
82
|
'profile': 'Save/load settings profiles',
|
|
83
|
-
'tasks': '
|
|
83
|
+
'tasks': 'List/add/done/delete codeep.dev tasks — add <title> [--bug|--feature]',
|
|
84
84
|
'sync': 'Sync learning preferences and profiles to codeep.dev',
|
|
85
85
|
'telemetry': 'Show or toggle automatic cloud telemetry (on/off)',
|
|
86
86
|
'keysync': 'Show or toggle syncing API keys to codeep.dev (on/off)',
|
|
@@ -234,7 +234,7 @@ export class App {
|
|
|
234
234
|
'multiline', 'memory', 'init',
|
|
235
235
|
'provider', 'model', 'protocol', 'lang', 'grant', 'login', 'logout',
|
|
236
236
|
'context-save', 'context-load', 'context-clear', 'learn',
|
|
237
|
-
'cost', 'tasks', 'account', 'sync', 'telemetry',
|
|
237
|
+
'cost', 'tasks', 'account', 'sync', 'keysync', 'telemetry',
|
|
238
238
|
// 2.0 — extensions, checkpoints, MCP, custom commands, OpenRouter prefs.
|
|
239
239
|
// Keep in lockstep with COMMAND_DESCRIPTIONS below and helpCategories.
|
|
240
240
|
'compact', 'commands', 'checkpoint', 'checkpoints', 'rewind',
|
|
@@ -1833,11 +1833,40 @@ Describe what this skill does. The agent reads this body verbatim when it invoke
|
|
|
1833
1833
|
}
|
|
1834
1834
|
break;
|
|
1835
1835
|
}
|
|
1836
|
-
// /tasks add <title> — create a
|
|
1836
|
+
// /tasks add <title> [--bug | --feature] [--desc <text>] — create a task
|
|
1837
|
+
// on the dashboard. Type matches the dashboard picker (task | bug |
|
|
1838
|
+
// feature); a --bug/--feature/--task flag anywhere sets it (default task).
|
|
1839
|
+
// --desc/--description captures the following words (until the next flag)
|
|
1840
|
+
// as the description — the same field the dashboard + macOS app set, and
|
|
1841
|
+
// which the list view and the agent task-context prompt already render.
|
|
1837
1842
|
if (subCmd === 'add') {
|
|
1838
|
-
const
|
|
1843
|
+
const TASK_TYPES = ['task', 'bug', 'feature'];
|
|
1844
|
+
let type = 'task';
|
|
1845
|
+
const titleWords = [];
|
|
1846
|
+
const descWords = [];
|
|
1847
|
+
let capturingDesc = false;
|
|
1848
|
+
for (const w of args.slice(1)) {
|
|
1849
|
+
const flag = /^--([\w-]+)$/.exec(w);
|
|
1850
|
+
if (flag) {
|
|
1851
|
+
const name = flag[1].toLowerCase();
|
|
1852
|
+
if (name === 'desc' || name === 'description') {
|
|
1853
|
+
capturingDesc = true;
|
|
1854
|
+
continue;
|
|
1855
|
+
}
|
|
1856
|
+
if (TASK_TYPES.includes(name))
|
|
1857
|
+
type = name;
|
|
1858
|
+
capturingDesc = false; // any non-desc flag ends description capture
|
|
1859
|
+
continue;
|
|
1860
|
+
}
|
|
1861
|
+
if (capturingDesc)
|
|
1862
|
+
descWords.push(w);
|
|
1863
|
+
else
|
|
1864
|
+
titleWords.push(w);
|
|
1865
|
+
}
|
|
1866
|
+
const title = titleWords.join(' ').trim();
|
|
1867
|
+
const description = descWords.join(' ').trim();
|
|
1839
1868
|
if (!title) {
|
|
1840
|
-
ctx.app.notify('Usage: /tasks add <title>');
|
|
1869
|
+
ctx.app.notify('Usage: /tasks add <title> [--bug | --feature] [--desc <text>]');
|
|
1841
1870
|
break;
|
|
1842
1871
|
}
|
|
1843
1872
|
const projectName = ctx.projectContext?.name;
|
|
@@ -1852,10 +1881,10 @@ Describe what this skill does. The agent reads this body verbatim when it invoke
|
|
|
1852
1881
|
const res = await fetch('https://codeep.dev/api/tasks', {
|
|
1853
1882
|
method: 'POST',
|
|
1854
1883
|
headers: { 'Content-Type': 'application/json', 'x-sync-token': syncToken },
|
|
1855
|
-
body: JSON.stringify({ projectName: projectName || '', projectId: projectId ?? null, title, type:
|
|
1884
|
+
body: JSON.stringify({ projectName: projectName || '', projectId: projectId ?? null, title, type, ...(description ? { description } : {}) }),
|
|
1856
1885
|
});
|
|
1857
1886
|
if (res.ok) {
|
|
1858
|
-
ctx.app.notify(`+
|
|
1887
|
+
ctx.app.notify(`+ ${type[0].toUpperCase()}${type.slice(1)} added: ${title}`);
|
|
1859
1888
|
}
|
|
1860
1889
|
else {
|
|
1861
1890
|
ctx.app.notify('Failed to add task');
|
|
@@ -1884,7 +1913,10 @@ Describe what this skill does. The agent reads this body verbatim when it invoke
|
|
|
1884
1913
|
const lines = [`## Tasks${projectName ? ` — ${projectName}` : ''}`, ''];
|
|
1885
1914
|
tasks.forEach((t, i) => {
|
|
1886
1915
|
const icon = TYPE_ICON[t.type] ?? '[task]';
|
|
1887
|
-
|
|
1916
|
+
// In a global listing (not scoped to one project) tag each row with its
|
|
1917
|
+
// project so a mixed list is legible — matches the macOS/web task rows.
|
|
1918
|
+
const proj = !projectName && t.project_name ? ` _(${t.project_name})_` : '';
|
|
1919
|
+
lines.push(`${i + 1}. ${icon} ${t.title}${proj}${t.description ? `\n ${t.description}` : ''}`);
|
|
1888
1920
|
});
|
|
1889
1921
|
lines.push('', `*${tasks.length} pending task${tasks.length > 1 ? 's' : ''}. Use /tasks done <n> to mark complete.*`);
|
|
1890
1922
|
lines.push('*Tasks loaded into agent context — agent will see them in the next message.*');
|
|
@@ -2034,9 +2066,12 @@ Describe what this skill does. The agent reads this body verbatim when it invoke
|
|
|
2034
2066
|
});
|
|
2035
2067
|
break;
|
|
2036
2068
|
}
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2069
|
+
// /stats — detailed session view: per-model breakdown, total, prompt-cache
|
|
2070
|
+
// summary, and the per-1M pricing reference. `/cost` is the concise sibling
|
|
2071
|
+
// (formatCostReport, above); the two are intentionally distinct, so this
|
|
2072
|
+
// case no longer also claims 'cost' (which always hit the handler above).
|
|
2073
|
+
case 'stats': {
|
|
2074
|
+
const { getCostBreakdown, getSessionStats, formatTokenCount, getPricingTable, getCacheStats } = await import('../utils/tokenTracker.js');
|
|
2040
2075
|
const stats = getSessionStats();
|
|
2041
2076
|
const lines = ['## Session Cost', ''];
|
|
2042
2077
|
if (stats.requestCount === 0) {
|
|
@@ -2064,6 +2099,19 @@ Describe what this skill does. The agent reads this body verbatim when it invoke
|
|
|
2064
2099
|
lines.push(`**Total: ~$${stats.estimatedCost.toFixed(4)}**`);
|
|
2065
2100
|
}
|
|
2066
2101
|
}
|
|
2102
|
+
// Prompt caching — parity with /cost (the 2.0.2 caching section was
|
|
2103
|
+
// only wired into formatCostReport). Shown only when caching landed.
|
|
2104
|
+
const cache = getCacheStats();
|
|
2105
|
+
if (cache.cacheReadTokens > 0 || cache.cacheCreationTokens > 0) {
|
|
2106
|
+
lines.push('', '### Prompt caching');
|
|
2107
|
+
lines.push(`Cache reads: ${formatTokenCount(cache.cacheReadTokens)} tokens (billed at 0.1× input rate)`);
|
|
2108
|
+
if (cache.cacheCreationTokens > 0) {
|
|
2109
|
+
lines.push(`Cache writes: ${formatTokenCount(cache.cacheCreationTokens)} tokens (billed at 1.25× input rate)`);
|
|
2110
|
+
}
|
|
2111
|
+
if (cache.estimatedSavingsUsd > 0) {
|
|
2112
|
+
lines.push(`Estimated savings vs no caching: $${cache.estimatedSavingsUsd.toFixed(4)}`);
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2067
2115
|
lines.push('');
|
|
2068
2116
|
}
|
|
2069
2117
|
lines.push('### Pricing (per 1M tokens)');
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "2.
|
|
1
|
+
export declare const VERSION = "2.10.0";
|
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.
|
|
4
|
+
export const VERSION = '2.10.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeep",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.10.0",
|
|
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",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"dev": "node scripts/gen-version.js && node --import tsx src/renderer/main.ts",
|
|
12
|
-
"prepack": "node scripts/gen-version.js && tsc
|
|
12
|
+
"prepack": "node scripts/gen-version.js && tsc && node scripts/fix-imports.js",
|
|
13
13
|
"build": "node scripts/gen-version.js && tsc && node scripts/fix-imports.js",
|
|
14
14
|
"start": "node dist/renderer/main.js",
|
|
15
15
|
"demo:renderer": "node --import tsx src/renderer/demo.ts",
|