codeep 2.15.0 → 2.17.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 (41) hide show
  1. package/README.md +41 -7
  2. package/dist/acp/serverHandlers.js +1 -1
  3. package/dist/acp/session.js +22 -1
  4. package/dist/config/index.js +20 -4
  5. package/dist/config/providers.d.ts +3 -2
  6. package/dist/config/providers.js +163 -69
  7. package/dist/renderer/App.d.ts +89 -0
  8. package/dist/renderer/App.js +637 -43
  9. package/dist/renderer/Screen.d.ts +1 -0
  10. package/dist/renderer/Screen.js +8 -3
  11. package/dist/renderer/commands/helpers.d.ts +189 -0
  12. package/dist/renderer/commands/helpers.js +345 -0
  13. package/dist/renderer/commands/registry.js +2 -1
  14. package/dist/renderer/commands.js +218 -267
  15. package/dist/renderer/components/AgentTimeline.d.ts +44 -0
  16. package/dist/renderer/components/AgentTimeline.js +157 -0
  17. package/dist/renderer/components/Autocomplete.d.ts +25 -0
  18. package/dist/renderer/components/Autocomplete.js +35 -0
  19. package/dist/renderer/components/Status.d.ts +2 -0
  20. package/dist/renderer/layout.d.ts +5 -1
  21. package/dist/renderer/layout.js +12 -0
  22. package/dist/renderer/main.js +110 -30
  23. package/dist/utils/agent.js +1 -1
  24. package/dist/utils/agents.d.ts +1 -1
  25. package/dist/utils/agents.js +1 -1
  26. package/dist/utils/checkpoints.d.ts +1 -1
  27. package/dist/utils/checkpoints.js +1 -1
  28. package/dist/utils/diffPreview.d.ts +31 -0
  29. package/dist/utils/diffPreview.js +102 -0
  30. package/dist/utils/git.d.ts +28 -0
  31. package/dist/utils/git.js +111 -1
  32. package/dist/utils/mentions.d.ts +195 -0
  33. package/dist/utils/mentions.js +672 -0
  34. package/dist/utils/resourceImpact.d.ts +25 -0
  35. package/dist/utils/resourceImpact.js +54 -0
  36. package/dist/utils/tokenTracker.js +52 -37
  37. package/dist/utils/webFetch.d.ts +101 -0
  38. package/dist/utils/webFetch.js +375 -0
  39. package/dist/version.d.ts +1 -1
  40. package/dist/version.js +1 -1
  41. package/package.json +2 -1
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <img src="Codeep.gif" alt="Codeep demo" width="700">
12
+ <img src="promo/sources/tui-current.png" alt="Codeep terminal UI with agent timeline, changed files, checks, and resource estimates" width="1000">
13
13
  </p>
14
14
 
15
15
  <p align="center">
@@ -23,6 +23,16 @@
23
23
  <a href="https://github.com/VladoIvankovic/Codeep"><img src="https://img.shields.io/github/stars/VladoIvankovic/Codeep?style=social" alt="GitHub stars"></a>
24
24
  </p>
25
25
 
26
+ ## One agent, every surface
27
+
28
+ Codeep keeps the same project context, provider configuration, sessions, and
29
+ agent workflow wherever you work:
30
+
31
+ - **[Terminal / TUI](https://codeep.dev/docs/installation)** — the primary CLI experience, with Plan → Read → Edit → Verify → Summary, live file changes, checks, token cost, and estimated energy and cooling-water impact.
32
+ - **[macOS app](https://codeep.dev/docs/mac)** — a native SwiftUI workbench with project conversations and Run Inspector.
33
+ - **[VS Code extension](https://github.com/VladoIvankovic/Codeep-vscode)** — the same agent over ACP, directly inside the editor. Also available on the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=VladoIvankovic.codeep).
34
+ - **[Web dashboard](https://codeep.dev/dashboard)** — synced sessions, usage, costs, tasks, and project activity.
35
+
26
36
  ## Upgrading
27
37
 
28
38
  Running `npm install -g codeep@latest` picks up the new version — config,
@@ -89,15 +99,19 @@ When started in a project directory, Codeep automatically:
89
99
  - Press Enter to send, Escape to cancel
90
100
  - Works reliably in all terminals (no Ctrl+V issues)
91
101
 
92
- ### File Context (`/add`, `/drop`)
102
+ ### File Context (`/add`, `/drop`, `@mentions`)
93
103
  Explicitly add files to the conversation context:
94
104
 
95
105
  - **`/add <path>`** - Add one or more files to context
96
106
  - **`/add`** (no args) - Show currently added files
97
107
  - **`/drop <path>`** - Remove a specific file from context
98
108
  - **`/drop`** (no args) - Remove all files from context
109
+ - **`@path/to/file`** - Inline mention: type `@` followed by a file path anywhere in your message and its contents are attached for that message only. Supports relative paths (`@src/index.ts`), absolute (`@/etc/hosts`), home (`@~/.codeep/profile.md`), and quoted paths with spaces (`@"my file.ts"`). In the CLI, typing `@` opens an autocomplete file picker — ↑↓ to navigate, Tab to insert.
110
+ - **`@folder <path>`** (alias `@dir`) - Attach an entire directory: type `@folder src/components` and every source file under it is loaded recursively. Skips `node_modules`, `.git`, `dist`, binary extensions (images, archives, lockfiles), and files over the per-file size cap. Stops at a 200 KB total cap per mention (with a notification when it hits the limit). Quoted paths supported: `@folder "my components"`.
111
+ - **`@web <url>`** - Inline web fetch: type `@web https://example.com/docs` (or `@web example.com/docs`) and the page is fetched, converted to readable text, and attached to the message. HTML is stripped; plain text and JSON pass through as-is. Capped at 32 KB, 12 s timeout. Successful fetches are cached for 30 min (per session, up to 50 entries) so repeated `@web` for the same URL is instant and free; use `/web-cache clear` to reset.
112
+ - **`@git <ref>`** - Inline git context: type `@git diff`, `@git diff --staged`, `@git HEAD`, `@git <sha>`, `@git main:src/x.ts`, or `@git diff a..b` to inject that diff / commit / file-at-ref into the message as a `[Git ref]` block. Capped at 64 KB per mention (truncated with a marker). Unknown refs surface a friendly failure note.
99
113
 
100
- Added files are automatically attached to every message (both chat and agent mode) until dropped. Useful for giving the AI specific files to work with.
114
+ Added files (via `/add`) are automatically attached to every message (both chat and agent mode) until dropped. `@mentions` are per-message — handy for one-off references without polluting the persistent context.
101
115
 
102
116
  ```
103
117
  > /add src/utils/api.ts src/types/index.ts
@@ -106,6 +120,10 @@ Added 2 file(s) to context (2 total)
106
120
  > refactor the API client to use async/await
107
121
  # AI sees both files attached to your message
108
122
 
123
+ > review @src/auth/login.ts for security issues
124
+ Loaded 1 file(s) from @mentions
125
+ # AI sees login.ts attached for this message only
126
+
109
127
  > /drop
110
128
  Dropped all 2 file(s) from context
111
129
  ```
@@ -1021,11 +1039,11 @@ After installation, `codeep` is available globally in your terminal. Simply run
1021
1039
  > /profile save fast
1022
1040
 
1023
1041
  > /provider # switch to openai
1024
- > /model gpt-4.1
1042
+ > /model gpt-5.6-sol
1025
1043
  > /profile save work
1026
1044
 
1027
1045
  > /model fast # instantly switch to z.ai / glm-5.2
1028
- > /model work # instantly switch to openai / gpt-4.1
1046
+ > /model work # instantly switch to openai / gpt-5.6-sol
1029
1047
  ```
1030
1048
 
1031
1049
  ### Session Management
@@ -1043,7 +1061,8 @@ After installation, `codeep` is available globally in your terminal. Simply run
1043
1061
 
1044
1062
  | Command | Description |
1045
1063
  |---------|-------------|
1046
- | `/apply` | Apply file changes from AI response |
1064
+ | `/apply` | Apply file changes from AI response (shows hunk counts; `--only file.ts:0,1` for selective apply, `--interactive`/`-i` for per-hunk review) |
1065
+ | `/web-cache` | Show `@web` fetch cache stats (alias `/web-cache clear` to reset) |
1047
1066
  | `/copy [n]` | Copy code block to clipboard (n = block number, -1 = last) |
1048
1067
  | `/paste` | Paste content from clipboard into chat |
1049
1068
  | `/add <path>` | Add file(s) to conversation context |
@@ -1256,6 +1275,17 @@ With write access enabled:
1256
1275
  | `GOOGLE_API_KEY` | Google AI (Gemini) API key |
1257
1276
  | `MINIMAX_API_KEY` | MiniMax (international) API key |
1258
1277
  | `MINIMAX_CN_API_KEY` | MiniMax China API key |
1278
+ | `KIMI_CODE_API_KEY` | Kimi Code subscription key |
1279
+ | `MOONSHOT_API_KEY` | Kimi international pay-per-use key |
1280
+ | `MOONSHOT_CN_API_KEY` | Kimi China pay-per-use key |
1281
+ | `XAI_API_KEY` | Grok (xAI) API key |
1282
+ | `BAILIAN_CODING_PLAN_API_KEY` | Qwen international Coding Plan key |
1283
+ | `BAILIAN_TOKEN_PLAN_API_KEY` | Qwen international Token Plan key |
1284
+ | `DASHSCOPE_API_KEY` | Qwen international pay-per-use key |
1285
+ | `BAILIAN_CODING_PLAN_CN_API_KEY` | Qwen China Coding Plan key |
1286
+ | `DASHSCOPE_CN_API_KEY` | Qwen China pay-per-use key |
1287
+ | `MODELSCOPE_API_KEY` | ModelScope token for its live model catalog |
1288
+ | `OPENROUTER_API_KEY` | OpenRouter API key |
1259
1289
 
1260
1290
  ### Settings (`/settings`)
1261
1291
 
@@ -1357,6 +1387,10 @@ Contributions are welcome! Before opening a PR, please read the
1357
1387
  how to propose a change. For provider integrations specifically, the guide
1358
1388
  walks through the files you need to touch.
1359
1389
 
1390
+ The active-product scope, model source index, replacement rules, telemetry
1391
+ contract, and recurring review checklist live in the
1392
+ [**model maintenance policy**](./docs/MODEL_MAINTENANCE.md).
1393
+
1360
1394
  Quick version: `npm install` → `npm test` → `npx tsc --noEmit` clean → open a
1361
1395
  PR against `main`. To report a security issue, see
1362
1396
  [**Security policy**](./SECURITY.md).
@@ -1464,7 +1498,7 @@ The chat sidebar now surfaces two extra ACP signals that previously only the TUI
1464
1498
  ### Editor-native actions (new in 2.2)
1465
1499
 
1466
1500
  - **Code Actions (lightbulb)** — select code and press `Ctrl+.` for **Explain**, **Improve / refactor**, **Add tests**, and **Add doc comment**. On a line with an error/warning, a **Fix this problem** quick-fix sends the diagnostic plus the code to Codeep. Everything routes through the chat, so the full agent (file edits via the diff preview, MCP tools) is available.
1467
- - **Model picker in the status bar** — click `Codeep · <model>` (or run **Codeep: Select Provider & Model**) to switch provider + model from a quick-pick. Providers with open-ended catalogs (OpenRouter, Ollama, custom endpoints) let you type a model id.
1501
+ - **Model picker in the status bar** — click `Codeep · <model>` (or run **Codeep: Select Provider & Model**) to switch provider + model from a quick-pick. Providers with open-ended catalogs (OpenRouter, ModelScope, Ollama, custom endpoints) let you type a model id.
1468
1502
  - **Self-hosted endpoints from settings** — point the extension at vLLM / LiteLLM / LM Studio / text-generation-webui with `codeep.baseUrl` (e.g. `http://localhost:8000/v1`), plus `codeep.provider` (`custom` or `openai`) and `codeep.model`. The `codeep.provider` / `codeep.model` settings are applied on every connect, so they stay authoritative.
1469
1503
  - **Get Started walkthrough** — a native VS Code walkthrough (Help → Get Started) covering CLI install, opening the chat, editor actions, and choosing a model.
1470
1504
 
@@ -224,7 +224,7 @@ export function buildProviderList() {
224
224
  // Model metadata so ACP clients (e.g. the VS Code model picker) can
225
225
  // offer a provider → model selector without hardcoding a catalog.
226
226
  // `dynamicModels` flags providers whose model list is open-ended
227
- // (OpenRouter, Ollama, custom endpoints) — clients should let the
227
+ // (OpenRouter, ModelScope, Ollama, custom endpoints) — clients should let the
228
228
  // user type a model id rather than only pick from `models`.
229
229
  models: p.models.map((m) => ({ id: m.id, name: m.name })),
230
230
  defaultModel: p.defaultModel,
@@ -87,11 +87,32 @@ export function buildRawOutput(toolName, params, toolResult) {
87
87
  }
88
88
  export async function runAgentSession(opts) {
89
89
  const projectContext = buildProjectContext(opts.workspaceRoot);
90
+ // Expand `@folder`/`@file`/`@git` mentions in the user prompt, the
91
+ // same way the TUI does (see src/renderer/main.ts). ACP clients
92
+ // (VS Code / Zed) get the same inline-context UX. `@web` is async
93
+ // and fetched here too.
94
+ let enrichedPrompt = opts.prompt;
95
+ try {
96
+ const { expandFileAndFolderMentions, expandGitMentions } = await import('../utils/mentions.js');
97
+ const { expandWebMentions } = await import('../utils/webFetch.js');
98
+ const fileResult = expandFileAndFolderMentions(enrichedPrompt, { root: opts.workspaceRoot });
99
+ const gitResult = await expandGitMentions(fileResult.enrichedPrompt, { root: opts.workspaceRoot });
100
+ const webResult = await expandWebMentions(gitResult.enrichedPrompt);
101
+ enrichedPrompt = webResult.enrichedPrompt;
102
+ // Surface failures as thoughts so the editor shows them.
103
+ const allFailures = [...fileResult.failures, ...gitResult.failures, ...webResult.failures];
104
+ if (allFailures.length > 0 && opts.onThought) {
105
+ opts.onThought(allFailures.map((f) => `${f.mention}: ${f.reason}`).join(' · '));
106
+ }
107
+ }
108
+ catch {
109
+ // Mention expansion is best-effort — never block the agent run.
110
+ }
90
111
  let toolCallCounter = 0;
91
112
  // Maps tool call key → ACP toolCallId so onToolResult can emit finished/error status
92
113
  const toolCallIdMap = new Map();
93
114
  let chunksEmitted = 0;
94
- const result = await runAgent(opts.prompt, projectContext, {
115
+ const result = await runAgent(enrichedPrompt, projectContext, {
95
116
  abortSignal: opts.abortSignal,
96
117
  onChunk: (text) => { chunksEmitted++; opts.onChunk(text); },
97
118
  onIteration: (_iteration, message) => {
@@ -2,7 +2,7 @@ import Conf from 'conf';
2
2
  import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, unlinkSync, statSync } from 'fs';
3
3
  import { join, dirname } from 'path';
4
4
  import { randomUUID } from 'crypto';
5
- import { PROVIDERS, getProvider, getProviderBaseUrl } from './providers.js';
5
+ import { PROVIDERS, getProvider, getProviderBaseUrl, replacementModelFor } from './providers.js';
6
6
  import { logSession } from '../utils/logger.js';
7
7
  import { createSecureStorage } from '../utils/keychain.js';
8
8
  // We'll initialize GLOBAL_SESSIONS_DIR after config is created (to use config.path)
@@ -255,8 +255,9 @@ if (config.get('agentMode') === 'auto') {
255
255
  // affected sliders were effectively lies). Each migration now runs exactly
256
256
  // once per config, recorded via `migrationVersion`; after that, whatever the
257
257
  // user sets sticks. Bump MIGRATION_VERSION when adding a new one.
258
- const MIGRATION_VERSION = 1;
259
- if ((config.get('migrationVersion') ?? 0) < 1) {
258
+ const MIGRATION_VERSION = 4;
259
+ const currentMigrationVersion = config.get('migrationVersion') ?? 0;
260
+ if (currentMigrationVersion < 1) {
260
261
  // Migrate the old runaway default (10000 iterations) down to a sane
261
262
  // ceiling, and old conservative defaults up to the current ones.
262
263
  if (config.get('agentMaxIterations') >= 10000) {
@@ -277,6 +278,18 @@ if ((config.get('migrationVersion') ?? 0) < 1) {
277
278
  if (config.get('rateLimitCommands') <= 100) {
278
279
  config.set('rateLimitCommands', 10000);
279
280
  }
281
+ }
282
+ if (currentMigrationVersion < 4) {
283
+ // Vendor aliases below were removed from Codeep's curated catalogue after
284
+ // their replacements became available. Migrate only exact known aliases:
285
+ // OpenRouter/Ollama/custom model ids remain user-controlled.
286
+ const provider = config.get('provider');
287
+ const model = config.get('model');
288
+ const replacement = replacementModelFor(provider, model);
289
+ if (replacement)
290
+ config.set('model', replacement);
291
+ }
292
+ if (currentMigrationVersion < MIGRATION_VERSION) {
280
293
  config.set('migrationVersion', MIGRATION_VERSION);
281
294
  }
282
295
  // Global sessions directory - use same directory as conf package for cross-platform consistency
@@ -1216,7 +1229,10 @@ export function loadProfile(name) {
1216
1229
  }
1217
1230
  export function applyProfile(profile) {
1218
1231
  config.set('provider', profile.provider);
1219
- config.set('model', profile.model);
1232
+ // A profile saved before a vendor retired a model would otherwise restore an
1233
+ // id the picker no longer offers. Normalize it exactly like the startup
1234
+ // migration does — dynamic OpenRouter/Ollama/custom ids are never rewritten.
1235
+ config.set('model', replacementModelFor(profile.provider, profile.model) ?? profile.model);
1220
1236
  config.set('protocol', profile.protocol);
1221
1237
  config.set('temperature', profile.temperature);
1222
1238
  config.set('maxTokens', profile.maxTokens);
@@ -45,6 +45,7 @@ export interface ProviderConfig {
45
45
  export declare const PROVIDERS: Record<string, ProviderConfig>;
46
46
  export type ProviderId = keyof typeof PROVIDERS;
47
47
  export declare function getProvider(id: string): ProviderConfig | null;
48
+ export declare function replacementModelFor(providerId: string, modelId: string): string | undefined;
48
49
  export declare function getProviderList(): {
49
50
  id: string;
50
51
  name: string;
@@ -133,8 +134,8 @@ export declare function availableReasoningTiers(providerId: string, model: strin
133
134
  /**
134
135
  * Map a (possibly out-of-range) tier to the tier this model actually distinguishes,
135
136
  * for display — the chip + the checked menu row. The effort setting is global, so
136
- * a tier picked on Opus ('low') may not exist on GLM-5.2; we show the level GLM
137
- * will really run (its 'low' clamps to 'high'). Picks the available tier whose
137
+ * a tier picked on Opus ('medium') may not exist on Kimi K3; we show the level
138
+ * Kimi will really run (its 'medium' clamps to 'high'). Picks the tier whose
138
139
  * effective param equals the requested one. 'auto' (or unsupported) → 'auto'.
139
140
  */
140
141
  export declare function resolveReasoningTier(providerId: string, model: string, tier: ReasoningTier): ReasoningTier;