codeep 3.2.2 → 3.3.1

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.
@@ -183,6 +183,19 @@ export declare function initializeAsProject(path: string): boolean;
183
183
  * Check if folder was manually initialized as project
184
184
  */
185
185
  export declare function isManuallyInitializedProject(path: string): boolean;
186
+ /**
187
+ * Create config with fallback logic
188
+ * 1. Try standard Conf location (~/.config/codeep-nodejs on Linux, etc.)
189
+ * 2. If not writable, use .codeep in current working directory
190
+ */
191
+ /**
192
+ * What a fresh install starts on. Exported so a test can hold the pair to the
193
+ * catalogue: the model had stayed `glm-5.2` after Z.AI's default moved to
194
+ * `glm-5.3`, so new users started a flagship behind what the website promised,
195
+ * and nothing failed because 5.2 still works.
196
+ */
197
+ export declare const DEFAULT_PROVIDER = "z.ai";
198
+ export declare const DEFAULT_MODEL = "glm-5.3";
186
199
  export declare const config: Conf<ConfigSchema>;
187
200
  export declare const LANGUAGES: Record<string, string>;
188
201
  export declare const PROTOCOLS: Record<string, string>;
@@ -138,12 +138,20 @@ function isWritable(dir) {
138
138
  * 1. Try standard Conf location (~/.config/codeep-nodejs on Linux, etc.)
139
139
  * 2. If not writable, use .codeep in current working directory
140
140
  */
141
+ /**
142
+ * What a fresh install starts on. Exported so a test can hold the pair to the
143
+ * catalogue: the model had stayed `glm-5.2` after Z.AI's default moved to
144
+ * `glm-5.3`, so new users started a flagship behind what the website promised,
145
+ * and nothing failed because 5.2 still works.
146
+ */
147
+ export const DEFAULT_PROVIDER = 'z.ai';
148
+ export const DEFAULT_MODEL = 'glm-5.3';
141
149
  function createConfig() {
142
150
  const defaults = {
143
151
  apiKey: '',
144
152
  migrationVersion: 0,
145
- provider: 'z.ai',
146
- model: 'glm-5.2',
153
+ provider: DEFAULT_PROVIDER,
154
+ model: DEFAULT_MODEL,
147
155
  agentMode: 'on',
148
156
  ollamaUrl: 'http://localhost:11434',
149
157
  ollamaNativeApi: false,
@@ -19,7 +19,7 @@ export const PROVIDERS = {
19
19
  },
20
20
  models: [
21
21
  { id: 'glm-5.3', name: 'GLM-5.3', description: 'Latest flagship for project-scale engineering (1M context)' },
22
- { id: 'glm-5.3-flash', name: 'GLM-5.3 Flash', description: 'Same 1M context at a twentieth of the price' },
22
+ { id: 'glm-5.3-flash', name: 'GLM-5.3 Flash', description: 'Same 1M context at roughly a ninth of the price' },
23
23
  { id: 'glm-5.2', name: 'GLM-5.2', description: 'Previous flagship for project-scale engineering (1M context)' },
24
24
  { id: 'glm-5-turbo', name: 'GLM-5 Turbo', description: 'Fast GLM-5 variant, available to all users' },
25
25
  ],
@@ -53,7 +53,7 @@ export const PROVIDERS = {
53
53
  // (`z.ai-cn*`) bills separately and is not covered by that page, so it is
54
54
  // left alone until its own listing is checked.
55
55
  { id: 'glm-5.3', name: 'GLM-5.3', description: 'Latest flagship for project-scale engineering (1M context)' },
56
- { id: 'glm-5.3-flash', name: 'GLM-5.3 Flash', description: 'Same 1M context at a twentieth of the price' },
56
+ { id: 'glm-5.3-flash', name: 'GLM-5.3 Flash', description: 'Same 1M context at roughly a ninth of the price' },
57
57
  { id: 'glm-5.2', name: 'GLM-5.2', description: 'Previous flagship for project-scale engineering (1M context)' },
58
58
  { id: 'glm-5-turbo', name: 'GLM-5 Turbo', description: 'Fast GLM-5 variant' },
59
59
  ],
@@ -80,11 +80,14 @@ export const PROVIDERS = {
80
80
  supportsNativeTools: true,
81
81
  },
82
82
  },
83
+ // GLM-5.3 is on the China gateway and the China Coding Plan (bigmodel.cn).
84
+ // Flash is listed only on China pay-per-use, so the plan does not offer it.
83
85
  models: [
84
- { id: 'glm-5.2', name: 'GLM-5.2', description: 'Latest flagship for project-scale engineering (1M context)' },
86
+ { id: 'glm-5.3', name: 'GLM-5.3', description: 'Latest flagship for project-scale engineering (1M context)' },
87
+ { id: 'glm-5.2', name: 'GLM-5.2', description: 'Previous flagship for project-scale engineering (1M context)' },
85
88
  { id: 'glm-5-turbo', name: 'GLM-5 Turbo', description: 'Fast GLM-5 variant, available to all users' },
86
89
  ],
87
- defaultModel: 'glm-5.2',
90
+ defaultModel: 'glm-5.3',
88
91
  defaultProtocol: 'openai',
89
92
  maxOutputTokens: 131_072,
90
93
  envKey: 'ZAI_CN_API_KEY',
@@ -109,10 +112,12 @@ export const PROVIDERS = {
109
112
  },
110
113
  },
111
114
  models: [
112
- { id: 'glm-5.2', name: 'GLM-5.2', description: 'Latest flagship for project-scale engineering (1M context)' },
115
+ { id: 'glm-5.3', name: 'GLM-5.3', description: 'Latest flagship for project-scale engineering (1M context)' },
116
+ { id: 'glm-5.3-flash', name: 'GLM-5.3 Flash', description: 'Same 1M context at a tenth of the price' },
117
+ { id: 'glm-5.2', name: 'GLM-5.2', description: 'Previous flagship for project-scale engineering (1M context)' },
113
118
  { id: 'glm-5-turbo', name: 'GLM-5 Turbo', description: 'Fast GLM-5 variant' },
114
119
  ],
115
- defaultModel: 'glm-5.2',
120
+ defaultModel: 'glm-5.3',
116
121
  defaultProtocol: 'openai',
117
122
  maxOutputTokens: 131_072,
118
123
  envKey: 'ZAI_CN_API_KEY',
@@ -207,11 +212,19 @@ export const PROVIDERS = {
207
212
  supportsNativeTools: true,
208
213
  },
209
214
  },
215
+ // One model. DeepSeek's own pricing page names `deepseek-flash` (V4.1 Flash)
216
+ // as the model to use and says it outperforms V4 Pro. `deepseek-v4-flash`
217
+ // is already served by it, and from 2026-09-14 12:00 Beijing time every
218
+ // `deepseek-v4-pro` request is routed to it and billed at its price until
219
+ // a V4.1 Pro exists — so a Pro entry would be a label on a different model.
220
+ // Both old ids migrate via RETIRED_MODEL_REPLACEMENTS.
221
+ //
222
+ // Note the id differs on OpenRouter, which lists the same model as
223
+ // `deepseek/deepseek-v4.1-flash`.
210
224
  models: [
211
- { id: 'deepseek-v4-pro', name: 'DeepSeek V4 Pro', description: 'Most capable DeepSeek model (1M context, thinking mode)' },
212
- { id: 'deepseek-v4-flash', name: 'DeepSeek V4 Flash', description: 'Fast and affordable DeepSeek model (1M context)' },
225
+ { id: 'deepseek-flash', name: 'DeepSeek V4.1 Flash', description: 'Current DeepSeek model — thinking on by default, vision, 1M context, 384K output' },
213
226
  ],
214
- defaultModel: 'deepseek-v4-pro',
227
+ defaultModel: 'deepseek-flash',
215
228
  defaultProtocol: 'openai',
216
229
  maxOutputTokens: 384_000, // DeepSeek V4 max output
217
230
  envKey: 'DEEPSEEK_API_KEY',
@@ -344,12 +357,17 @@ export const PROVIDERS = {
344
357
  protocols: {
345
358
  openai: { baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1', authHeader: 'Bearer', supportsNativeTools: true },
346
359
  },
360
+ // 3.8 Max and Flash are GA on Model Studio international and cost less
361
+ // than the 3.7 Max / 3.6 Flash they sit above. China (`qwen-cn-api`) is a
362
+ // separate listing and is not changed on this evidence.
347
363
  models: [
348
- { id: 'qwen3.7-max', name: 'Qwen3.7-Max', description: 'Latest flagship for complex coding and reasoning' },
364
+ { id: 'qwen3.8-max', name: 'Qwen3.8-Max', description: 'Latest flagship for complex coding and reasoning (1M context)' },
365
+ { id: 'qwen3.8-flash', name: 'Qwen3.8-Flash', description: 'Low-latency, low-cost multimodal model (1M context)' },
366
+ { id: 'qwen3.7-max', name: 'Qwen3.7-Max', description: 'Previous flagship for complex coding and reasoning' },
349
367
  { id: 'qwen3.7-plus', name: 'Qwen3.7-Plus', description: 'Balanced quality, speed, and price (1M context)' },
350
- { id: 'qwen3.6-flash', name: 'Qwen3.6-Flash', description: 'Low-latency, low-cost multimodal model' },
368
+ { id: 'qwen3.6-flash', name: 'Qwen3.6-Flash', description: 'Previous low-latency, low-cost multimodal model' },
351
369
  ],
352
- defaultModel: 'qwen3.7-max',
370
+ defaultModel: 'qwen3.8-max',
353
371
  defaultProtocol: 'openai',
354
372
  maxOutputTokens: 65_536,
355
373
  noStreamWithTools: true,
@@ -535,12 +553,17 @@ export const PROVIDERS = {
535
553
  { id: 'anthropic/claude-fable-5', name: 'Claude Fable 5', description: 'Anthropic — superseded by 5.1' },
536
554
  { id: 'anthropic/claude-opus-5', name: 'Claude Opus 5', description: 'Anthropic — flagship Opus tier' },
537
555
  { id: 'anthropic/claude-sonnet-5', name: 'Claude Sonnet 5', description: 'Anthropic — balanced' },
556
+ { id: 'openai/gpt-6-astra', name: 'GPT-6 Astra', description: 'OpenAI — frontier' },
538
557
  { id: 'openai/gpt-5.6-sol', name: 'GPT-5.6 Sol', description: 'OpenAI — flagship' },
539
558
  { id: 'openai/gpt-5.6-luna', name: 'GPT-5.6 Luna', description: 'OpenAI — fast/efficient' },
540
- { id: 'google/gemini-3.7-flash', name: 'Gemini 3.7 Flash', description: 'Google — latest production Flash' },
541
- { id: 'deepseek/deepseek-v4-pro', name: 'DeepSeek V4 Pro', description: 'DeepSeek — flagship agentic model' },
559
+ { id: 'google/gemini-3.8-flash', name: 'Gemini 3.8 Flash', description: 'Google — latest production Flash' },
560
+ { id: 'google/gemini-3.7-flash', name: 'Gemini 3.7 Flash', description: 'Google — previous production Flash' },
561
+ { id: 'deepseek/deepseek-v4.1-flash', name: 'DeepSeek V4.1 Flash', description: 'DeepSeek — current model' },
542
562
  { id: 'moonshotai/kimi-k3', name: 'Kimi K3', description: 'Moonshot — long-horizon coding' },
543
- { id: 'qwen/qwen3.8-max', name: 'Qwen 3.8 Max', description: 'Alibaba — latest flagship' },
563
+ // Dated on purpose: OpenRouter lists only the snapshot. The undated
564
+ // `qwen/qwen3.8-max` this used to carry does not exist there, so picking
565
+ // it before the live catalogue loaded was an error.
566
+ { id: 'qwen/qwen3.8-max-0902', name: 'Qwen 3.8 Max', description: 'Alibaba — latest flagship' },
544
567
  { id: 'x-ai/grok-4.6', name: 'Grok 4.6', description: 'xAI — flagship reasoning' },
545
568
  ],
546
569
  defaultModel: 'openrouter/auto',
@@ -607,6 +630,13 @@ const RETIRED_MODEL_REPLACEMENTS = {
607
630
  google: {
608
631
  'gemini-3.1-flash-lite': 'gemini-3.5-flash-lite',
609
632
  },
633
+ // DeepSeek named V4.1 Flash the model to use: the V4 Flash ids are retired
634
+ // and served by it, and V4 Pro is routed to it from 2026-09-14.
635
+ deepseek: {
636
+ 'deepseek-v4-flash': 'deepseek-flash',
637
+ 'deepseek-v4-flash-vision-exp': 'deepseek-flash',
638
+ 'deepseek-v4-pro': 'deepseek-flash',
639
+ },
610
640
  grok: {
611
641
  'grok-code-fast-1': 'grok-build-0.1',
612
642
  'grok-4-fast-reasoning': 'grok-4.3',
@@ -848,7 +878,10 @@ export function modelSupportsReasoningEffort(providerId, model) {
848
878
  // Gemini 3.x thinking_level via the OpenAI-compat reasoning_effort mapping.
849
879
  return id.startsWith('gemini-3');
850
880
  case 'deepseek':
851
- return id.startsWith('deepseek-v4');
881
+ // `deepseek-flash` does not start with `deepseek-v4` — a prefix check
882
+ // alone would ship the current model with /thinking hidden, the same
883
+ // trap GPT-6 nearly fell into behind `gpt-5`.
884
+ return id.startsWith('deepseek-v4') || idMatches(id, 'deepseek-flash');
852
885
  case 'z.ai':
853
886
  case 'z.ai-api':
854
887
  case 'z.ai-cn':
@@ -908,7 +941,12 @@ export function reasoningParamsFor(providerId, model, tier) {
908
941
  // 'minimal' is deliberately not emitted: 3.7 Flash rejects it outright.
909
942
  return { reasoning_effort: tier === 'max' ? 'high' : tier };
910
943
  case 'deepseek':
911
- // Graded thinking depth: high (default) or max. Lower tiers collapse to high.
944
+ // V4.1 Flash distinguishes low / high / max (DeepSeek's mapping table:
945
+ // minimal+low→low, medium+high+xhigh→high, max+ultra→max). The retired V4
946
+ // ids graded only high|max. Always an effort, never a disabled block.
947
+ if (idMatches(canonicalModelId(model), 'deepseek-flash')) {
948
+ return { reasoning_effort: tier === 'low' ? 'low' : tier === 'max' ? 'max' : 'high' };
949
+ }
912
950
  return { reasoning_effort: tier === 'max' ? 'max' : 'high' };
913
951
  case 'z.ai':
914
952
  case 'z.ai-api':
@@ -959,7 +997,9 @@ export function availableReasoningTiers(providerId, model) {
959
997
  // coding, so collapsing it hid the setting most users want.
960
998
  return ['auto', 'low', 'medium', 'high'];
961
999
  case 'deepseek':
962
- return ['auto', 'high', 'max'];
1000
+ return idMatches(canonicalModelId(model), 'deepseek-flash')
1001
+ ? ['auto', 'low', 'high', 'max']
1002
+ : ['auto', 'high', 'max'];
963
1003
  case 'z.ai':
964
1004
  case 'z.ai-api':
965
1005
  case 'z.ai-cn':
@@ -1,11 +1,24 @@
1
1
  /**
2
- * Single source of truth for Codeep slash commands.
2
+ * Single source of truth for Codeep's TUI slash commands.
3
3
  *
4
- * Every other place that needs command metadata — the `/` autocomplete in
5
- * `App.ts`, the `/help` screen in `components/Help.ts`, the dispatcher in
6
- * `commands.ts`, and the ACP command handler in `acp/commands.ts` — derives
7
- * from this registry. Adding a command means adding one entry here; the
8
- * autocomplete list, help screen, and command index all pick it up.
4
+ * The `/` autocomplete in `App.ts` and alias resolution in the dispatcher
5
+ * (`commands.ts`) derive from this registry. Adding a command means:
6
+ *
7
+ * 1. an entry in `COMMANDS` below;
8
+ * 2. a handler — a `case` in `renderer/commands.ts`, a `case` in `App.ts`, or
9
+ * a built-in skill of the same name;
10
+ * 3. a row in `HELP_LAYOUT` at the bottom of this file;
11
+ * 4. `npm run export:commands`, which regenerates the website's command
12
+ * reference (`Codeep-web/src/data/commands.json`) from this file.
13
+ *
14
+ * `registry.test.ts` fails if 2 or 3 is missed: a command offered in the
15
+ * autocomplete with no handler answers "Unknown command" (this is how
16
+ * `/account` shipped broken), and one missing from `HELP_LAYOUT` is invisible
17
+ * in `/help` and on the website.
18
+ *
19
+ * The ACP server (VS Code, Zed) is NOT derived from here: it keeps its own
20
+ * `AVAILABLE_COMMANDS` list in `acp/server.ts` and resolves its own aliases,
21
+ * so a command added here is not automatically offered to editors.
9
22
  *
10
23
  * ## What lives here vs. elsewhere
11
24
  *
@@ -76,7 +89,11 @@ export declare const ALL_ALIASES: ReadonlySet<string>;
76
89
  export interface HelpItemSpec {
77
90
  /** Visible key in `/help`, including the leading `/`. */
78
91
  key: string;
92
+ /** One line, sized for the terminal. */
79
93
  description: string;
94
+ /** Longer explanation used on the website's command reference instead of
95
+ * `description`, where a terminal row is too short to say what matters. */
96
+ web?: string;
80
97
  }
81
98
  export interface HelpCategorySpec {
82
99
  title: string;
@@ -1,11 +1,24 @@
1
1
  /**
2
- * Single source of truth for Codeep slash commands.
2
+ * Single source of truth for Codeep's TUI slash commands.
3
3
  *
4
- * Every other place that needs command metadata — the `/` autocomplete in
5
- * `App.ts`, the `/help` screen in `components/Help.ts`, the dispatcher in
6
- * `commands.ts`, and the ACP command handler in `acp/commands.ts` — derives
7
- * from this registry. Adding a command means adding one entry here; the
8
- * autocomplete list, help screen, and command index all pick it up.
4
+ * The `/` autocomplete in `App.ts` and alias resolution in the dispatcher
5
+ * (`commands.ts`) derive from this registry. Adding a command means:
6
+ *
7
+ * 1. an entry in `COMMANDS` below;
8
+ * 2. a handler — a `case` in `renderer/commands.ts`, a `case` in `App.ts`, or
9
+ * a built-in skill of the same name;
10
+ * 3. a row in `HELP_LAYOUT` at the bottom of this file;
11
+ * 4. `npm run export:commands`, which regenerates the website's command
12
+ * reference (`Codeep-web/src/data/commands.json`) from this file.
13
+ *
14
+ * `registry.test.ts` fails if 2 or 3 is missed: a command offered in the
15
+ * autocomplete with no handler answers "Unknown command" (this is how
16
+ * `/account` shipped broken), and one missing from `HELP_LAYOUT` is invisible
17
+ * in `/help` and on the website.
18
+ *
19
+ * The ACP server (VS Code, Zed) is NOT derived from here: it keeps its own
20
+ * `AVAILABLE_COMMANDS` list in `acp/server.ts` and resolves its own aliases,
21
+ * so a command added here is not automatically offered to editors.
9
22
  *
10
23
  * ## What lives here vs. elsewhere
11
24
  *
@@ -67,13 +80,12 @@ export const COMMANDS = [
67
80
  { name: 'settings', description: 'Open settings', category: 'general' },
68
81
  { name: 'version', description: 'Show version', category: 'general' },
69
82
  { name: 'update', description: 'Check for updates', category: 'general' },
70
- {
71
- name: 'cost',
72
- aliases: ['stats'],
73
- description: 'Token usage & cost this session',
74
- category: 'general',
75
- aliasListed: true,
76
- },
83
+ { name: 'cost', description: 'Token usage & cost this session', category: 'general' },
84
+ // Its own command, not an alias of /cost. From 2026-06-24 it was
85
+ // `aliases: ['stats']` on /cost, and the dispatcher resolves aliases before
86
+ // the switch — so /stats printed the /cost report and its own handler (per-
87
+ // model breakdown, cache summary, pricing table) never ran.
88
+ { name: 'stats', description: 'Detailed session view — per-model breakdown, cache, and pricing table', category: 'general' },
77
89
  { name: 'clear', description: 'Clear chat', category: 'general', hidden: true },
78
90
  { name: 'exit', description: 'Quit application', category: 'general', hidden: true },
79
91
  // ── sessions ───────────────────────────────────────────────────────────────
@@ -220,7 +232,7 @@ export const COMMANDS = [
220
232
  { name: 'commands', description: 'List custom slash commands in .codeep/commands/*.md', category: 'extensions' },
221
233
  { name: 'web-cache', aliases: ['webcache'], description: 'Show @web fetch cache stats (alias: /web-cache clear)', category: 'extensions' },
222
234
  // ── cloud & account ────────────────────────────────────────────────────────
223
- { name: 'account', description: 'Link this machine to your codeep.dev account', category: 'cloud' },
235
+ { name: 'account', description: 'Show whether this machine is linked to codeep.dev, and how to link it', category: 'cloud' },
224
236
  { name: 'tasks', description: 'List/add/done/delete codeep.dev tasks', category: 'cloud', usage: ['add <title> [--bug|--feature]'] },
225
237
  { name: 'sync', description: 'Sync learning preferences and profiles to codeep.dev', category: 'cloud' },
226
238
  { name: 'telemetry', description: 'Show or toggle automatic cloud telemetry (on/off)', category: 'cloud' },
@@ -229,7 +241,11 @@ export const COMMANDS = [
229
241
  { name: 'context-save', description: 'Save conversation', category: 'cloud', hidden: true },
230
242
  { name: 'context-load', description: 'Load conversation', category: 'cloud', hidden: true },
231
243
  { name: 'context-clear', description: 'Clear saved context', category: 'cloud', hidden: true },
232
- { name: 'save', description: 'Save current session', category: 'cloud', hidden: true },
244
+ // ACP-only. acp/commands.ts handles /save (an editor has no autosave); the TUI
245
+ // saves sessions on its own and has no handler, so this stays hidden — offering
246
+ // it in the terminal would only answer "Unknown command". Registered because
247
+ // registry.test.ts requires every ACP case label to be.
248
+ { name: 'save', description: 'Save current session (VS Code / Zed only)', category: 'cloud', hidden: true },
233
249
  // ── code generation ────────────────────────────────────────────────────────
234
250
  { name: 'build', description: 'Build the project', category: 'codegen' },
235
251
  { name: 'deploy', description: 'Build and deploy', category: 'codegen' },
@@ -333,7 +349,10 @@ export const HELP_LAYOUT = [
333
349
  { key: '/settings', description: 'Open settings' },
334
350
  { key: '/version', description: 'Show version' },
335
351
  { key: '/update', description: 'Check for updates' },
336
- { key: '/stats (/cost)', description: 'Token usage & cost this session' },
352
+ { key: '/cost', description: 'Token usage & cost this session',
353
+ web: 'Token usage and estimated cost this session, per provider and model, with prompt-cache savings' },
354
+ { key: '/stats', description: 'Detailed view — per-model breakdown, cache, pricing table',
355
+ web: 'Detailed session view — per-model breakdown, plan-aware totals, prompt-cache reads and writes, and the per-1M pricing table' },
337
356
  { key: '/clear', description: 'Clear chat' },
338
357
  { key: '/exit', description: 'Quit application' },
339
358
  ],
@@ -345,11 +364,15 @@ export const HELP_LAYOUT = [
345
364
  { key: '/new', description: 'Start new session' },
346
365
  { key: '/rename <name>', description: 'Rename current session' },
347
366
  { key: '/search <term>', description: 'Search the current session' },
348
- { key: '/recall <query>', description: 'Search across ALL saved sessions (cross-session)' },
349
- { key: '/recall … --resume', description: 'Load the top-matching session directly' },
367
+ { key: '/recall <query>', description: 'Search across ALL saved sessions (cross-session)',
368
+ web: 'Search across all saved sessions, ranked by relevance and recency' },
369
+ { key: '/recall … --resume', description: 'Load the top-matching session directly',
370
+ web: 'Load the top-matching session directly, skipping the picker' },
350
371
  { key: '/recall … --summarize', description: 'LLM recap of what you did across matches' },
372
+ { key: '/cloud', description: 'List and resume sessions synced from other devices' },
351
373
  { key: '/export [md|json|txt]', description: 'Export chat' },
352
- { key: '/compact [keepN]', description: 'AI-summarize older messages to free up context (keeps last N)' },
374
+ { key: '/compact [keepN]', description: 'AI-summarize older messages to free up context (keeps last N)',
375
+ web: 'AI-summarize older messages to free up context, keeping the last N (default 4)' },
353
376
  ],
354
377
  },
355
378
  {
@@ -357,7 +380,8 @@ export const HELP_LAYOUT = [
357
380
  items: [
358
381
  { key: '/checkpoint [name]', description: 'Snapshot conversation + provider/model + git HEAD' },
359
382
  { key: '/checkpoints', description: 'List saved checkpoints in this workspace' },
360
- { key: '/rewind <id>', description: 'Restore conversation from a checkpoint' },
383
+ { key: '/rewind <id>', description: 'Restore conversation from a checkpoint',
384
+ web: 'Restore a checkpoint — conversation and provider/model; files roll back via the git command printed afterwards' },
361
385
  { key: '/checkpoint delete <id>', description: 'Delete a saved checkpoint' },
362
386
  ],
363
387
  },
@@ -387,6 +411,9 @@ export const HELP_LAYOUT = [
387
411
  { key: '/amend', description: 'Amend last commit' },
388
412
  { key: '/branch', description: 'Create/manage branches' },
389
413
  { key: '/stash', description: 'Stash changes' },
414
+ { key: '/unstash', description: 'Apply and drop the most recent stash' },
415
+ { key: '/pr', description: 'Create a pull request description' },
416
+ { key: '/changelog', description: 'Generate changelog from recent commits' },
390
417
  { key: '/init', description: 'Initialize project (.codeep/ folder)' },
391
418
  { key: '/scan', description: 'Scan project structure' },
392
419
  { key: '/memory <note>', description: 'Add note to project intelligence' },
@@ -414,19 +441,58 @@ export const HELP_LAYOUT = [
414
441
  title: 'Skills (Shortcuts)',
415
442
  items: [
416
443
  { key: '/test (/t)', description: 'Generate/run tests' },
444
+ { key: '/test-fix', description: 'Fix failing tests' },
445
+ { key: '/coverage', description: 'Run/analyze test coverage' },
446
+ { key: '/e2e', description: 'Generate end-to-end tests' },
447
+ { key: '/mock', description: 'Generate mock data for testing' },
417
448
  { key: '/docs (/d)', description: 'Open web docs for a command' },
449
+ { key: '/readme', description: 'Generate or update README' },
450
+ { key: '/api-docs', description: 'Generate API documentation' },
418
451
  { key: '/refactor (/r)', description: 'Improve code quality' },
419
452
  { key: '/fix (/f)', description: 'Debug and fix issues' },
420
453
  { key: '/explain (/e)', description: 'Explain code' },
421
454
  { key: '/optimize (/o)', description: 'Optimize performance' },
422
455
  { key: '/debug (/b)', description: 'Debug problems' },
423
456
  { key: '/security', description: 'Security audit (SQLi, XSS, secrets, auth)' },
424
- { key: '/coverage', description: 'Run/analyze test coverage' },
457
+ { key: '/types', description: 'Add or improve TypeScript types' },
458
+ { key: '/cleanup', description: 'Clean up code (remove unused, format)' },
459
+ { key: '/modernize', description: 'Update code to use modern syntax' },
460
+ { key: '/migrate', description: 'Migrate code to newer version' },
461
+ { key: '/split', description: 'Split a large file into smaller modules' },
462
+ { key: '/log', description: 'Add logging to code' },
463
+ { key: '/translate', description: 'Translate code comments to English' },
464
+ { key: '/skills', description: 'List all skills' },
465
+ { key: '/skills <query>', description: 'Search skills by keyword' },
466
+ { key: '/skills bundles', description: 'List skill bundles (project + global)' },
467
+ { key: '/skills create-bundle <name>', description: 'Scaffold a bundle in .codeep/skills/' },
468
+ { key: '/skills show <name>', description: "Print a bundle's SKILL.md" },
469
+ { key: '/skills browse [query]', description: 'Search the marketplace at codeep.dev/skills' },
470
+ { key: '/skills install <owner>/<slug>', description: 'Install a marketplace bundle into the project' },
471
+ { key: '/skills publish <name> [--public]', description: 'Share a bundle to codeep.dev' },
472
+ { key: '/skills unpublish <owner>/<slug>', description: 'Remove a bundle you published' },
473
+ ],
474
+ },
475
+ {
476
+ title: 'Code Generation',
477
+ items: [
425
478
  { key: '/component <name>', description: 'Generate UI component' },
426
479
  { key: '/api <name>', description: 'Generate API endpoint' },
480
+ { key: '/hook', description: 'Generate a React hook' },
481
+ { key: '/service', description: 'Generate a service/utility module' },
482
+ { key: '/page', description: 'Generate a new page/route' },
483
+ { key: '/form', description: 'Generate a form with validation' },
484
+ { key: '/crud', description: 'Generate full CRUD for an entity' },
427
485
  { key: '/docker', description: 'Generate Dockerfile + compose' },
428
- { key: '/skills', description: 'List all 50+ skills' },
429
- { key: '/skills <query>', description: 'Search skills by keyword' },
486
+ { key: '/ci', description: 'Generate CI/CD configuration' },
487
+ { key: '/env', description: 'Setup environment configuration' },
488
+ { key: '/k8s', description: 'Generate Kubernetes manifests' },
489
+ { key: '/terraform', description: 'Generate Terraform configuration' },
490
+ { key: '/nginx', description: 'Generate Nginx configuration' },
491
+ { key: '/monitor', description: 'Add monitoring and observability' },
492
+ { key: '/build', description: 'Build the project' },
493
+ { key: '/deploy', description: 'Build and deploy' },
494
+ { key: '/release', description: 'Create a new release' },
495
+ { key: '/publish', description: 'Publish package to npm' },
430
496
  ],
431
497
  },
432
498
  {
@@ -441,16 +507,33 @@ export const HELP_LAYOUT = [
441
507
  { key: '/login', description: 'Login with API key' },
442
508
  { key: '/logout', description: 'Logout from provider' },
443
509
  { key: '/profile save <name>', description: 'Save current provider+model as profile' },
510
+ { key: '/profile load <name>', description: 'Load a saved profile' },
444
511
  { key: '/profile list', description: 'List saved profiles' },
445
- { key: '/openrouter', description: 'OpenRouter routing prefs (prefer/ignore providers, fallbacks, privacy)' },
512
+ { key: '/profile delete <name>', description: 'Delete a saved profile' },
513
+ { key: '/openrouter', description: 'OpenRouter routing prefs (prefer/ignore providers, fallbacks, privacy)',
514
+ web: 'OpenRouter routing preferences: show, prefer or ignore upstream providers, fallbacks on/off, privacy strict/allow, clear' },
446
515
  { key: '/personality', description: 'List personalities and custom bots with model, tools, and scope' },
447
516
  { key: '/personality <name>', description: 'Activate a personality or custom bot. /personality off to clear.' },
448
- { key: '/me', description: 'Your user profile (reply language, style, stack) — adapts the agent to you' },
517
+ { key: '/me', description: 'Your user profile (reply language, style, stack) — adapts the agent to you',
518
+ web: 'Your user profile — reply language, style, stack — injected into every run on every surface' },
449
519
  { key: '/me init [project]', description: 'Scaffold a profile template (global, or for this project). /me off to disable' },
450
520
  { key: '/me learn [on|off]', description: 'Learn durable prefs from this session now; on/off toggles auto-learn. /me forget clears it' },
451
521
  { key: '/me sync', description: 'Push your profile to the codeep.dev dashboard (and pull on a fresh machine)' },
452
- { key: '/agents', description: 'List sub-agents the agent can delegate to (researcher / reviewer / tester / your own)' },
522
+ { key: '/agents', description: 'List sub-agents the agent can delegate to (researcher / reviewer / tester / your own)',
523
+ web: 'List the sub-agents the agent can delegate to — planner, researcher, reviewer, tester, or your own in .codeep/agents/' },
453
524
  { key: '/insights [--days N]', description: 'Activity summary — runs, files, tools, projects over the last N days (default 7)' },
525
+ { key: '/telegram', description: 'Set up answering confirmations on your phone' },
526
+ { key: '/telegram on|off', description: 'Turn Telegram approvals on or off' },
527
+ { key: '/audit', description: 'What agents did here — runs, tools, and what the boundary refused' },
528
+ { key: '/audit on|off', description: 'Turn the project audit record on or off' },
529
+ ],
530
+ },
531
+ {
532
+ title: 'Thinking',
533
+ items: [
534
+ { key: '/thinking (/effort)', description: 'Show the thinking tier and what this model supports' },
535
+ { key: '/thinking <auto|low|medium|high|max>', description: 'Set how hard the model reasons',
536
+ web: "Set the reasoning-effort tier. Auto uses each model's own default; other tiers are clamped to the levels the current provider and model actually distinguish, so an unsupported value is never sent. Models with no graded control ignore it." },
454
537
  ],
455
538
  },
456
539
  {
@@ -468,6 +551,25 @@ export const HELP_LAYOUT = [
468
551
  { key: '/mcp prompt <server> <name>', description: 'Materialize a prompt with arguments (key=value)' },
469
552
  { key: '/hooks', description: 'List installed lifecycle hooks (.codeep/hooks/<event>.sh)' },
470
553
  { key: '/commands', description: 'List custom slash commands (.codeep/commands/*.md)' },
554
+ { key: '/web-cache', description: 'Show @web fetch cache stats' },
555
+ { key: '/web-cache clear', description: 'Clear the @web fetch cache' },
556
+ ],
557
+ },
558
+ {
559
+ title: 'Cloud & Account',
560
+ items: [
561
+ { key: '/account', description: 'Is this machine linked to codeep.dev? How to link it',
562
+ web: 'Show whether this machine is linked to codeep.dev. Linking runs in your shell as `codeep account`, and the approval link it prints can be opened on any device where you are already signed in' },
563
+ { key: '/tasks', description: 'List codeep.dev tasks' },
564
+ { key: '/tasks add <title> [--bug|--feature] [--desc <text>]', description: 'Create a task on the dashboard' },
565
+ { key: '/tasks done <n>', description: 'Mark task #n as done' },
566
+ { key: '/tasks delete <n>', description: 'Delete task #n' },
567
+ { key: '/sync', description: 'Sync learning preferences and profiles to codeep.dev' },
568
+ { key: '/sync learning', description: 'Sync only learning preferences' },
569
+ { key: '/sync profiles', description: 'Sync only saved profiles' },
570
+ { key: '/telemetry [on|off]', description: 'Show or toggle automatic cloud telemetry' },
571
+ { key: '/keysync [on|off]', description: 'Show or toggle syncing API keys to codeep.dev',
572
+ web: 'Show or toggle syncing API keys to codeep.dev. Off by default — keys stay in your OS keychain unless you opt in' },
471
573
  ],
472
574
  },
473
575
  {
@@ -288,7 +288,6 @@ export async function handleCommand(command, args, ctx) {
288
288
  }
289
289
  break;
290
290
  }
291
- case 'effort':
292
291
  case 'thinking': {
293
292
  const providerId = config.get('provider');
294
293
  const model = config.get('model');
@@ -302,7 +301,7 @@ export async function handleCommand(command, args, ctx) {
302
301
  ctx.app.notify('Thinking effort: auto — each model uses its own default.');
303
302
  }
304
303
  else if (!supported) {
305
- ctx.app.notify(`Thinking effort set to "${sub}", but ${model} has no graded thinking control — it will be ignored until you switch to a model that does (e.g. Opus 5, GPT-5.x, Gemini 3, DeepSeek V4, Kimi K3).`);
304
+ ctx.app.notify(`Thinking effort set to "${sub}", but ${model} has no graded thinking control — it will be ignored until you switch to a model that does (e.g. Opus 5, GPT-5.x or GPT-6, Gemini 3, DeepSeek V4.1 Flash, GLM-5.x, Kimi K3).`);
306
305
  }
307
306
  else {
308
307
  // Tell the user what THIS model will actually run (the tier may
@@ -377,7 +376,6 @@ export async function handleCommand(command, args, ctx) {
377
376
  runAgentTask(args.join(' '), true, ctx, () => null, () => { });
378
377
  break;
379
378
  }
380
- case 'd':
381
379
  case 'docs': {
382
380
  // Open per-command web docs in the system browser. Lets the inline
383
381
  // /help stay terse (single-line entries) while users who want the
@@ -1771,21 +1769,13 @@ Format: use headers per category, only include categories where you found issues
1771
1769
  break;
1772
1770
  }
1773
1771
  // Built-in skill shortcuts
1774
- case 'c':
1775
1772
  case 'commit':
1776
- case 't':
1777
1773
  case 'test':
1778
- case 'r':
1779
1774
  case 'refactor':
1780
- case 'f':
1781
1775
  case 'fix':
1782
- case 'e':
1783
1776
  case 'explain':
1784
- case 'o':
1785
1777
  case 'optimize':
1786
- case 'b':
1787
1778
  case 'debug':
1788
- case 'p':
1789
1779
  case 'push':
1790
1780
  case 'pull':
1791
1781
  case 'amend':
@@ -2025,6 +2015,23 @@ Describe what this skill does. The agent reads this body verbatim when it invoke
2025
2015
  });
2026
2016
  break;
2027
2017
  }
2018
+ case 'account': {
2019
+ // Linking cannot run here: `codeep account` prints to stdout and exits the
2020
+ // process when it finishes, which would tear down the TUI. Before this
2021
+ // case existed the autocomplete offered /account and it answered
2022
+ // "Unknown command" — so this says where the flow runs, and what state
2023
+ // the machine is in now.
2024
+ const { getSyncToken, getGithubId } = await import('../config/index.js');
2025
+ const linked = Boolean(getSyncToken());
2026
+ const githubId = getGithubId();
2027
+ ctx.app.addMessage({
2028
+ role: 'system',
2029
+ content: linked
2030
+ ? `## codeep.dev account\n\nThis machine is **linked**${githubId ? ` (GitHub id ${githubId})` : ''}. Usage and sessions sync to your dashboard.\n\nTo cut it off, use **Settings → Connected devices** on codeep.dev.`
2031
+ : `## codeep.dev account\n\nThis machine is **not linked**.\n\nQuit Codeep and run this in your shell:\n\n\`\`\`bash\ncodeep account\n\`\`\`\n\nIt prints a one-time approval link. You can open it on **any** device where you are already signed in to codeep.dev — it does not have to be this machine, so there is no need to sign in to GitHub here.`,
2032
+ });
2033
+ break;
2034
+ }
2028
2035
  case 'tasks': {
2029
2036
  const { fetchTasks, markTaskDone, generateProjectId } = await import('../utils/codeepCloud.js');
2030
2037
  const { setTaskContext, clearTaskContext } = await import('../utils/taskContext.js');
@@ -30,6 +30,7 @@ const MODEL_CONTEXT_WINDOWS = {
30
30
  'claude-sonnet-5': 1_000_000,
31
31
  'claude-haiku-4-5-20251001': 200_000,
32
32
  // DeepSeek
33
+ 'deepseek-flash': 1_000_000,
33
34
  'deepseek-v4-pro': 1_000_000,
34
35
  'deepseek-v4-flash': 1_000_000,
35
36
  // Google
@@ -43,7 +44,7 @@ const MODEL_CONTEXT_WINDOWS = {
43
44
  // MiniMax
44
45
  'MiniMax-M3': 1_000_000,
45
46
  // Kimi (Moonshot) — 1M on K3, 256K across K2.x
46
- 'kimi-k3': 1_000_000,
47
+ 'kimi-k3': 1_048_576,
47
48
  'kimi-k2.7-code': 262_144,
48
49
  'kimi-k2.7-code-highspeed': 262_144,
49
50
  'kimi-k2.6': 262_144,
@@ -59,6 +60,8 @@ const MODEL_CONTEXT_WINDOWS = {
59
60
  'grok-code-fast-1': 256_000,
60
61
  'grok-4-fast-reasoning': 2_000_000,
61
62
  // Qwen (Alibaba) — current hosted generation
63
+ 'qwen3.8-max': 1_000_000,
64
+ 'qwen3.8-flash': 1_000_000,
62
65
  'qwen3.7-max': 1_000_000,
63
66
  'qwen3.8-max-preview': 1_000_000,
64
67
  'qwen3.7-plus': 1_000_000,
@@ -93,10 +96,14 @@ const MODEL_PRICING = {
93
96
  'glm-5.1': { inputPer1M: 1.40, outputPer1M: 4.40 },
94
97
  'glm-5-turbo': { inputPer1M: 1.20, outputPer1M: 4.00 },
95
98
  // OpenAI
96
- // Twice the price of 5.6 Sol. Cached reads are $1.00/M — 0.1x input, which is
99
+ // 2.5x 5.6 Sol at its current promotional rate. Cached reads are $1.00/M — 0.1x input, which is
97
100
  // what DEFAULT_CACHE_READ_RATE already applies, so no model row is needed.
98
101
  'gpt-6-astra': { inputPer1M: 10.00, outputPer1M: 50.00 },
99
- 'gpt-5.6-sol': { inputPer1M: 5.00, outputPer1M: 30.00 },
102
+ // Promotional rate "available at least through 2026-11-21" per OpenAI's
103
+ // pricing page. Carried because it is what users are billed now, and no end
104
+ // date is written ahead of time — the Sonnet 5 lesson. Long-context requests
105
+ // bill 8/30; like every row here this holds the standard short-context tier.
106
+ 'gpt-5.6-sol': { inputPer1M: 4.00, outputPer1M: 20.00 },
100
107
  'gpt-5.6-terra': { inputPer1M: 2.00, outputPer1M: 12.00 },
101
108
  'gpt-5.6-luna': { inputPer1M: 0.20, outputPer1M: 1.20 },
102
109
  'gpt-5.5': { inputPer1M: 5.00, outputPer1M: 30.00 },
@@ -116,8 +123,19 @@ const MODEL_PRICING = {
116
123
  // honest direction for a cost estimate, and rule 5 of the catalogue policy
117
124
  // allows a clearly-labelled conservative approximation but never an invented
118
125
  // number. Cache-miss input; cache hits are ~1/50th and not modelled here.
119
- 'deepseek-v4-pro': { inputPer1M: 0.435, outputPer1M: 0.87 },
120
- 'deepseek-v4-flash': { inputPer1M: 0.14, outputPer1M: 0.28 },
126
+ // DeepSeek bills peak / off-peak (off-peak is half), and this table holds one
127
+ // rate, so it carries PEAK — an over-estimate by design. The previous rows
128
+ // (0.435/0.87 and 0.14/0.28) were two to four and a half times below today's
129
+ // peak and so under-reported, which is the one direction this table must not
130
+ // err in. Cache hits cost 2% of a miss, but DeepSeek reports them as
131
+ // `prompt_cache_hit_tokens`, which this tracker does not read — so every input
132
+ // token bills at the miss rate: an over-estimate again, not a gap.
133
+ 'deepseek-flash': { inputPer1M: 0.30, outputPer1M: 1.20 },
134
+ // Retired V4 Flash is served by V4.1 Flash and billed at its price.
135
+ 'deepseek-v4-flash': { inputPer1M: 0.30, outputPer1M: 1.20 },
136
+ // Pro's own peak rate, right for every run until 2026-09-14; after that the id
137
+ // is routed to Flash, and configs holding it have been migrated away from it.
138
+ 'deepseek-v4-pro': { inputPer1M: 1.32, outputPer1M: 3.96 },
121
139
  // Google
122
140
  // Gemini 3.6/3.7/3.8 Flash carry PROMOTIONAL rates that run through 2026-12-31
123
141
  // and are scheduled to step up to 1.50/7.50 on 2027-01-01 — revisit all three
@@ -132,7 +150,10 @@ const MODEL_PRICING = {
132
150
  'gemini-3.5-flash-lite': { inputPer1M: 0.30, outputPer1M: 2.50 },
133
151
  'gemini-3-flash-preview': { inputPer1M: 0.50, outputPer1M: 3.00 },
134
152
  // MiniMax
135
- 'MiniMax-M3': { inputPer1M: 0.60, outputPer1M: 2.40 },
153
+ // "Permanent 50% off" list price for prompts up to 512K tokens; above that,
154
+ // 0.60/2.40. The old 0.60/2.40 row was the long-context tier and doubled the
155
+ // estimate for virtually every real request.
156
+ 'MiniMax-M3': { inputPer1M: 0.30, outputPer1M: 1.20 },
136
157
  // Kimi (Moonshot) — pay-per-use cache-miss rates; `kimi-for-coding` is the
137
158
  // subscription alias (flat-fee in reality, priced notionally like K2.7 Code).
138
159
  'kimi-k3': { inputPer1M: 3.00, outputPer1M: 15.00 },
@@ -160,6 +181,8 @@ const MODEL_PRICING = {
160
181
  // `qwen3.8-max-preview` is Token-Plan-only (credit-metered, promotional
161
182
  // preview rate); Alibaba publishes no pay-per-use per-token price for it.
162
183
  // Leave it unpriced rather than borrowing the GA qwen3.8-max rate.
184
+ 'qwen3.8-max': { inputPer1M: 2.00, outputPer1M: 6.00 },
185
+ 'qwen3.8-flash': { inputPer1M: 0.15, outputPer1M: 0.47 },
163
186
  'qwen3.7-max': { inputPer1M: 2.50, outputPer1M: 7.50 },
164
187
  'qwen3.7-plus': { inputPer1M: 0.40, outputPer1M: 1.60 },
165
188
  'qwen3.6-plus': { inputPer1M: 0.40, outputPer1M: 2.40 },
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "3.2.2";
1
+ export declare const VERSION = "3.3.1";
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 = '3.2.2';
4
+ export const VERSION = '3.3.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "3.2.2",
3
+ "version": "3.3.1",
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",
@@ -17,6 +17,7 @@
17
17
  "test:coverage": "vitest run --coverage",
18
18
  "version": "node scripts/gen-version.js && git add src/version.ts",
19
19
  "export:catalogue": "node --import tsx scripts/export-catalogue.ts",
20
+ "export:commands": "node --import tsx scripts/export-commands.ts",
20
21
  "release": "node scripts/release.js"
21
22
  },
22
23
  "repository": {