@shareai-lab/kode 1.1.13 → 1.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/entrypoints/cli.js +2 -1
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/index.js +5 -26
- package/dist/package.json +4 -1
- package/package.json +9 -104
- package/dist/test/testAdapters.js +0 -88
- package/dist/test/testAdapters.js.map +0 -1
- package/src/ProjectOnboarding.tsx +0 -198
- package/src/Tool.ts +0 -83
- package/src/commands/agents.tsx +0 -3416
- package/src/commands/approvedTools.ts +0 -53
- package/src/commands/bug.tsx +0 -20
- package/src/commands/clear.ts +0 -43
- package/src/commands/compact.ts +0 -120
- package/src/commands/config.tsx +0 -19
- package/src/commands/cost.ts +0 -18
- package/src/commands/ctx_viz.ts +0 -209
- package/src/commands/doctor.ts +0 -24
- package/src/commands/help.tsx +0 -19
- package/src/commands/init.ts +0 -37
- package/src/commands/listen.ts +0 -42
- package/src/commands/login.tsx +0 -51
- package/src/commands/logout.tsx +0 -40
- package/src/commands/mcp.ts +0 -41
- package/src/commands/model.tsx +0 -40
- package/src/commands/modelstatus.tsx +0 -20
- package/src/commands/onboarding.tsx +0 -34
- package/src/commands/pr_comments.ts +0 -59
- package/src/commands/refreshCommands.ts +0 -54
- package/src/commands/release-notes.ts +0 -34
- package/src/commands/resume.tsx +0 -31
- package/src/commands/review.ts +0 -49
- package/src/commands/terminalSetup.ts +0 -221
- package/src/commands.ts +0 -139
- package/src/components/ApproveApiKey.tsx +0 -93
- package/src/components/AsciiLogo.tsx +0 -13
- package/src/components/AutoUpdater.tsx +0 -148
- package/src/components/Bug.tsx +0 -367
- package/src/components/Config.tsx +0 -293
- package/src/components/ConsoleOAuthFlow.tsx +0 -327
- package/src/components/Cost.tsx +0 -23
- package/src/components/CostThresholdDialog.tsx +0 -46
- package/src/components/CustomSelect/option-map.ts +0 -42
- package/src/components/CustomSelect/select-option.tsx +0 -78
- package/src/components/CustomSelect/select.tsx +0 -152
- package/src/components/CustomSelect/theme.ts +0 -45
- package/src/components/CustomSelect/use-select-state.ts +0 -414
- package/src/components/CustomSelect/use-select.ts +0 -35
- package/src/components/FallbackToolUseRejectedMessage.tsx +0 -15
- package/src/components/FileEditToolUpdatedMessage.tsx +0 -66
- package/src/components/Help.tsx +0 -215
- package/src/components/HighlightedCode.tsx +0 -33
- package/src/components/InvalidConfigDialog.tsx +0 -113
- package/src/components/Link.tsx +0 -32
- package/src/components/LogSelector.tsx +0 -86
- package/src/components/Logo.tsx +0 -170
- package/src/components/MCPServerApprovalDialog.tsx +0 -100
- package/src/components/MCPServerDialogCopy.tsx +0 -25
- package/src/components/MCPServerMultiselectDialog.tsx +0 -109
- package/src/components/Message.tsx +0 -221
- package/src/components/MessageResponse.tsx +0 -15
- package/src/components/MessageSelector.tsx +0 -211
- package/src/components/ModeIndicator.tsx +0 -88
- package/src/components/ModelConfig.tsx +0 -301
- package/src/components/ModelListManager.tsx +0 -227
- package/src/components/ModelSelector.tsx +0 -3387
- package/src/components/ModelStatusDisplay.tsx +0 -230
- package/src/components/Onboarding.tsx +0 -274
- package/src/components/PressEnterToContinue.tsx +0 -11
- package/src/components/PromptInput.tsx +0 -760
- package/src/components/SentryErrorBoundary.ts +0 -39
- package/src/components/Spinner.tsx +0 -129
- package/src/components/StickerRequestForm.tsx +0 -16
- package/src/components/StructuredDiff.tsx +0 -191
- package/src/components/TextInput.tsx +0 -259
- package/src/components/TodoItem.tsx +0 -47
- package/src/components/TokenWarning.tsx +0 -31
- package/src/components/ToolUseLoader.tsx +0 -40
- package/src/components/TrustDialog.tsx +0 -106
- package/src/components/binary-feedback/BinaryFeedback.tsx +0 -63
- package/src/components/binary-feedback/BinaryFeedbackOption.tsx +0 -111
- package/src/components/binary-feedback/BinaryFeedbackView.tsx +0 -172
- package/src/components/binary-feedback/utils.ts +0 -220
- package/src/components/messages/AssistantBashOutputMessage.tsx +0 -22
- package/src/components/messages/AssistantLocalCommandOutputMessage.tsx +0 -49
- package/src/components/messages/AssistantRedactedThinkingMessage.tsx +0 -19
- package/src/components/messages/AssistantTextMessage.tsx +0 -144
- package/src/components/messages/AssistantThinkingMessage.tsx +0 -40
- package/src/components/messages/AssistantToolUseMessage.tsx +0 -132
- package/src/components/messages/TaskProgressMessage.tsx +0 -32
- package/src/components/messages/TaskToolMessage.tsx +0 -58
- package/src/components/messages/UserBashInputMessage.tsx +0 -28
- package/src/components/messages/UserCommandMessage.tsx +0 -30
- package/src/components/messages/UserKodingInputMessage.tsx +0 -28
- package/src/components/messages/UserPromptMessage.tsx +0 -35
- package/src/components/messages/UserTextMessage.tsx +0 -39
- package/src/components/messages/UserToolResultMessage/UserToolCanceledMessage.tsx +0 -12
- package/src/components/messages/UserToolResultMessage/UserToolErrorMessage.tsx +0 -36
- package/src/components/messages/UserToolResultMessage/UserToolRejectMessage.tsx +0 -31
- package/src/components/messages/UserToolResultMessage/UserToolResultMessage.tsx +0 -57
- package/src/components/messages/UserToolResultMessage/UserToolSuccessMessage.tsx +0 -35
- package/src/components/messages/UserToolResultMessage/utils.tsx +0 -56
- package/src/components/permissions/BashPermissionRequest/BashPermissionRequest.tsx +0 -121
- package/src/components/permissions/FallbackPermissionRequest.tsx +0 -153
- package/src/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.tsx +0 -182
- package/src/components/permissions/FileEditPermissionRequest/FileEditToolDiff.tsx +0 -77
- package/src/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.tsx +0 -164
- package/src/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.tsx +0 -83
- package/src/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.tsx +0 -240
- package/src/components/permissions/PermissionRequest.tsx +0 -101
- package/src/components/permissions/PermissionRequestTitle.tsx +0 -69
- package/src/components/permissions/hooks.ts +0 -44
- package/src/components/permissions/toolUseOptions.ts +0 -59
- package/src/components/permissions/utils.ts +0 -23
- package/src/constants/betas.ts +0 -5
- package/src/constants/claude-asterisk-ascii-art.tsx +0 -238
- package/src/constants/figures.ts +0 -4
- package/src/constants/keys.ts +0 -3
- package/src/constants/macros.ts +0 -11
- package/src/constants/modelCapabilities.ts +0 -179
- package/src/constants/models.ts +0 -1025
- package/src/constants/oauth.ts +0 -18
- package/src/constants/product.ts +0 -17
- package/src/constants/prompts.ts +0 -168
- package/src/constants/releaseNotes.ts +0 -7
- package/src/context/PermissionContext.tsx +0 -149
- package/src/context.ts +0 -278
- package/src/cost-tracker.ts +0 -84
- package/src/entrypoints/cli.tsx +0 -1561
- package/src/entrypoints/mcp.ts +0 -175
- package/src/history.ts +0 -25
- package/src/hooks/useApiKeyVerification.ts +0 -59
- package/src/hooks/useArrowKeyHistory.ts +0 -55
- package/src/hooks/useCanUseTool.ts +0 -138
- package/src/hooks/useCancelRequest.ts +0 -39
- package/src/hooks/useDoublePress.ts +0 -41
- package/src/hooks/useExitOnCtrlCD.ts +0 -31
- package/src/hooks/useInterval.ts +0 -25
- package/src/hooks/useLogMessages.ts +0 -16
- package/src/hooks/useLogStartupTime.ts +0 -12
- package/src/hooks/useNotifyAfterTimeout.ts +0 -65
- package/src/hooks/usePermissionRequestLogging.ts +0 -44
- package/src/hooks/useTerminalSize.ts +0 -49
- package/src/hooks/useTextInput.ts +0 -317
- package/src/hooks/useUnifiedCompletion.ts +0 -1405
- package/src/index.ts +0 -34
- package/src/messages.ts +0 -38
- package/src/permissions.ts +0 -268
- package/src/query.ts +0 -720
- package/src/screens/ConfigureNpmPrefix.tsx +0 -197
- package/src/screens/Doctor.tsx +0 -219
- package/src/screens/LogList.tsx +0 -68
- package/src/screens/REPL.tsx +0 -813
- package/src/screens/ResumeConversation.tsx +0 -68
- package/src/services/adapters/base.ts +0 -38
- package/src/services/adapters/chatCompletions.ts +0 -90
- package/src/services/adapters/responsesAPI.ts +0 -170
- package/src/services/browserMocks.ts +0 -66
- package/src/services/claude.ts +0 -2197
- package/src/services/customCommands.ts +0 -704
- package/src/services/fileFreshness.ts +0 -377
- package/src/services/gpt5ConnectionTest.ts +0 -340
- package/src/services/mcpClient.ts +0 -564
- package/src/services/mcpServerApproval.tsx +0 -50
- package/src/services/mentionProcessor.ts +0 -273
- package/src/services/modelAdapterFactory.ts +0 -69
- package/src/services/notifier.ts +0 -40
- package/src/services/oauth.ts +0 -357
- package/src/services/openai.ts +0 -1359
- package/src/services/responseStateManager.ts +0 -90
- package/src/services/sentry.ts +0 -3
- package/src/services/statsig.ts +0 -172
- package/src/services/statsigStorage.ts +0 -86
- package/src/services/systemReminder.ts +0 -507
- package/src/services/vcr.ts +0 -161
- package/src/test/testAdapters.ts +0 -96
- package/src/tools/ArchitectTool/ArchitectTool.tsx +0 -135
- package/src/tools/ArchitectTool/prompt.ts +0 -15
- package/src/tools/AskExpertModelTool/AskExpertModelTool.tsx +0 -576
- package/src/tools/BashTool/BashTool.tsx +0 -243
- package/src/tools/BashTool/BashToolResultMessage.tsx +0 -38
- package/src/tools/BashTool/OutputLine.tsx +0 -49
- package/src/tools/BashTool/prompt.ts +0 -174
- package/src/tools/BashTool/utils.ts +0 -56
- package/src/tools/FileEditTool/FileEditTool.tsx +0 -319
- package/src/tools/FileEditTool/prompt.ts +0 -51
- package/src/tools/FileEditTool/utils.ts +0 -58
- package/src/tools/FileReadTool/FileReadTool.tsx +0 -404
- package/src/tools/FileReadTool/prompt.ts +0 -7
- package/src/tools/FileWriteTool/FileWriteTool.tsx +0 -301
- package/src/tools/FileWriteTool/prompt.ts +0 -10
- package/src/tools/GlobTool/GlobTool.tsx +0 -119
- package/src/tools/GlobTool/prompt.ts +0 -8
- package/src/tools/GrepTool/GrepTool.tsx +0 -147
- package/src/tools/GrepTool/prompt.ts +0 -11
- package/src/tools/MCPTool/MCPTool.tsx +0 -107
- package/src/tools/MCPTool/prompt.ts +0 -3
- package/src/tools/MemoryReadTool/MemoryReadTool.tsx +0 -127
- package/src/tools/MemoryReadTool/prompt.ts +0 -3
- package/src/tools/MemoryWriteTool/MemoryWriteTool.tsx +0 -89
- package/src/tools/MemoryWriteTool/prompt.ts +0 -3
- package/src/tools/MultiEditTool/MultiEditTool.tsx +0 -388
- package/src/tools/MultiEditTool/prompt.ts +0 -45
- package/src/tools/NotebookEditTool/NotebookEditTool.tsx +0 -298
- package/src/tools/NotebookEditTool/prompt.ts +0 -3
- package/src/tools/NotebookReadTool/NotebookReadTool.tsx +0 -258
- package/src/tools/NotebookReadTool/prompt.ts +0 -3
- package/src/tools/StickerRequestTool/StickerRequestTool.tsx +0 -107
- package/src/tools/StickerRequestTool/prompt.ts +0 -19
- package/src/tools/TaskTool/TaskTool.tsx +0 -438
- package/src/tools/TaskTool/constants.ts +0 -1
- package/src/tools/TaskTool/prompt.ts +0 -92
- package/src/tools/ThinkTool/ThinkTool.tsx +0 -54
- package/src/tools/ThinkTool/prompt.ts +0 -12
- package/src/tools/TodoWriteTool/TodoWriteTool.tsx +0 -313
- package/src/tools/TodoWriteTool/prompt.ts +0 -63
- package/src/tools/URLFetcherTool/URLFetcherTool.tsx +0 -178
- package/src/tools/URLFetcherTool/cache.ts +0 -55
- package/src/tools/URLFetcherTool/htmlToMarkdown.ts +0 -55
- package/src/tools/URLFetcherTool/prompt.ts +0 -17
- package/src/tools/WebSearchTool/WebSearchTool.tsx +0 -103
- package/src/tools/WebSearchTool/prompt.ts +0 -13
- package/src/tools/WebSearchTool/searchProviders.ts +0 -66
- package/src/tools/lsTool/lsTool.tsx +0 -272
- package/src/tools/lsTool/prompt.ts +0 -2
- package/src/tools.ts +0 -67
- package/src/types/PermissionMode.ts +0 -120
- package/src/types/RequestContext.ts +0 -72
- package/src/types/common.d.ts +0 -2
- package/src/types/conversation.ts +0 -51
- package/src/types/logs.ts +0 -58
- package/src/types/modelCapabilities.ts +0 -64
- package/src/types/notebook.ts +0 -87
- package/src/utils/Cursor.ts +0 -436
- package/src/utils/PersistentShell.ts +0 -552
- package/src/utils/advancedFuzzyMatcher.ts +0 -290
- package/src/utils/agentLoader.ts +0 -278
- package/src/utils/agentStorage.ts +0 -97
- package/src/utils/array.ts +0 -3
- package/src/utils/ask.tsx +0 -99
- package/src/utils/auth.ts +0 -13
- package/src/utils/autoCompactCore.ts +0 -223
- package/src/utils/autoUpdater.ts +0 -458
- package/src/utils/betas.ts +0 -20
- package/src/utils/browser.ts +0 -14
- package/src/utils/cleanup.ts +0 -72
- package/src/utils/commands.ts +0 -261
- package/src/utils/commonUnixCommands.ts +0 -161
- package/src/utils/config.ts +0 -945
- package/src/utils/conversationRecovery.ts +0 -55
- package/src/utils/debugLogger.ts +0 -1235
- package/src/utils/diff.ts +0 -42
- package/src/utils/env.ts +0 -57
- package/src/utils/errors.ts +0 -21
- package/src/utils/exampleCommands.ts +0 -109
- package/src/utils/execFileNoThrow.ts +0 -51
- package/src/utils/expertChatStorage.ts +0 -136
- package/src/utils/file.ts +0 -405
- package/src/utils/fileRecoveryCore.ts +0 -71
- package/src/utils/format.tsx +0 -44
- package/src/utils/fuzzyMatcher.ts +0 -328
- package/src/utils/generators.ts +0 -62
- package/src/utils/git.ts +0 -92
- package/src/utils/globalLogger.ts +0 -77
- package/src/utils/http.ts +0 -10
- package/src/utils/imagePaste.ts +0 -38
- package/src/utils/json.ts +0 -13
- package/src/utils/log.ts +0 -382
- package/src/utils/markdown.ts +0 -213
- package/src/utils/messageContextManager.ts +0 -294
- package/src/utils/messages.tsx +0 -945
- package/src/utils/model.ts +0 -914
- package/src/utils/permissions/filesystem.ts +0 -127
- package/src/utils/responseState.ts +0 -23
- package/src/utils/ripgrep.ts +0 -167
- package/src/utils/secureFile.ts +0 -564
- package/src/utils/sessionState.ts +0 -49
- package/src/utils/state.ts +0 -25
- package/src/utils/style.ts +0 -29
- package/src/utils/terminal.ts +0 -50
- package/src/utils/theme.ts +0 -127
- package/src/utils/thinking.ts +0 -144
- package/src/utils/todoStorage.ts +0 -431
- package/src/utils/tokens.ts +0 -43
- package/src/utils/toolExecutionController.ts +0 -163
- package/src/utils/unaryLogging.ts +0 -26
- package/src/utils/user.ts +0 -37
- package/src/utils/validate.ts +0 -165
package/src/utils/file.ts
DELETED
|
@@ -1,405 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
readFileSync,
|
|
3
|
-
writeFileSync,
|
|
4
|
-
openSync,
|
|
5
|
-
readSync,
|
|
6
|
-
closeSync,
|
|
7
|
-
existsSync,
|
|
8
|
-
readdirSync,
|
|
9
|
-
} from 'fs'
|
|
10
|
-
import { logError } from './log'
|
|
11
|
-
import {
|
|
12
|
-
isAbsolute,
|
|
13
|
-
normalize,
|
|
14
|
-
resolve,
|
|
15
|
-
resolve as resolvePath,
|
|
16
|
-
relative,
|
|
17
|
-
sep,
|
|
18
|
-
basename,
|
|
19
|
-
dirname,
|
|
20
|
-
extname,
|
|
21
|
-
join,
|
|
22
|
-
} from 'path'
|
|
23
|
-
import { glob as globLib } from 'glob'
|
|
24
|
-
import { cwd } from 'process'
|
|
25
|
-
import { listAllContentFiles } from './ripgrep'
|
|
26
|
-
import { LRUCache } from 'lru-cache'
|
|
27
|
-
import { getCwd } from './state'
|
|
28
|
-
|
|
29
|
-
export type File = {
|
|
30
|
-
filename: string
|
|
31
|
-
content: string
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export type LineEndingType = 'CRLF' | 'LF'
|
|
35
|
-
|
|
36
|
-
export async function glob(
|
|
37
|
-
filePattern: string,
|
|
38
|
-
cwd: string,
|
|
39
|
-
{ limit, offset }: { limit: number; offset: number },
|
|
40
|
-
abortSignal: AbortSignal,
|
|
41
|
-
): Promise<{ files: string[]; truncated: boolean }> {
|
|
42
|
-
// TODO: Use worker threads
|
|
43
|
-
const paths = await globLib([filePattern], {
|
|
44
|
-
cwd,
|
|
45
|
-
nocase: true,
|
|
46
|
-
nodir: true,
|
|
47
|
-
signal: abortSignal,
|
|
48
|
-
stat: true,
|
|
49
|
-
withFileTypes: true,
|
|
50
|
-
})
|
|
51
|
-
const sortedPaths = paths.sort((a, b) => (a.mtimeMs ?? 0) - (b.mtimeMs ?? 0))
|
|
52
|
-
const truncated = sortedPaths.length > offset + limit
|
|
53
|
-
return {
|
|
54
|
-
files: sortedPaths
|
|
55
|
-
.slice(offset, offset + limit)
|
|
56
|
-
.map(path => path.fullpath()),
|
|
57
|
-
truncated,
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function readFileSafe(filepath: string): string | null {
|
|
62
|
-
try {
|
|
63
|
-
return readFileSync(filepath, 'utf-8')
|
|
64
|
-
} catch (error) {
|
|
65
|
-
logError(error)
|
|
66
|
-
return null
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function isInDirectory(
|
|
71
|
-
relativePath: string,
|
|
72
|
-
relativeCwd: string,
|
|
73
|
-
): boolean {
|
|
74
|
-
if (relativePath === '.') {
|
|
75
|
-
return true
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Reject paths starting with ~ (home directory)
|
|
79
|
-
if (relativePath.startsWith('~')) {
|
|
80
|
-
return false
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Reject paths containing null bytes or other sneaky characters
|
|
84
|
-
if (relativePath.includes('\0') || relativeCwd.includes('\0')) {
|
|
85
|
-
return false
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Normalize paths to resolve any '..' or '.' segments
|
|
89
|
-
// and add trailing slashes
|
|
90
|
-
let normalizedPath = normalize(relativePath)
|
|
91
|
-
let normalizedCwd = normalize(relativeCwd)
|
|
92
|
-
|
|
93
|
-
normalizedPath = normalizedPath.endsWith(sep)
|
|
94
|
-
? normalizedPath
|
|
95
|
-
: normalizedPath + sep
|
|
96
|
-
normalizedCwd = normalizedCwd.endsWith(sep)
|
|
97
|
-
? normalizedCwd
|
|
98
|
-
: normalizedCwd + sep
|
|
99
|
-
|
|
100
|
-
// Join with a base directory to make them absolute-like for comparison
|
|
101
|
-
const fullPath = resolvePath(cwd(), normalizedCwd, normalizedPath)
|
|
102
|
-
const fullCwd = resolvePath(cwd(), normalizedCwd)
|
|
103
|
-
|
|
104
|
-
// Robust subpath check using path.relative (case-insensitive on Windows)
|
|
105
|
-
const rel = relative(fullCwd, fullPath)
|
|
106
|
-
if (!rel || rel === '') return true
|
|
107
|
-
if (rel.startsWith('..')) return false
|
|
108
|
-
if (isAbsolute(rel)) return false
|
|
109
|
-
return true
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export function readTextContent(
|
|
113
|
-
filePath: string,
|
|
114
|
-
offset = 0,
|
|
115
|
-
maxLines?: number,
|
|
116
|
-
): { content: string; lineCount: number; totalLines: number } {
|
|
117
|
-
const enc = detectFileEncoding(filePath)
|
|
118
|
-
const content = readFileSync(filePath, enc)
|
|
119
|
-
const lines = content.split(/\r?\n/)
|
|
120
|
-
|
|
121
|
-
// Truncate number of lines if needed
|
|
122
|
-
const toReturn =
|
|
123
|
-
maxLines !== undefined && lines.length - offset > maxLines
|
|
124
|
-
? lines.slice(offset, offset + maxLines)
|
|
125
|
-
: lines.slice(offset)
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
content: toReturn.join('\n'), // TODO: This probably won't work for Windows
|
|
129
|
-
lineCount: toReturn.length,
|
|
130
|
-
totalLines: lines.length,
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export function writeTextContent(
|
|
135
|
-
filePath: string,
|
|
136
|
-
content: string,
|
|
137
|
-
encoding: BufferEncoding,
|
|
138
|
-
endings: LineEndingType,
|
|
139
|
-
): void {
|
|
140
|
-
let toWrite = content
|
|
141
|
-
if (endings === 'CRLF') {
|
|
142
|
-
toWrite = content.split('\n').join('\r\n')
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
writeFileSync(filePath, toWrite, { encoding, flush: true })
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const repoEndingCache = new LRUCache<string, LineEndingType>({
|
|
149
|
-
fetchMethod: path => detectRepoLineEndingsDirect(path),
|
|
150
|
-
ttl: 5 * 60 * 1000,
|
|
151
|
-
ttlAutopurge: false,
|
|
152
|
-
max: 1000,
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
export async function detectRepoLineEndings(
|
|
156
|
-
filePath: string,
|
|
157
|
-
): Promise<LineEndingType | undefined> {
|
|
158
|
-
return repoEndingCache.fetch(resolve(filePath))
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export async function detectRepoLineEndingsDirect(
|
|
162
|
-
cwd: string,
|
|
163
|
-
): Promise<LineEndingType> {
|
|
164
|
-
const abortController = new AbortController()
|
|
165
|
-
setTimeout(() => {
|
|
166
|
-
abortController.abort()
|
|
167
|
-
}, 1_000)
|
|
168
|
-
const allFiles = await listAllContentFiles(cwd, abortController.signal, 15)
|
|
169
|
-
|
|
170
|
-
let crlfCount = 0
|
|
171
|
-
for (const file of allFiles) {
|
|
172
|
-
const lineEnding = detectLineEndings(file)
|
|
173
|
-
if (lineEnding === 'CRLF') {
|
|
174
|
-
crlfCount++
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return crlfCount > 3 ? 'CRLF' : 'LF'
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
182
|
-
function fetch<K extends {}, V extends {}>(
|
|
183
|
-
cache: LRUCache<K, V>,
|
|
184
|
-
key: K,
|
|
185
|
-
value: () => V,
|
|
186
|
-
): V {
|
|
187
|
-
if (cache.has(key)) {
|
|
188
|
-
return cache.get(key)!
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const v = value()
|
|
192
|
-
cache.set(key, v)
|
|
193
|
-
return v
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const fileEncodingCache = new LRUCache<string, BufferEncoding>({
|
|
197
|
-
fetchMethod: path => detectFileEncodingDirect(path),
|
|
198
|
-
ttl: 5 * 60 * 1000,
|
|
199
|
-
ttlAutopurge: false,
|
|
200
|
-
max: 1000,
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
export function detectFileEncoding(filePath: string): BufferEncoding {
|
|
204
|
-
const k = resolve(filePath)
|
|
205
|
-
return fetch(fileEncodingCache, k, () => detectFileEncodingDirect(k))
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export function detectFileEncodingDirect(filePath: string): BufferEncoding {
|
|
209
|
-
const BUFFER_SIZE = 4096
|
|
210
|
-
const buffer = Buffer.alloc(BUFFER_SIZE)
|
|
211
|
-
|
|
212
|
-
let fd: number | undefined = undefined
|
|
213
|
-
try {
|
|
214
|
-
fd = openSync(filePath, 'r')
|
|
215
|
-
const bytesRead = readSync(fd, buffer, 0, BUFFER_SIZE, 0)
|
|
216
|
-
|
|
217
|
-
if (bytesRead >= 2) {
|
|
218
|
-
if (buffer[0] === 0xff && buffer[1] === 0xfe) return 'utf16le'
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (
|
|
222
|
-
bytesRead >= 3 &&
|
|
223
|
-
buffer[0] === 0xef &&
|
|
224
|
-
buffer[1] === 0xbb &&
|
|
225
|
-
buffer[2] === 0xbf
|
|
226
|
-
) {
|
|
227
|
-
return 'utf8'
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const isUtf8 = buffer.slice(0, bytesRead).toString('utf8').length > 0
|
|
231
|
-
return isUtf8 ? 'utf8' : 'ascii'
|
|
232
|
-
} catch (error) {
|
|
233
|
-
logError(`Error detecting encoding for file ${filePath}: ${error}`)
|
|
234
|
-
return 'utf8'
|
|
235
|
-
} finally {
|
|
236
|
-
if (fd) closeSync(fd)
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const lineEndingCache = new LRUCache<string, LineEndingType>({
|
|
241
|
-
fetchMethod: path => detectLineEndingsDirect(path),
|
|
242
|
-
ttl: 5 * 60 * 1000,
|
|
243
|
-
ttlAutopurge: false,
|
|
244
|
-
max: 1000,
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
export function detectLineEndings(filePath: string): LineEndingType {
|
|
248
|
-
const k = resolve(filePath)
|
|
249
|
-
return fetch(lineEndingCache, k, () => detectLineEndingsDirect(k))
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
export function detectLineEndingsDirect(
|
|
253
|
-
filePath: string,
|
|
254
|
-
encoding: BufferEncoding = 'utf8',
|
|
255
|
-
): LineEndingType {
|
|
256
|
-
try {
|
|
257
|
-
const buffer = Buffer.alloc(4096)
|
|
258
|
-
const fd = openSync(filePath, 'r')
|
|
259
|
-
const bytesRead = readSync(fd, buffer, 0, 4096, 0)
|
|
260
|
-
closeSync(fd)
|
|
261
|
-
|
|
262
|
-
const content = buffer.toString(encoding, 0, bytesRead)
|
|
263
|
-
let crlfCount = 0
|
|
264
|
-
let lfCount = 0
|
|
265
|
-
|
|
266
|
-
for (let i = 0; i < content.length; i++) {
|
|
267
|
-
if (content[i] === '\n') {
|
|
268
|
-
if (i > 0 && content[i - 1] === '\r') {
|
|
269
|
-
crlfCount++
|
|
270
|
-
} else {
|
|
271
|
-
lfCount++
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return crlfCount > lfCount ? 'CRLF' : 'LF'
|
|
277
|
-
} catch (error) {
|
|
278
|
-
logError(`Error detecting line endings for file ${filePath}: ${error}`)
|
|
279
|
-
return 'LF'
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
export function normalizeFilePath(filePath: string): string {
|
|
284
|
-
const absoluteFilePath = isAbsolute(filePath)
|
|
285
|
-
? filePath
|
|
286
|
-
: resolve(getCwd(), filePath)
|
|
287
|
-
|
|
288
|
-
// One weird trick for half-width space characters in MacOS screenshot filenames
|
|
289
|
-
if (absoluteFilePath.endsWith(' AM.png')) {
|
|
290
|
-
return absoluteFilePath.replace(
|
|
291
|
-
' AM.png',
|
|
292
|
-
`${String.fromCharCode(8239)}AM.png`,
|
|
293
|
-
)
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// One weird trick for half-width space characters in MacOS screenshot filenames
|
|
297
|
-
if (absoluteFilePath.endsWith(' PM.png')) {
|
|
298
|
-
return absoluteFilePath.replace(
|
|
299
|
-
' PM.png',
|
|
300
|
-
`${String.fromCharCode(8239)}PM.png`,
|
|
301
|
-
)
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return absoluteFilePath
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
export function getAbsolutePath(path: string | undefined): string | undefined {
|
|
308
|
-
return path ? (isAbsolute(path) ? path : resolve(getCwd(), path)) : undefined
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
export function getAbsoluteAndRelativePaths(path: string | undefined): {
|
|
312
|
-
absolutePath: string | undefined
|
|
313
|
-
relativePath: string | undefined
|
|
314
|
-
} {
|
|
315
|
-
const absolutePath = getAbsolutePath(path)
|
|
316
|
-
const relativePath = absolutePath
|
|
317
|
-
? relative(getCwd(), absolutePath)
|
|
318
|
-
: undefined
|
|
319
|
-
return { absolutePath, relativePath }
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Find files with the same name but different extensions in the same directory
|
|
324
|
-
* @param filePath The path to the file that doesn't exist
|
|
325
|
-
* @returns The found file with a different extension, or undefined if none found
|
|
326
|
-
*/
|
|
327
|
-
|
|
328
|
-
export function findSimilarFile(filePath: string): string | undefined {
|
|
329
|
-
try {
|
|
330
|
-
const dir = dirname(filePath)
|
|
331
|
-
const fileBaseName = basename(filePath, extname(filePath))
|
|
332
|
-
|
|
333
|
-
// Check if directory exists
|
|
334
|
-
if (!existsSync(dir)) {
|
|
335
|
-
return undefined
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// Get all files in the directory
|
|
339
|
-
const files = readdirSync(dir)
|
|
340
|
-
|
|
341
|
-
// Find files with the same base name but different extension
|
|
342
|
-
const similarFiles = files.filter(
|
|
343
|
-
file =>
|
|
344
|
-
basename(file, extname(file)) === fileBaseName &&
|
|
345
|
-
join(dir, file) !== filePath,
|
|
346
|
-
)
|
|
347
|
-
|
|
348
|
-
// Return just the filename of the first match if found
|
|
349
|
-
const firstMatch = similarFiles[0]
|
|
350
|
-
if (firstMatch) {
|
|
351
|
-
return firstMatch
|
|
352
|
-
}
|
|
353
|
-
return undefined
|
|
354
|
-
} catch (error) {
|
|
355
|
-
// In case of any errors, return undefined
|
|
356
|
-
logError(`Error finding similar file for ${filePath}: ${error}`)
|
|
357
|
-
return undefined
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* Adds cat -n style line numbers to the content
|
|
363
|
-
*/
|
|
364
|
-
export function addLineNumbers({
|
|
365
|
-
content,
|
|
366
|
-
// 1-indexed
|
|
367
|
-
startLine,
|
|
368
|
-
}: {
|
|
369
|
-
content: string
|
|
370
|
-
startLine: number
|
|
371
|
-
}): string {
|
|
372
|
-
if (!content) {
|
|
373
|
-
return ''
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
return content
|
|
377
|
-
.split(/\r?\n/)
|
|
378
|
-
.map((line, index) => {
|
|
379
|
-
const lineNum = index + startLine
|
|
380
|
-
const numStr = String(lineNum)
|
|
381
|
-
// Handle large numbers differently
|
|
382
|
-
if (numStr.length >= 6) {
|
|
383
|
-
return `${numStr}\t${line}`
|
|
384
|
-
}
|
|
385
|
-
// Regular numbers get padding to 6 characters
|
|
386
|
-
const n = numStr.padStart(6, ' ')
|
|
387
|
-
return `${n}\t${line}`
|
|
388
|
-
})
|
|
389
|
-
.join('\n') // TODO: This probably won't work for Windows
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
/**
|
|
393
|
-
* Checks if a directory is empty by efficiently reading just the first entry
|
|
394
|
-
* @param dirPath The path to the directory to check
|
|
395
|
-
* @returns true if the directory is empty, false otherwise
|
|
396
|
-
*/
|
|
397
|
-
export function isDirEmpty(dirPath: string): boolean {
|
|
398
|
-
try {
|
|
399
|
-
const entries = readdirSync(dirPath)
|
|
400
|
-
return entries.length === 0
|
|
401
|
-
} catch (error) {
|
|
402
|
-
logError(`Error checking directory: ${error}`)
|
|
403
|
-
return false
|
|
404
|
-
}
|
|
405
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { readTextContent } from './file'
|
|
2
|
-
import { fileFreshnessService } from '../services/fileFreshness'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* File recovery configuration for auto-compact feature
|
|
6
|
-
* These limits ensure recovered files don't overwhelm the compressed context
|
|
7
|
-
*/
|
|
8
|
-
const MAX_FILES_TO_RECOVER = 5
|
|
9
|
-
const MAX_TOKENS_PER_FILE = 10_000
|
|
10
|
-
const MAX_TOTAL_FILE_TOKENS = 50_000
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Selects and reads recently accessed files for context recovery
|
|
14
|
-
*
|
|
15
|
-
* During auto-compact, this function preserves development context by:
|
|
16
|
-
* - Selecting files based on recent access patterns
|
|
17
|
-
* - Enforcing token budgets to prevent context bloat
|
|
18
|
-
* - Truncating large files while preserving essential content
|
|
19
|
-
*
|
|
20
|
-
* @returns Array of file data with content, token counts, and truncation flags
|
|
21
|
-
*/
|
|
22
|
-
export async function selectAndReadFiles(): Promise<
|
|
23
|
-
Array<{
|
|
24
|
-
path: string
|
|
25
|
-
content: string
|
|
26
|
-
tokens: number
|
|
27
|
-
truncated: boolean
|
|
28
|
-
}>
|
|
29
|
-
> {
|
|
30
|
-
const importantFiles =
|
|
31
|
-
fileFreshnessService.getImportantFiles(MAX_FILES_TO_RECOVER)
|
|
32
|
-
const results = []
|
|
33
|
-
let totalTokens = 0
|
|
34
|
-
|
|
35
|
-
for (const fileInfo of importantFiles) {
|
|
36
|
-
try {
|
|
37
|
-
const { content } = readTextContent(fileInfo.path)
|
|
38
|
-
const estimatedTokens = Math.ceil(content.length * 0.25)
|
|
39
|
-
|
|
40
|
-
// Apply per-file token limit to prevent any single file from dominating context
|
|
41
|
-
let finalContent = content
|
|
42
|
-
let truncated = false
|
|
43
|
-
|
|
44
|
-
if (estimatedTokens > MAX_TOKENS_PER_FILE) {
|
|
45
|
-
const maxChars = Math.floor(MAX_TOKENS_PER_FILE / 0.25)
|
|
46
|
-
finalContent = content.substring(0, maxChars)
|
|
47
|
-
truncated = true
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const finalTokens = Math.min(estimatedTokens, MAX_TOKENS_PER_FILE)
|
|
51
|
-
|
|
52
|
-
// Enforce total token budget to maintain auto-compact effectiveness
|
|
53
|
-
if (totalTokens + finalTokens > MAX_TOTAL_FILE_TOKENS) {
|
|
54
|
-
break
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
totalTokens += finalTokens
|
|
58
|
-
results.push({
|
|
59
|
-
path: fileInfo.path,
|
|
60
|
-
content: finalContent,
|
|
61
|
-
tokens: finalTokens,
|
|
62
|
-
truncated,
|
|
63
|
-
})
|
|
64
|
-
} catch (error) {
|
|
65
|
-
// Skip files that cannot be read, don't let one failure stop the process
|
|
66
|
-
console.error(`Failed to read file for recovery: ${fileInfo.path}`, error)
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return results
|
|
71
|
-
}
|
package/src/utils/format.tsx
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
export function wrapText(text: string, width: number): string[] {
|
|
2
|
-
const lines: string[] = []
|
|
3
|
-
let currentLine = ''
|
|
4
|
-
|
|
5
|
-
for (const char of text) {
|
|
6
|
-
// Important: we need the spread to properly count multi-plane UTF-8 characters (eg. 𑚖)
|
|
7
|
-
if ([...currentLine].length < width) {
|
|
8
|
-
currentLine += char
|
|
9
|
-
} else {
|
|
10
|
-
lines.push(currentLine)
|
|
11
|
-
currentLine = char
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (currentLine) lines.push(currentLine)
|
|
16
|
-
return lines
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function formatDuration(ms: number): string {
|
|
20
|
-
if (ms < 60000) {
|
|
21
|
-
return `${(ms / 1000).toFixed(1)}s`
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const hours = Math.floor(ms / 3600000)
|
|
25
|
-
const minutes = Math.floor((ms % 3600000) / 60000)
|
|
26
|
-
const seconds = ((ms % 60000) / 1000).toFixed(1)
|
|
27
|
-
|
|
28
|
-
if (hours > 0) {
|
|
29
|
-
return `${hours}h ${minutes}m ${seconds}s`
|
|
30
|
-
}
|
|
31
|
-
if (minutes > 0) {
|
|
32
|
-
return `${minutes}m ${seconds}s`
|
|
33
|
-
}
|
|
34
|
-
return `${seconds}s`
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function formatNumber(number: number): string {
|
|
38
|
-
return new Intl.NumberFormat('en', {
|
|
39
|
-
notation: 'compact',
|
|
40
|
-
maximumFractionDigits: 1,
|
|
41
|
-
})
|
|
42
|
-
.format(number) // eg. "1321" => "1.3K"
|
|
43
|
-
.toLowerCase() // eg. "1.3K" => "1.3k"
|
|
44
|
-
}
|