codeep 2.15.0 → 2.16.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/README.md +12 -3
- package/dist/acp/session.js +22 -1
- package/dist/config/providers.js +20 -14
- package/dist/renderer/App.d.ts +77 -0
- package/dist/renderer/App.js +283 -3
- package/dist/renderer/commands/helpers.d.ts +188 -0
- package/dist/renderer/commands/helpers.js +342 -0
- package/dist/renderer/commands/registry.js +2 -1
- package/dist/renderer/commands.js +193 -264
- package/dist/renderer/components/Autocomplete.d.ts +25 -0
- package/dist/renderer/components/Autocomplete.js +35 -0
- package/dist/renderer/layout.d.ts +5 -1
- package/dist/renderer/layout.js +12 -0
- package/dist/renderer/main.js +34 -1
- package/dist/utils/diffPreview.d.ts +31 -0
- package/dist/utils/diffPreview.js +102 -0
- package/dist/utils/git.d.ts +28 -0
- package/dist/utils/git.js +111 -1
- package/dist/utils/mentions.d.ts +195 -0
- package/dist/utils/mentions.js +672 -0
- package/dist/utils/tokenTracker.js +9 -3
- package/dist/utils/webFetch.d.ts +101 -0
- package/dist/utils/webFetch.js +375 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -89,15 +89,19 @@ When started in a project directory, Codeep automatically:
|
|
|
89
89
|
- Press Enter to send, Escape to cancel
|
|
90
90
|
- Works reliably in all terminals (no Ctrl+V issues)
|
|
91
91
|
|
|
92
|
-
### File Context (`/add`, `/drop`)
|
|
92
|
+
### File Context (`/add`, `/drop`, `@mentions`)
|
|
93
93
|
Explicitly add files to the conversation context:
|
|
94
94
|
|
|
95
95
|
- **`/add <path>`** - Add one or more files to context
|
|
96
96
|
- **`/add`** (no args) - Show currently added files
|
|
97
97
|
- **`/drop <path>`** - Remove a specific file from context
|
|
98
98
|
- **`/drop`** (no args) - Remove all files from context
|
|
99
|
+
- **`@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.
|
|
100
|
+
- **`@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"`.
|
|
101
|
+
- **`@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.
|
|
102
|
+
- **`@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
103
|
|
|
100
|
-
Added files are automatically attached to every message (both chat and agent mode) until dropped.
|
|
104
|
+
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
105
|
|
|
102
106
|
```
|
|
103
107
|
> /add src/utils/api.ts src/types/index.ts
|
|
@@ -106,6 +110,10 @@ Added 2 file(s) to context (2 total)
|
|
|
106
110
|
> refactor the API client to use async/await
|
|
107
111
|
# AI sees both files attached to your message
|
|
108
112
|
|
|
113
|
+
> review @src/auth/login.ts for security issues
|
|
114
|
+
Loaded 1 file(s) from @mentions
|
|
115
|
+
# AI sees login.ts attached for this message only
|
|
116
|
+
|
|
109
117
|
> /drop
|
|
110
118
|
Dropped all 2 file(s) from context
|
|
111
119
|
```
|
|
@@ -1043,7 +1051,8 @@ After installation, `codeep` is available globally in your terminal. Simply run
|
|
|
1043
1051
|
|
|
1044
1052
|
| Command | Description |
|
|
1045
1053
|
|---------|-------------|
|
|
1046
|
-
| `/apply` | Apply file changes from AI response |
|
|
1054
|
+
| `/apply` | Apply file changes from AI response (shows hunk counts; `--only file.ts:0,1` for selective apply, `--interactive`/`-i` for per-hunk review) |
|
|
1055
|
+
| `/web-cache` | Show `@web` fetch cache stats (alias `/web-cache clear` to reset) |
|
|
1047
1056
|
| `/copy [n]` | Copy code block to clipboard (n = block number, -1 = last) |
|
|
1048
1057
|
| `/paste` | Paste content from clipboard into chat |
|
|
1049
1058
|
| `/add <path>` | Add file(s) to conversation context |
|
package/dist/acp/session.js
CHANGED
|
@@ -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(
|
|
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) => {
|
package/dist/config/providers.js
CHANGED
|
@@ -232,18 +232,21 @@ export const PROVIDERS = {
|
|
|
232
232
|
openai: { baseUrl: 'https://api.moonshot.ai/v1', authHeader: 'Bearer', supportsNativeTools: true },
|
|
233
233
|
},
|
|
234
234
|
models: [
|
|
235
|
-
{ id: 'kimi-
|
|
235
|
+
{ id: 'kimi-k3-code', name: 'Kimi K3 Code', description: 'Newest flagship agentic coding model (1M context, deep reasoning)' },
|
|
236
|
+
{ id: 'kimi-k3-code-highspeed', name: 'Kimi K3 Code (High-Speed)', description: 'Throughput-tuned K3 Code for latency-sensitive loops' },
|
|
237
|
+
{ id: 'kimi-k3-thinking', name: 'Kimi K3 Thinking', description: 'K3 with explicit reasoning traces (highest quality, slower)' },
|
|
238
|
+
{ id: 'kimi-k2.7-code', name: 'Kimi K2.7 Code', description: 'Previous-gen flagship agentic coding model (256K context)' },
|
|
236
239
|
{ id: 'kimi-k2.7-code-highspeed', name: 'Kimi K2.7 Code (High-Speed)', description: 'Throughput-tuned K2.7 Code for latency-sensitive loops' },
|
|
237
240
|
{ id: 'kimi-k2.6', name: 'Kimi K2.6', description: 'Previous-gen multimodal reasoning model' },
|
|
238
241
|
{ id: 'kimi-k2.5', name: 'Kimi K2.5', description: 'Older general-purpose model (cheaper)' },
|
|
239
242
|
],
|
|
240
|
-
defaultModel: 'kimi-
|
|
243
|
+
defaultModel: 'kimi-k3-code',
|
|
241
244
|
defaultProtocol: 'openai',
|
|
242
|
-
maxOutputTokens:
|
|
245
|
+
maxOutputTokens: 65_536,
|
|
243
246
|
envKey: 'MOONSHOT_API_KEY',
|
|
244
247
|
subscribeUrl: 'https://platform.kimi.ai/console/api-keys',
|
|
245
248
|
groupLabel: 'Kimi — API (pay-per-use)',
|
|
246
|
-
hint: 'Pay-per-use via Moonshot API key (platform.kimi.ai).',
|
|
249
|
+
hint: 'Pay-per-use via Moonshot API key (platform.kimi.ai). K3 models support 1M context and explicit reasoning.',
|
|
247
250
|
},
|
|
248
251
|
'kimi-cn': {
|
|
249
252
|
name: 'Kimi China (Moonshot)',
|
|
@@ -252,18 +255,21 @@ export const PROVIDERS = {
|
|
|
252
255
|
openai: { baseUrl: 'https://api.moonshot.cn/v1', authHeader: 'Bearer', supportsNativeTools: true },
|
|
253
256
|
},
|
|
254
257
|
models: [
|
|
255
|
-
{ id: 'kimi-
|
|
258
|
+
{ id: 'kimi-k3-code', name: 'Kimi K3 Code', description: 'Newest flagship agentic coding model (1M context, deep reasoning)' },
|
|
259
|
+
{ id: 'kimi-k3-code-highspeed', name: 'Kimi K3 Code (High-Speed)', description: 'Throughput-tuned K3 Code' },
|
|
260
|
+
{ id: 'kimi-k3-thinking', name: 'Kimi K3 Thinking', description: 'K3 with explicit reasoning traces' },
|
|
261
|
+
{ id: 'kimi-k2.7-code', name: 'Kimi K2.7 Code', description: 'Previous-gen flagship agentic coding model (256K context)' },
|
|
256
262
|
{ id: 'kimi-k2.7-code-highspeed', name: 'Kimi K2.7 Code (High-Speed)', description: 'Throughput-tuned K2.7 Code' },
|
|
257
263
|
{ id: 'kimi-k2.6', name: 'Kimi K2.6', description: 'Previous-gen multimodal reasoning model' },
|
|
258
264
|
{ id: 'kimi-k2.5', name: 'Kimi K2.5', description: 'Older general-purpose model' },
|
|
259
265
|
],
|
|
260
|
-
defaultModel: 'kimi-
|
|
266
|
+
defaultModel: 'kimi-k3-code',
|
|
261
267
|
defaultProtocol: 'openai',
|
|
262
|
-
maxOutputTokens:
|
|
268
|
+
maxOutputTokens: 65_536,
|
|
263
269
|
envKey: 'MOONSHOT_CN_API_KEY',
|
|
264
270
|
subscribeUrl: 'https://platform.moonshot.cn/console/api-keys',
|
|
265
271
|
groupLabel: 'Kimi China — API (pay-per-use)',
|
|
266
|
-
hint: 'Pay-per-use via Moonshot China API key (platform.moonshot.cn).',
|
|
272
|
+
hint: 'Pay-per-use via Moonshot China API key (platform.moonshot.cn). K3 models support 1M context.',
|
|
267
273
|
},
|
|
268
274
|
// ── Grok (xAI) ────────────────────────────────────────────────────
|
|
269
275
|
// Pay-per-use today (console.x.ai key). The SuperGrok / X Premium+
|
|
@@ -433,11 +439,11 @@ export const PROVIDERS = {
|
|
|
433
439
|
},
|
|
434
440
|
models: [
|
|
435
441
|
{ id: 'claude-fable-5', name: 'Claude Fable 5', description: 'Most capable — hardest reasoning & long-horizon agentic work' },
|
|
436
|
-
{ id: 'claude-opus-
|
|
442
|
+
{ id: 'claude-opus-5', name: 'Claude Opus 5', description: 'Complex agentic coding & deep reasoning — the Opus workhorse' },
|
|
437
443
|
{ id: 'claude-sonnet-5', name: 'Claude Sonnet 5', description: 'Best balance of speed and intelligence' },
|
|
438
444
|
{ id: 'claude-haiku-4-5-20251001', name: 'Claude Haiku', description: 'Fastest and most affordable' },
|
|
439
445
|
],
|
|
440
|
-
defaultModel: 'claude-opus-
|
|
446
|
+
defaultModel: 'claude-opus-5',
|
|
441
447
|
defaultProtocol: 'anthropic',
|
|
442
448
|
envKey: 'ANTHROPIC_API_KEY',
|
|
443
449
|
groupLabel: 'Anthropic',
|
|
@@ -666,8 +672,8 @@ export function providerNoStreamWithTools(providerId) {
|
|
|
666
672
|
* internally and 400 on any custom value, so they're here too.
|
|
667
673
|
*/
|
|
668
674
|
const SAMPLING_PARAMS_REJECTED = [
|
|
669
|
-
'claude-fable-5', 'claude-opus-4-8', 'claude-opus-4-7', 'claude-sonnet-5',
|
|
670
|
-
'kimi-k2.7-code', 'kimi-for-coding',
|
|
675
|
+
'claude-fable-5', 'claude-opus-5', 'claude-opus-4-8', 'claude-opus-4-7', 'claude-sonnet-5',
|
|
676
|
+
'kimi-k3-code', 'kimi-k3-thinking', 'kimi-k2.7-code', 'kimi-for-coding',
|
|
671
677
|
];
|
|
672
678
|
export function modelRejectsSamplingParams(model) {
|
|
673
679
|
return SAMPLING_PARAMS_REJECTED.some(id => model === id || model.startsWith(`${id}-`));
|
|
@@ -709,10 +715,10 @@ export function modelSupportsReasoningEffort(providerId, model) {
|
|
|
709
715
|
const id = canonicalModelId(model);
|
|
710
716
|
switch (providerId) {
|
|
711
717
|
case 'anthropic':
|
|
712
|
-
// Effort is GA on Opus 4.5+, Sonnet 4.6/5, Fable 5 — NOT Haiku or Sonnet 4.5.
|
|
718
|
+
// Effort is GA on Opus 5, Opus 4.5+, Sonnet 4.6/5, Fable 5 — NOT Haiku or Sonnet 4.5.
|
|
713
719
|
if (idMatches(id, 'claude-haiku-4-5') || idMatches(id, 'claude-sonnet-4-5'))
|
|
714
720
|
return false;
|
|
715
|
-
return /^claude-(opus-4-([5-9]|\d\d)|sonnet-(4-6|5)|fable-5)/.test(id);
|
|
721
|
+
return /^claude-(opus-5|opus-4-([5-9]|\d\d)|sonnet-(4-6|5)|fable-5)/.test(id);
|
|
716
722
|
case 'openai':
|
|
717
723
|
// GPT-5.x are reasoning models — reasoning_effort across the family (incl. mini).
|
|
718
724
|
return id.startsWith('gpt-5');
|
package/dist/renderer/App.d.ts
CHANGED
|
@@ -20,6 +20,37 @@ export interface ConfirmOptions {
|
|
|
20
20
|
onConfirm: () => void;
|
|
21
21
|
onCancel?: () => void;
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* One hunk in the interactive `/apply --interactive` picker.
|
|
25
|
+
* `lines` are already-formatted diff lines (e.g. `+ added`, `- removed`).
|
|
26
|
+
*/
|
|
27
|
+
export interface HunkPickerItem {
|
|
28
|
+
/** File path this hunk belongs to. */
|
|
29
|
+
path: string;
|
|
30
|
+
/** 0-based hunk index within the file diff. */
|
|
31
|
+
hunkIndex: number;
|
|
32
|
+
/** Human-readable hunk header, e.g. `@@ -12,3 +12,5 @@`. */
|
|
33
|
+
header: string;
|
|
34
|
+
/** Pre-formatted diff lines to display. */
|
|
35
|
+
lines: string[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Options for the interactive hunk picker. The picker walks the user
|
|
39
|
+
* through `items` one at a time; for each they accept (`y`/Enter) or
|
|
40
|
+
* skip (`n`). `a` accepts all remaining, `q`/Esc quits.
|
|
41
|
+
*
|
|
42
|
+
* `onComplete` fires once with the set of accepted `[path, hunkIndex]`
|
|
43
|
+
* pairs (possibly empty) so the caller can apply them via
|
|
44
|
+
* `applyHunksToFiles`.
|
|
45
|
+
*/
|
|
46
|
+
export interface HunkPickerOptions {
|
|
47
|
+
title: string;
|
|
48
|
+
items: HunkPickerItem[];
|
|
49
|
+
onComplete: (accepted: Array<{
|
|
50
|
+
path: string;
|
|
51
|
+
hunkIndex: number;
|
|
52
|
+
}>) => void;
|
|
53
|
+
}
|
|
23
54
|
export interface AppOptions {
|
|
24
55
|
onSubmit: (message: string) => Promise<void>;
|
|
25
56
|
onCommand: (command: string, args: string[]) => void;
|
|
@@ -29,6 +60,8 @@ export interface AppOptions {
|
|
|
29
60
|
getStatus: () => StatusInfo;
|
|
30
61
|
hasWriteAccess?: () => boolean;
|
|
31
62
|
hasProjectContext?: () => boolean;
|
|
63
|
+
/** Project root for `@mention` autocomplete suggestions. Falls back to cwd. */
|
|
64
|
+
getProjectRoot?: () => string;
|
|
32
65
|
}
|
|
33
66
|
export declare class App {
|
|
34
67
|
private screen;
|
|
@@ -67,9 +100,19 @@ export declare class App {
|
|
|
67
100
|
private showAutocomplete;
|
|
68
101
|
private autocompleteIndex;
|
|
69
102
|
private autocompleteItems;
|
|
103
|
+
private showMentionAutocomplete;
|
|
104
|
+
private mentionIndex;
|
|
105
|
+
private mentionItems;
|
|
106
|
+
private mentionAtStart;
|
|
107
|
+
/** Project root for resolving `suggestMentions`. Cached per update. */
|
|
108
|
+
private mentionRoot;
|
|
70
109
|
private confirmOpen;
|
|
71
110
|
private confirmOptions;
|
|
72
111
|
private confirmSelection;
|
|
112
|
+
private hunkPickerOpen;
|
|
113
|
+
private hunkPickerOptions;
|
|
114
|
+
private hunkPickerIndex;
|
|
115
|
+
private hunkPickerAccepted;
|
|
73
116
|
private menuOpen;
|
|
74
117
|
private menuTitle;
|
|
75
118
|
/** Filtered view shown to the user; derived from `menuItemsAll` + `menuFilter`. */
|
|
@@ -231,6 +274,11 @@ export declare class App {
|
|
|
231
274
|
* Show confirmation dialog
|
|
232
275
|
*/
|
|
233
276
|
showConfirm(options: ConfirmOptions): void;
|
|
277
|
+
/**
|
|
278
|
+
* Show the interactive hunk picker (`/apply --interactive`).
|
|
279
|
+
* The caller passes pre-built items + an `onComplete` callback.
|
|
280
|
+
*/
|
|
281
|
+
showHunkPicker(options: HunkPickerOptions): void;
|
|
234
282
|
/**
|
|
235
283
|
* Show permission dialog (inline, below status bar)
|
|
236
284
|
*/
|
|
@@ -314,6 +362,13 @@ export declare class App {
|
|
|
314
362
|
* Update autocomplete suggestions
|
|
315
363
|
*/
|
|
316
364
|
private updateAutocomplete;
|
|
365
|
+
/**
|
|
366
|
+
* Replace the in-progress `@query` (from `mentionAtStart` to the
|
|
367
|
+
* cursor) with the selected mention's path. Keeps the `@` prefix and
|
|
368
|
+
* positions the cursor right after the inserted path so the user can
|
|
369
|
+
* keep typing the rest of the message.
|
|
370
|
+
*/
|
|
371
|
+
private applyMentionSelection;
|
|
317
372
|
/**
|
|
318
373
|
* Handle inline status keys
|
|
319
374
|
*/
|
|
@@ -352,6 +407,15 @@ export declare class App {
|
|
|
352
407
|
private handleInlinePermissionKey;
|
|
353
408
|
private handleInlineSessionPickerKey;
|
|
354
409
|
private handleInlineConfirmKey;
|
|
410
|
+
/**
|
|
411
|
+
* Handle keys in the interactive hunk picker.
|
|
412
|
+
* y / Enter / → accept this hunk, advance
|
|
413
|
+
* n / ← skip this hunk, advance
|
|
414
|
+
* a accept this + all remaining, finish
|
|
415
|
+
* q / Esc finish without accepting this hunk
|
|
416
|
+
* ↑ / ↓ navigate (preview only — no decision)
|
|
417
|
+
*/
|
|
418
|
+
private handleHunkPickerKey;
|
|
355
419
|
/**
|
|
356
420
|
* Submit the current input buffer (used by Enter and Escape-in-multiline)
|
|
357
421
|
*/
|
|
@@ -373,6 +437,11 @@ export declare class App {
|
|
|
373
437
|
* Render inline confirmation dialog below status bar
|
|
374
438
|
*/
|
|
375
439
|
private renderInlineConfirm;
|
|
440
|
+
/**
|
|
441
|
+
* Render inline hunk picker (`/apply --interactive`).
|
|
442
|
+
* Shows the current hunk's diff + the y/n/a/q key legend.
|
|
443
|
+
*/
|
|
444
|
+
private renderInlineHunkPicker;
|
|
376
445
|
/**
|
|
377
446
|
* Render input line
|
|
378
447
|
*/
|
|
@@ -394,6 +463,14 @@ export declare class App {
|
|
|
394
463
|
* Render inline autocomplete below status bar
|
|
395
464
|
*/
|
|
396
465
|
private renderInlineAutocomplete;
|
|
466
|
+
/**
|
|
467
|
+
* Render inline `@mention` file picker below the status bar.
|
|
468
|
+
*
|
|
469
|
+
* Mirrors the layout of `renderInlineAutocomplete` (separator → title →
|
|
470
|
+
* items → footer) but shows file paths with their parent directory as
|
|
471
|
+
* the description, and a `@` prefix instead of `/`.
|
|
472
|
+
*/
|
|
473
|
+
private renderInlineMentionPicker;
|
|
397
474
|
/**
|
|
398
475
|
* Render inline permission dialog
|
|
399
476
|
*/
|