codeep 2.14.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.
Files changed (70) hide show
  1. package/README.md +47 -27
  2. package/dist/acp/commands.js +22 -1
  3. package/dist/acp/server.js +13 -2
  4. package/dist/acp/session.js +22 -1
  5. package/dist/config/index.d.ts +10 -0
  6. package/dist/config/index.js +2 -2
  7. package/dist/config/providers.js +35 -24
  8. package/dist/renderer/App.d.ts +77 -30
  9. package/dist/renderer/App.js +429 -659
  10. package/dist/renderer/agentExecution.d.ts +1 -0
  11. package/dist/renderer/agentExecution.js +3 -2
  12. package/dist/renderer/commands/helpers.d.ts +251 -0
  13. package/dist/renderer/commands/helpers.js +450 -0
  14. package/dist/renderer/commands/registry.js +7 -1
  15. package/dist/renderer/commands.d.ts +4 -0
  16. package/dist/renderer/commands.js +363 -318
  17. package/dist/renderer/components/ActionFormatting.d.ts +17 -0
  18. package/dist/renderer/components/ActionFormatting.js +67 -0
  19. package/dist/renderer/components/Autocomplete.d.ts +58 -0
  20. package/dist/renderer/components/Autocomplete.js +75 -0
  21. package/dist/renderer/components/Intro.d.ts +9 -0
  22. package/dist/renderer/components/Intro.js +5 -15
  23. package/dist/renderer/components/MessageFormatter.d.ts +96 -0
  24. package/dist/renderer/components/MessageFormatter.js +375 -0
  25. package/dist/renderer/components/Permission.d.ts +4 -0
  26. package/dist/renderer/components/Permission.js +1 -1
  27. package/dist/renderer/components/Status.d.ts +4 -0
  28. package/dist/renderer/components/Status.js +2 -3
  29. package/dist/renderer/components/WelcomeFormatter.d.ts +19 -0
  30. package/dist/renderer/components/WelcomeFormatter.js +79 -0
  31. package/dist/renderer/components/uiConstants.d.ts +8 -0
  32. package/dist/renderer/components/uiConstants.js +24 -0
  33. package/dist/renderer/inputParsing.d.ts +22 -0
  34. package/dist/renderer/inputParsing.js +28 -0
  35. package/dist/renderer/layout.d.ts +219 -0
  36. package/dist/renderer/layout.js +338 -0
  37. package/dist/renderer/main.d.ts +2 -1
  38. package/dist/renderer/main.js +79 -11
  39. package/dist/renderer/ollamaHint.d.ts +12 -0
  40. package/dist/renderer/ollamaHint.js +29 -0
  41. package/dist/utils/agentChat.js +23 -1
  42. package/dist/utils/codeepCloud.d.ts +54 -0
  43. package/dist/utils/codeepCloud.js +95 -0
  44. package/dist/utils/diffPreview.d.ts +31 -0
  45. package/dist/utils/diffPreview.js +102 -0
  46. package/dist/utils/export.d.ts +12 -0
  47. package/dist/utils/export.js +3 -3
  48. package/dist/utils/git.d.ts +28 -0
  49. package/dist/utils/git.js +111 -1
  50. package/dist/utils/hooks.d.ts +26 -0
  51. package/dist/utils/hooks.js +69 -1
  52. package/dist/utils/keychain.js +45 -29
  53. package/dist/utils/logger.d.ts +12 -0
  54. package/dist/utils/logger.js +1 -1
  55. package/dist/utils/mcpConfig.d.ts +26 -0
  56. package/dist/utils/mcpConfig.js +109 -4
  57. package/dist/utils/mentions.d.ts +195 -0
  58. package/dist/utils/mentions.js +672 -0
  59. package/dist/utils/skillBundles.d.ts +14 -0
  60. package/dist/utils/skillBundles.js +3 -3
  61. package/dist/utils/skillBundlesCloud.d.ts +7 -0
  62. package/dist/utils/skillBundlesCloud.js +1 -1
  63. package/dist/utils/tokenTracker.js +21 -5
  64. package/dist/utils/toolParsing.d.ts +11 -0
  65. package/dist/utils/toolParsing.js +6 -0
  66. package/dist/utils/webFetch.d.ts +101 -0
  67. package/dist/utils/webFetch.js +375 -0
  68. package/dist/version.d.ts +1 -1
  69. package/dist/version.js +1 -1
  70. package/package.json +2 -2
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import { App } from './App';
9
9
  import { ProjectContext } from '../utils/project';
10
+ export declare function getActionType(toolName: string): string;
10
11
  export interface AppExecutionContext {
11
12
  app: App;
12
13
  projectPath: string;
@@ -11,7 +11,7 @@ import { config, autoSaveSession, getCurrentSessionId } from '../config/index.js
11
11
  import { reportStats, syncSession, generateProjectId } from '../utils/codeepCloud.js';
12
12
  import { getGitStatus, isGitRepository } from '../utils/git.js';
13
13
  import { getCostBreakdown, getRecordCount } from '../utils/tokenTracker.js';
14
- function getActionType(toolName) {
14
+ export function getActionType(toolName) {
15
15
  return toolName.includes('write') ? 'write' :
16
16
  toolName.includes('edit') ? 'edit' :
17
17
  toolName.includes('read') ? 'read' :
@@ -27,7 +27,8 @@ export function isDangerousTool(toolName, parameters) {
27
27
  const lowerName = toolName.toLowerCase();
28
28
  if (DANGEROUS_TOOLS.some(d => lowerName.includes(d)))
29
29
  return true;
30
- const command = parameters.command || '';
30
+ const rawCommand = parameters.command;
31
+ const command = typeof rawCommand === 'string' ? rawCommand : '';
31
32
  const dangerousCommands = ['rm ', 'rm -', 'rmdir', 'del ', 'delete', 'drop ', 'truncate'];
32
33
  return dangerousCommands.some(c => command.toLowerCase().includes(c));
33
34
  }
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Pure helpers extracted from `renderer/commands.ts`.
3
+ *
4
+ * The dispatcher is one giant switch/case; many cases contain small but
5
+ * tricky bits of pure logic (arg parsing, snippet extraction, message
6
+ * formatting) that were previously untestable because they were inlined
7
+ * alongside `ctx.app.*` calls. Pulling them here gives them direct unit
8
+ * coverage.
9
+ */
10
+ export interface SearchSnippet {
11
+ role: string;
12
+ messageIndex: number;
13
+ matchedText: string;
14
+ }
15
+ /** Snippet window: chars of context before / after the match. */
16
+ export declare const SEARCH_SNIPPET_BEFORE = 30;
17
+ export declare const SEARCH_SNIPPET_AFTER = 50;
18
+ /**
19
+ * Build search-result snippets for messages matching `term`. Mirrors the
20
+ * inline loop that used to live in the `/search` case. Case-insensitive.
21
+ */
22
+ export declare function buildSearchSnippets(messages: Array<{
23
+ role: string;
24
+ content: string;
25
+ }>, term: string): SearchSnippet[];
26
+ /**
27
+ * Parse the `/compact <n>` argument. Returns a value of at least 2
28
+ * (never compacts below 2 messages); defaults to `fallback` when the arg
29
+ * is missing or unparseable.
30
+ *
31
+ * Note: we use `Number.isNaN` rather than `parsed || fallback` because
32
+ * `0` is a valid (if useless) numeric input that should clamp to 2, not
33
+ * silently fall through to the default.
34
+ */
35
+ export declare function parseKeepRecent(arg: string | undefined, fallback?: number): number;
36
+ /**
37
+ * Join slash-command args into a single hyphen-separated name, as used by
38
+ * `/rename`. Empty args are dropped so `/rename my session ` still
39
+ * yields `my-session`.
40
+ */
41
+ export declare function joinSessionName(args: string[]): string;
42
+ export declare const TASK_TYPES: readonly ["task", "bug", "feature"];
43
+ export type TaskType = (typeof TASK_TYPES)[number];
44
+ /** Result of parsing `/tasks add` flags. */
45
+ export interface ParsedTaskAdd {
46
+ title: string;
47
+ description: string;
48
+ type: TaskType;
49
+ }
50
+ /**
51
+ * Parse the args following `/tasks add` into a title, description, and
52
+ * type. Flags (`--bug`, `--feature`, `--task`) set the type; `--desc` /
53
+ * `--description` captures the following words until the next flag.
54
+ * Non-flag words before any `--desc` form the title.
55
+ */
56
+ export declare function parseTaskAddArgs(args: string[]): ParsedTaskAdd;
57
+ /** Render a list of tasks as a Markdown list, mirroring `/tasks`. */
58
+ export declare function formatTaskList(tasks: Array<{
59
+ title: string;
60
+ type?: string | null;
61
+ description?: string | null;
62
+ project_name?: string | null;
63
+ }>, scopeProjectName?: string): string;
64
+ /** Render the `/profile list` Markdown message from saved profile names. */
65
+ export declare function formatProfileList(profiles: string[]): string;
66
+ /** Render the `/memory list` Markdown message from saved notes. */
67
+ export declare function formatMemoryList(notes: string[]): string;
68
+ export interface StatsModelRow {
69
+ model: string;
70
+ provider: string;
71
+ promptTokens: number;
72
+ completionTokens: number;
73
+ estimatedCost: number;
74
+ }
75
+ export interface StatsTotals {
76
+ requestCount: number;
77
+ totalTokens: number;
78
+ totalPromptTokens: number;
79
+ totalCompletionTokens: number;
80
+ estimatedCost: number;
81
+ }
82
+ export interface StatsCache {
83
+ cacheReadTokens: number;
84
+ cacheCreationTokens: number;
85
+ estimatedSavingsUsd: number;
86
+ }
87
+ export interface PricingRow {
88
+ model: string;
89
+ inputPer1M: number;
90
+ outputPer1M: number;
91
+ }
92
+ /** A formatter for token counts (injected so this module stays pure). */
93
+ export type TokenFormatter = (n: number) => string;
94
+ /** Format a single model-row's cost string, mirroring the inline logic. */
95
+ export declare function formatModelCost(provider: string, estimatedCost: number): string;
96
+ /**
97
+ * Build the full `/stats` Markdown report. `currentProvider` controls
98
+ * whether the total shows "free" (ollama) or a dollar figure.
99
+ */
100
+ export declare function formatStatsReport(args: {
101
+ totals: StatsTotals;
102
+ breakdown: StatsModelRow[];
103
+ cache: StatsCache;
104
+ pricing: PricingRow[];
105
+ currentProvider: string;
106
+ fmt: TokenFormatter;
107
+ }): string;
108
+ /**
109
+ * Extract every fenced code block body (the text inside ```…```) from a
110
+ * string, mirroring the `/copy` loop. Language fences (```ts) are ignored —
111
+ * only the body is captured.
112
+ */
113
+ export declare function extractCodeBlocks(text: string): string[];
114
+ /**
115
+ * Validate a 1-based block index against the available block list, as used
116
+ * by `/copy <n>`. Returns the 0-based index, or `null` when the index is
117
+ * out of range (the caller shows an error).
118
+ */
119
+ export declare function resolveBlockIndex(blockNum: number, blockCount: number): number | null;
120
+ export interface FileChange {
121
+ path: string;
122
+ content: string;
123
+ }
124
+ /**
125
+ * Extract file-change pairs from an assistant message, mirroring `/apply`.
126
+ * Two patterns are tried in order:
127
+ * 1. fence with a filename header: ```ts\nsrc/foo.ts\n<body>```
128
+ * 2. fence with a `// File:` / `# Path:` comment header.
129
+ * A path is only accepted when it contains a dot and no spaces.
130
+ */
131
+ export declare function extractFileChanges(text: string): FileChange[];
132
+ /** Truncate a path for display: keep the last 37 chars, prefixed with “…”. */
133
+ export declare function shortPathForDisplay(path: string, max?: number): string;
134
+ /**
135
+ * Build a single diff-line summary for a file change, mirroring `/apply`.
136
+ * Returns `null` when `existingContent` is empty (a CREATE), otherwise a
137
+ * MODIFY line with the line-count delta.
138
+ */
139
+ export declare function formatApplyDiffLine(change: {
140
+ path: string;
141
+ content: string;
142
+ }, existingContent: string): string[];
143
+ /**
144
+ * Parse `key=value` tokens (as used by `/mcp prompt <server> <name> [k=v...]`)
145
+ * into a record. Tokens without an `=` (or with `=` at position 0) are
146
+ * skipped. Mirrors the inline loop.
147
+ */
148
+ export declare function parsePromptArgs(tokens: string[]): Record<string, string>;
149
+ /** Pluralise "tool"/"tools" based on the count. */
150
+ export declare function pluralTools(n: number): string;
151
+ /**
152
+ * Group a flat list of tools by `serverName`, preserving first-seen order.
153
+ * Used by `/mcp` (default), `/mcp reload`, and the install report.
154
+ */
155
+ export declare function groupToolsByServer<T extends {
156
+ serverName: string;
157
+ }>(tools: T[]): Array<{
158
+ serverName: string;
159
+ serverTools: T[];
160
+ }>;
161
+ /** Format the `/mcp` default server/tool listing. */
162
+ export declare function formatMcpServerList<T extends {
163
+ serverName: string;
164
+ agentName: string;
165
+ description?: string;
166
+ }>(tools: T[], errors: Array<{
167
+ server: string;
168
+ error: string;
169
+ }>): string;
170
+ /** Format the `/mcp reload` report. */
171
+ export declare function formatMcpReloadReport(toolCount: number, serverCount: number, errors: Array<{
172
+ server: string;
173
+ error: string;
174
+ }>): string;
175
+ /** Format the `/mcp resources` listing. */
176
+ export declare function formatMcpResourcesList(groups: Array<{
177
+ serverName: string;
178
+ resources: Array<{
179
+ uri: string;
180
+ name?: string;
181
+ mimeType?: string;
182
+ description?: string;
183
+ }>;
184
+ }>): string;
185
+ /** Format the `/mcp read` output for a list of resource contents. */
186
+ export declare function formatMcpResourceRead(uri: string, contents: Array<{
187
+ text?: string;
188
+ blob?: string;
189
+ mimeType?: string;
190
+ }>): string;
191
+ /** Format the `/mcp prompts` listing. */
192
+ export declare function formatMcpPromptsList(groups: Array<{
193
+ serverName: string;
194
+ prompts: Array<{
195
+ name: string;
196
+ description?: string;
197
+ arguments?: Array<{
198
+ name: string;
199
+ required?: boolean;
200
+ }>;
201
+ }>;
202
+ }>): string;
203
+ /** Format the `/mcp prompt` materialised output. */
204
+ export declare function formatMcpPromptResult(serverName: string, name: string, description: string | undefined, messages: Array<{
205
+ role: string;
206
+ content?: {
207
+ text?: string;
208
+ };
209
+ }>): string;
210
+ /**
211
+ * Parse the `--days N` / `--days=N` flag from `/insights` args. Returns the
212
+ * default (7) when absent or unparseable; clamps negatives to 0.
213
+ */
214
+ export declare function parseInsightsDays(args: string[], fallback?: number): number;
215
+ /**
216
+ * Format a single cloud-session row for the `/cloud` picker, mirroring the
217
+ * inline template: `title · date · N msg · [project?]`.
218
+ */
219
+ export declare function formatCloudSessionLabel(s: {
220
+ sessionId: string;
221
+ sessionName?: string | null;
222
+ updatedAt: string;
223
+ messageCount: number;
224
+ projectName?: string | null;
225
+ }): string;
226
+ /** Format the `/me sync` result list. `pulled` is `1` on success, `0` or `null` otherwise. */
227
+ export declare function formatMeSyncReport(pushed: boolean, pulled: number | null): string;
228
+ /**
229
+ * Format the `/me learn` result. `updated` distinguishes "new facts written"
230
+ * from "already covered"; `file` is the human-readable path.
231
+ */
232
+ export declare function formatMeLearnResult(scope: 'global' | 'project', file: string, res: {
233
+ updated: boolean;
234
+ facts: string;
235
+ }): string;
236
+ /** Format the `/me init` result. */
237
+ export declare function formatMeInitResult(scope: 'global' | 'project', res: {
238
+ created: boolean;
239
+ path: string;
240
+ }): string;
241
+ /** Format the `/skills show` detail view from a skill bundle. */
242
+ export declare function formatSkillsShow(bundle: {
243
+ name: string;
244
+ description: string;
245
+ source: string;
246
+ body: string;
247
+ }): string;
248
+ /** Format the `/skills browse` empty-state message. */
249
+ export declare function formatSkillsBrowseEmpty(query: string): string;
250
+ /** Format the `/skills publish` success message. */
251
+ export declare function formatSkillsPublishResult(slug: string, isPublic: boolean, owner: string | null | undefined): string;