@shareai-lab/kode 1.1.14 → 1.1.16-dev.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.
Files changed (289) hide show
  1. package/cli.js +77 -82
  2. package/dist/entrypoints/cli.js +59 -38
  3. package/dist/entrypoints/cli.js.map +3 -3
  4. package/dist/index.js +5 -26
  5. package/dist/package.json +4 -1
  6. package/package.json +11 -104
  7. package/dist/test/testAdapters.js +0 -88
  8. package/dist/test/testAdapters.js.map +0 -1
  9. package/src/ProjectOnboarding.tsx +0 -198
  10. package/src/Tool.ts +0 -83
  11. package/src/commands/agents.tsx +0 -3416
  12. package/src/commands/approvedTools.ts +0 -53
  13. package/src/commands/bug.tsx +0 -20
  14. package/src/commands/clear.ts +0 -43
  15. package/src/commands/compact.ts +0 -120
  16. package/src/commands/config.tsx +0 -19
  17. package/src/commands/cost.ts +0 -18
  18. package/src/commands/ctx_viz.ts +0 -209
  19. package/src/commands/doctor.ts +0 -24
  20. package/src/commands/help.tsx +0 -19
  21. package/src/commands/init.ts +0 -37
  22. package/src/commands/listen.ts +0 -42
  23. package/src/commands/login.tsx +0 -51
  24. package/src/commands/logout.tsx +0 -40
  25. package/src/commands/mcp.ts +0 -41
  26. package/src/commands/model.tsx +0 -40
  27. package/src/commands/modelstatus.tsx +0 -20
  28. package/src/commands/onboarding.tsx +0 -34
  29. package/src/commands/pr_comments.ts +0 -59
  30. package/src/commands/refreshCommands.ts +0 -54
  31. package/src/commands/release-notes.ts +0 -34
  32. package/src/commands/resume.tsx +0 -31
  33. package/src/commands/review.ts +0 -49
  34. package/src/commands/terminalSetup.ts +0 -221
  35. package/src/commands.ts +0 -139
  36. package/src/components/ApproveApiKey.tsx +0 -93
  37. package/src/components/AsciiLogo.tsx +0 -13
  38. package/src/components/AutoUpdater.tsx +0 -148
  39. package/src/components/Bug.tsx +0 -367
  40. package/src/components/Config.tsx +0 -293
  41. package/src/components/ConsoleOAuthFlow.tsx +0 -327
  42. package/src/components/Cost.tsx +0 -23
  43. package/src/components/CostThresholdDialog.tsx +0 -46
  44. package/src/components/CustomSelect/option-map.ts +0 -42
  45. package/src/components/CustomSelect/select-option.tsx +0 -78
  46. package/src/components/CustomSelect/select.tsx +0 -152
  47. package/src/components/CustomSelect/theme.ts +0 -45
  48. package/src/components/CustomSelect/use-select-state.ts +0 -414
  49. package/src/components/CustomSelect/use-select.ts +0 -35
  50. package/src/components/FallbackToolUseRejectedMessage.tsx +0 -15
  51. package/src/components/FileEditToolUpdatedMessage.tsx +0 -66
  52. package/src/components/Help.tsx +0 -215
  53. package/src/components/HighlightedCode.tsx +0 -33
  54. package/src/components/InvalidConfigDialog.tsx +0 -113
  55. package/src/components/Link.tsx +0 -32
  56. package/src/components/LogSelector.tsx +0 -86
  57. package/src/components/Logo.tsx +0 -170
  58. package/src/components/MCPServerApprovalDialog.tsx +0 -100
  59. package/src/components/MCPServerDialogCopy.tsx +0 -25
  60. package/src/components/MCPServerMultiselectDialog.tsx +0 -109
  61. package/src/components/Message.tsx +0 -221
  62. package/src/components/MessageResponse.tsx +0 -15
  63. package/src/components/MessageSelector.tsx +0 -211
  64. package/src/components/ModeIndicator.tsx +0 -88
  65. package/src/components/ModelConfig.tsx +0 -301
  66. package/src/components/ModelListManager.tsx +0 -227
  67. package/src/components/ModelSelector.tsx +0 -3387
  68. package/src/components/ModelStatusDisplay.tsx +0 -230
  69. package/src/components/Onboarding.tsx +0 -274
  70. package/src/components/PressEnterToContinue.tsx +0 -11
  71. package/src/components/PromptInput.tsx +0 -760
  72. package/src/components/SentryErrorBoundary.ts +0 -39
  73. package/src/components/Spinner.tsx +0 -129
  74. package/src/components/StickerRequestForm.tsx +0 -16
  75. package/src/components/StructuredDiff.tsx +0 -191
  76. package/src/components/TextInput.tsx +0 -259
  77. package/src/components/TodoItem.tsx +0 -47
  78. package/src/components/TokenWarning.tsx +0 -31
  79. package/src/components/ToolUseLoader.tsx +0 -40
  80. package/src/components/TrustDialog.tsx +0 -106
  81. package/src/components/binary-feedback/BinaryFeedback.tsx +0 -63
  82. package/src/components/binary-feedback/BinaryFeedbackOption.tsx +0 -111
  83. package/src/components/binary-feedback/BinaryFeedbackView.tsx +0 -172
  84. package/src/components/binary-feedback/utils.ts +0 -220
  85. package/src/components/messages/AssistantBashOutputMessage.tsx +0 -22
  86. package/src/components/messages/AssistantLocalCommandOutputMessage.tsx +0 -49
  87. package/src/components/messages/AssistantRedactedThinkingMessage.tsx +0 -19
  88. package/src/components/messages/AssistantTextMessage.tsx +0 -144
  89. package/src/components/messages/AssistantThinkingMessage.tsx +0 -40
  90. package/src/components/messages/AssistantToolUseMessage.tsx +0 -132
  91. package/src/components/messages/TaskProgressMessage.tsx +0 -32
  92. package/src/components/messages/TaskToolMessage.tsx +0 -58
  93. package/src/components/messages/UserBashInputMessage.tsx +0 -28
  94. package/src/components/messages/UserCommandMessage.tsx +0 -30
  95. package/src/components/messages/UserKodingInputMessage.tsx +0 -28
  96. package/src/components/messages/UserPromptMessage.tsx +0 -35
  97. package/src/components/messages/UserTextMessage.tsx +0 -39
  98. package/src/components/messages/UserToolResultMessage/UserToolCanceledMessage.tsx +0 -12
  99. package/src/components/messages/UserToolResultMessage/UserToolErrorMessage.tsx +0 -36
  100. package/src/components/messages/UserToolResultMessage/UserToolRejectMessage.tsx +0 -31
  101. package/src/components/messages/UserToolResultMessage/UserToolResultMessage.tsx +0 -57
  102. package/src/components/messages/UserToolResultMessage/UserToolSuccessMessage.tsx +0 -35
  103. package/src/components/messages/UserToolResultMessage/utils.tsx +0 -56
  104. package/src/components/permissions/BashPermissionRequest/BashPermissionRequest.tsx +0 -121
  105. package/src/components/permissions/FallbackPermissionRequest.tsx +0 -153
  106. package/src/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.tsx +0 -182
  107. package/src/components/permissions/FileEditPermissionRequest/FileEditToolDiff.tsx +0 -77
  108. package/src/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.tsx +0 -164
  109. package/src/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.tsx +0 -83
  110. package/src/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.tsx +0 -240
  111. package/src/components/permissions/PermissionRequest.tsx +0 -101
  112. package/src/components/permissions/PermissionRequestTitle.tsx +0 -69
  113. package/src/components/permissions/hooks.ts +0 -44
  114. package/src/components/permissions/toolUseOptions.ts +0 -59
  115. package/src/components/permissions/utils.ts +0 -23
  116. package/src/constants/betas.ts +0 -5
  117. package/src/constants/claude-asterisk-ascii-art.tsx +0 -238
  118. package/src/constants/figures.ts +0 -4
  119. package/src/constants/keys.ts +0 -3
  120. package/src/constants/macros.ts +0 -11
  121. package/src/constants/modelCapabilities.ts +0 -179
  122. package/src/constants/models.ts +0 -1025
  123. package/src/constants/oauth.ts +0 -18
  124. package/src/constants/product.ts +0 -17
  125. package/src/constants/prompts.ts +0 -168
  126. package/src/constants/releaseNotes.ts +0 -7
  127. package/src/context/PermissionContext.tsx +0 -149
  128. package/src/context.ts +0 -278
  129. package/src/cost-tracker.ts +0 -84
  130. package/src/entrypoints/cli.tsx +0 -1561
  131. package/src/entrypoints/mcp.ts +0 -175
  132. package/src/history.ts +0 -25
  133. package/src/hooks/useApiKeyVerification.ts +0 -59
  134. package/src/hooks/useArrowKeyHistory.ts +0 -55
  135. package/src/hooks/useCanUseTool.ts +0 -138
  136. package/src/hooks/useCancelRequest.ts +0 -39
  137. package/src/hooks/useDoublePress.ts +0 -41
  138. package/src/hooks/useExitOnCtrlCD.ts +0 -31
  139. package/src/hooks/useInterval.ts +0 -25
  140. package/src/hooks/useLogMessages.ts +0 -16
  141. package/src/hooks/useLogStartupTime.ts +0 -12
  142. package/src/hooks/useNotifyAfterTimeout.ts +0 -65
  143. package/src/hooks/usePermissionRequestLogging.ts +0 -44
  144. package/src/hooks/useTerminalSize.ts +0 -49
  145. package/src/hooks/useTextInput.ts +0 -317
  146. package/src/hooks/useUnifiedCompletion.ts +0 -1405
  147. package/src/index.ts +0 -34
  148. package/src/messages.ts +0 -38
  149. package/src/permissions.ts +0 -268
  150. package/src/query.ts +0 -720
  151. package/src/screens/ConfigureNpmPrefix.tsx +0 -197
  152. package/src/screens/Doctor.tsx +0 -219
  153. package/src/screens/LogList.tsx +0 -68
  154. package/src/screens/REPL.tsx +0 -813
  155. package/src/screens/ResumeConversation.tsx +0 -68
  156. package/src/services/adapters/base.ts +0 -38
  157. package/src/services/adapters/chatCompletions.ts +0 -90
  158. package/src/services/adapters/responsesAPI.ts +0 -170
  159. package/src/services/browserMocks.ts +0 -66
  160. package/src/services/claude.ts +0 -2197
  161. package/src/services/customCommands.ts +0 -704
  162. package/src/services/fileFreshness.ts +0 -377
  163. package/src/services/gpt5ConnectionTest.ts +0 -340
  164. package/src/services/mcpClient.ts +0 -564
  165. package/src/services/mcpServerApproval.tsx +0 -50
  166. package/src/services/mentionProcessor.ts +0 -273
  167. package/src/services/modelAdapterFactory.ts +0 -69
  168. package/src/services/notifier.ts +0 -40
  169. package/src/services/oauth.ts +0 -357
  170. package/src/services/openai.ts +0 -1359
  171. package/src/services/responseStateManager.ts +0 -90
  172. package/src/services/sentry.ts +0 -3
  173. package/src/services/statsig.ts +0 -172
  174. package/src/services/statsigStorage.ts +0 -86
  175. package/src/services/systemReminder.ts +0 -507
  176. package/src/services/vcr.ts +0 -161
  177. package/src/test/testAdapters.ts +0 -96
  178. package/src/tools/ArchitectTool/ArchitectTool.tsx +0 -135
  179. package/src/tools/ArchitectTool/prompt.ts +0 -15
  180. package/src/tools/AskExpertModelTool/AskExpertModelTool.tsx +0 -576
  181. package/src/tools/BashTool/BashTool.tsx +0 -243
  182. package/src/tools/BashTool/BashToolResultMessage.tsx +0 -38
  183. package/src/tools/BashTool/OutputLine.tsx +0 -49
  184. package/src/tools/BashTool/prompt.ts +0 -174
  185. package/src/tools/BashTool/utils.ts +0 -56
  186. package/src/tools/FileEditTool/FileEditTool.tsx +0 -319
  187. package/src/tools/FileEditTool/prompt.ts +0 -51
  188. package/src/tools/FileEditTool/utils.ts +0 -58
  189. package/src/tools/FileReadTool/FileReadTool.tsx +0 -404
  190. package/src/tools/FileReadTool/prompt.ts +0 -7
  191. package/src/tools/FileWriteTool/FileWriteTool.tsx +0 -301
  192. package/src/tools/FileWriteTool/prompt.ts +0 -10
  193. package/src/tools/GlobTool/GlobTool.tsx +0 -119
  194. package/src/tools/GlobTool/prompt.ts +0 -8
  195. package/src/tools/GrepTool/GrepTool.tsx +0 -147
  196. package/src/tools/GrepTool/prompt.ts +0 -11
  197. package/src/tools/MCPTool/MCPTool.tsx +0 -107
  198. package/src/tools/MCPTool/prompt.ts +0 -3
  199. package/src/tools/MemoryReadTool/MemoryReadTool.tsx +0 -127
  200. package/src/tools/MemoryReadTool/prompt.ts +0 -3
  201. package/src/tools/MemoryWriteTool/MemoryWriteTool.tsx +0 -89
  202. package/src/tools/MemoryWriteTool/prompt.ts +0 -3
  203. package/src/tools/MultiEditTool/MultiEditTool.tsx +0 -388
  204. package/src/tools/MultiEditTool/prompt.ts +0 -45
  205. package/src/tools/NotebookEditTool/NotebookEditTool.tsx +0 -298
  206. package/src/tools/NotebookEditTool/prompt.ts +0 -3
  207. package/src/tools/NotebookReadTool/NotebookReadTool.tsx +0 -258
  208. package/src/tools/NotebookReadTool/prompt.ts +0 -3
  209. package/src/tools/StickerRequestTool/StickerRequestTool.tsx +0 -107
  210. package/src/tools/StickerRequestTool/prompt.ts +0 -19
  211. package/src/tools/TaskTool/TaskTool.tsx +0 -438
  212. package/src/tools/TaskTool/constants.ts +0 -1
  213. package/src/tools/TaskTool/prompt.ts +0 -92
  214. package/src/tools/ThinkTool/ThinkTool.tsx +0 -54
  215. package/src/tools/ThinkTool/prompt.ts +0 -12
  216. package/src/tools/TodoWriteTool/TodoWriteTool.tsx +0 -313
  217. package/src/tools/TodoWriteTool/prompt.ts +0 -63
  218. package/src/tools/URLFetcherTool/URLFetcherTool.tsx +0 -178
  219. package/src/tools/URLFetcherTool/cache.ts +0 -55
  220. package/src/tools/URLFetcherTool/htmlToMarkdown.ts +0 -55
  221. package/src/tools/URLFetcherTool/prompt.ts +0 -17
  222. package/src/tools/WebSearchTool/WebSearchTool.tsx +0 -103
  223. package/src/tools/WebSearchTool/prompt.ts +0 -13
  224. package/src/tools/WebSearchTool/searchProviders.ts +0 -66
  225. package/src/tools/lsTool/lsTool.tsx +0 -272
  226. package/src/tools/lsTool/prompt.ts +0 -2
  227. package/src/tools.ts +0 -67
  228. package/src/types/PermissionMode.ts +0 -120
  229. package/src/types/RequestContext.ts +0 -72
  230. package/src/types/common.d.ts +0 -2
  231. package/src/types/conversation.ts +0 -51
  232. package/src/types/logs.ts +0 -58
  233. package/src/types/modelCapabilities.ts +0 -64
  234. package/src/types/notebook.ts +0 -87
  235. package/src/utils/Cursor.ts +0 -436
  236. package/src/utils/PersistentShell.ts +0 -552
  237. package/src/utils/advancedFuzzyMatcher.ts +0 -290
  238. package/src/utils/agentLoader.ts +0 -278
  239. package/src/utils/agentStorage.ts +0 -97
  240. package/src/utils/array.ts +0 -3
  241. package/src/utils/ask.tsx +0 -99
  242. package/src/utils/auth.ts +0 -13
  243. package/src/utils/autoCompactCore.ts +0 -223
  244. package/src/utils/autoUpdater.ts +0 -458
  245. package/src/utils/betas.ts +0 -20
  246. package/src/utils/browser.ts +0 -14
  247. package/src/utils/cleanup.ts +0 -72
  248. package/src/utils/commands.ts +0 -261
  249. package/src/utils/commonUnixCommands.ts +0 -161
  250. package/src/utils/config.ts +0 -945
  251. package/src/utils/conversationRecovery.ts +0 -55
  252. package/src/utils/debugLogger.ts +0 -1235
  253. package/src/utils/diff.ts +0 -42
  254. package/src/utils/env.ts +0 -57
  255. package/src/utils/errors.ts +0 -21
  256. package/src/utils/exampleCommands.ts +0 -109
  257. package/src/utils/execFileNoThrow.ts +0 -51
  258. package/src/utils/expertChatStorage.ts +0 -136
  259. package/src/utils/file.ts +0 -405
  260. package/src/utils/fileRecoveryCore.ts +0 -71
  261. package/src/utils/format.tsx +0 -44
  262. package/src/utils/fuzzyMatcher.ts +0 -328
  263. package/src/utils/generators.ts +0 -62
  264. package/src/utils/git.ts +0 -92
  265. package/src/utils/globalLogger.ts +0 -77
  266. package/src/utils/http.ts +0 -10
  267. package/src/utils/imagePaste.ts +0 -38
  268. package/src/utils/json.ts +0 -13
  269. package/src/utils/log.ts +0 -382
  270. package/src/utils/markdown.ts +0 -213
  271. package/src/utils/messageContextManager.ts +0 -294
  272. package/src/utils/messages.tsx +0 -945
  273. package/src/utils/model.ts +0 -914
  274. package/src/utils/permissions/filesystem.ts +0 -127
  275. package/src/utils/responseState.ts +0 -23
  276. package/src/utils/ripgrep.ts +0 -167
  277. package/src/utils/secureFile.ts +0 -564
  278. package/src/utils/sessionState.ts +0 -49
  279. package/src/utils/state.ts +0 -25
  280. package/src/utils/style.ts +0 -29
  281. package/src/utils/terminal.ts +0 -50
  282. package/src/utils/theme.ts +0 -127
  283. package/src/utils/thinking.ts +0 -144
  284. package/src/utils/todoStorage.ts +0 -431
  285. package/src/utils/tokens.ts +0 -43
  286. package/src/utils/toolExecutionController.ts +0 -163
  287. package/src/utils/unaryLogging.ts +0 -26
  288. package/src/utils/user.ts +0 -37
  289. package/src/utils/validate.ts +0 -165
@@ -1,458 +0,0 @@
1
- import { homedir } from 'os'
2
- import { join } from 'path'
3
- import {
4
- existsSync,
5
- mkdirSync,
6
- appendFileSync,
7
- readFileSync,
8
- constants,
9
- writeFileSync,
10
- unlinkSync,
11
- statSync,
12
- } from 'fs'
13
- import { platform } from 'process'
14
- import { execFileNoThrow } from './execFileNoThrow'
15
- import { spawn } from 'child_process'
16
- import { logError } from './log'
17
- import { accessSync } from 'fs'
18
- import { CLAUDE_BASE_DIR } from './env'
19
- import { logEvent, getDynamicConfig } from '../services/statsig'
20
- import { lt, gt } from 'semver'
21
- import { MACRO } from '../constants/macros'
22
- import { PRODUCT_COMMAND, PRODUCT_NAME } from '../constants/product'
23
- import { getGlobalConfig, saveGlobalConfig, isAutoUpdaterDisabled } from './config'
24
- import { env } from './env'
25
- export type InstallStatus =
26
- | 'success'
27
- | 'no_permissions'
28
- | 'install_failed'
29
- | 'in_progress'
30
-
31
- export type AutoUpdaterResult = {
32
- version: string | null
33
- status: InstallStatus
34
- }
35
-
36
- export type VersionConfig = {
37
- minVersion: string
38
- }
39
-
40
- /**
41
- * Checks if the current version meets the minimum required version from Statsig config
42
- * Terminates the process with an error message if the version is too old
43
- */
44
- export async function assertMinVersion(): Promise<void> {
45
- try {
46
- const versionConfig = await getDynamicConfig<VersionConfig>(
47
- 'tengu_version_config',
48
- { minVersion: '0.0.0' },
49
- )
50
-
51
- if (
52
- versionConfig.minVersion &&
53
- lt(MACRO.VERSION, versionConfig.minVersion)
54
- ) {
55
- const suggestions = await getUpdateCommandSuggestions()
56
- const cmdLines = suggestions.map(c => ` ${c}`).join('\n')
57
- console.error(`
58
- 您的 ${PRODUCT_NAME} 版本 (${MACRO.VERSION}) 过低,需要升级到 ${versionConfig.minVersion} 或更高版本。
59
- 请手动执行以下任一命令进行升级:
60
- ${cmdLines}
61
- `)
62
- process.exit(1)
63
- }
64
- } catch (error) {
65
- logError(`Error checking minimum version: ${error}`)
66
- }
67
- }
68
-
69
- // Lock file for auto-updater to prevent concurrent updates
70
- export const LOCK_FILE_PATH = join(CLAUDE_BASE_DIR, '.update.lock')
71
- const LOCK_TIMEOUT_MS = 5 * 60 * 1000 // 5 minute timeout for locks
72
-
73
- /**
74
- * Attempts to acquire a lock for auto-updater
75
- * @returns {boolean} true if lock was acquired, false if another process holds the lock
76
- */
77
- function acquireLock(): boolean {
78
- try {
79
- // Ensure the base directory exists
80
- if (!existsSync(CLAUDE_BASE_DIR)) {
81
- mkdirSync(CLAUDE_BASE_DIR, { recursive: true })
82
- }
83
-
84
- // Check if lock file exists and is not stale
85
- if (existsSync(LOCK_FILE_PATH)) {
86
- const stats = statSync(LOCK_FILE_PATH)
87
- const age = Date.now() - stats.mtimeMs
88
-
89
- // If lock file is older than timeout, consider it stale
90
- if (age < LOCK_TIMEOUT_MS) {
91
- return false
92
- }
93
-
94
- // Lock is stale, we can take over
95
- try {
96
- unlinkSync(LOCK_FILE_PATH)
97
- } catch (err) {
98
- logError(`Failed to remove stale lock file: ${err}`)
99
- return false
100
- }
101
- }
102
-
103
- // Create lock file with current pid
104
- writeFileSync(LOCK_FILE_PATH, `${process.pid}`, 'utf8')
105
- return true
106
- } catch (err) {
107
- logError(`Failed to acquire lock: ${err}`)
108
- return false
109
- }
110
- }
111
-
112
- /**
113
- * Releases the update lock if it's held by this process
114
- */
115
- function releaseLock(): void {
116
- try {
117
- if (existsSync(LOCK_FILE_PATH)) {
118
- const lockData = readFileSync(LOCK_FILE_PATH, 'utf8')
119
- if (lockData === `${process.pid}`) {
120
- unlinkSync(LOCK_FILE_PATH)
121
- }
122
- }
123
- } catch (err) {
124
- logError(`Failed to release lock: ${err}`)
125
- }
126
- }
127
-
128
- export async function checkNpmPermissions(): Promise<{
129
- hasPermissions: boolean
130
- npmPrefix: string | null
131
- }> {
132
- try {
133
- const prefixResult = await execFileNoThrow('npm', [
134
- '-g',
135
- 'config',
136
- 'get',
137
- 'prefix',
138
- ])
139
- if (prefixResult.code !== 0) {
140
- logError('Failed to check npm permissions')
141
- return { hasPermissions: false, npmPrefix: null }
142
- }
143
-
144
- const prefix = prefixResult.stdout.trim()
145
-
146
- let testWriteResult = false
147
- try {
148
- accessSync(prefix, constants.W_OK)
149
- testWriteResult = true
150
- } catch {
151
- testWriteResult = false
152
- }
153
-
154
- if (testWriteResult) {
155
- return { hasPermissions: true, npmPrefix: prefix }
156
- }
157
-
158
- logError('Insufficient permissions for global npm install.')
159
- return { hasPermissions: false, npmPrefix: prefix }
160
- } catch (error) {
161
- logError(`Failed to verify npm global install permissions: ${error}`)
162
- return { hasPermissions: false, npmPrefix: null }
163
- }
164
- }
165
-
166
- export async function setupNewPrefix(prefix: string): Promise<void> {
167
- if (!acquireLock()) {
168
- // Log the lock contention to statsig
169
- logEvent('tengu_auto_updater_prefix_lock_contention', {
170
- pid: String(process.pid),
171
- currentVersion: MACRO.VERSION,
172
- prefix,
173
- })
174
- throw new Error('Another process is currently setting up npm prefix')
175
- }
176
-
177
- try {
178
- // Create directory if it doesn't exist
179
- if (!existsSync(prefix)) {
180
- mkdirSync(prefix, { recursive: true })
181
- }
182
-
183
- // Set npm prefix
184
- const setPrefix = await execFileNoThrow('npm', [
185
- '-g',
186
- 'config',
187
- 'set',
188
- 'prefix',
189
- prefix,
190
- ])
191
-
192
- if (setPrefix.code !== 0) {
193
- throw new Error(`Failed to set npm prefix: ${setPrefix.stderr}`)
194
- }
195
-
196
- // Update shell config files
197
- const pathUpdate = `\n# npm global path\nexport PATH="${prefix}/bin:$PATH"\n`
198
-
199
- if (platform === 'win32') {
200
- // On Windows, update user PATH environment variable
201
- const setxResult = await execFileNoThrow('setx', [
202
- 'PATH',
203
- `${process.env.PATH};${prefix}`,
204
- ])
205
- if (setxResult.code !== 0) {
206
- throw new Error(
207
- `Failed to update PATH on Windows: ${setxResult.stderr}`,
208
- )
209
- }
210
- } else {
211
- // Unix-like systems
212
- const shellConfigs = [
213
- // Bash
214
- join(homedir(), '.bashrc'),
215
- join(homedir(), '.bash_profile'),
216
- // Zsh
217
- join(homedir(), '.zshrc'),
218
- // Fish
219
- join(homedir(), '.config', 'fish', 'config.fish'),
220
- ]
221
-
222
- for (const config of shellConfigs) {
223
- if (existsSync(config)) {
224
- try {
225
- const content = readFileSync(config, 'utf8')
226
- if (!content.includes(prefix)) {
227
- if (config.includes('fish')) {
228
- // Fish shell has different syntax
229
- const fishPath = `\n# npm global path\nset -gx PATH ${prefix}/bin $PATH\n`
230
- appendFileSync(config, fishPath)
231
- } else {
232
- appendFileSync(config, pathUpdate)
233
- }
234
-
235
- logEvent('npm_prefix_path_updated', {
236
- configPath: config,
237
- })
238
- }
239
- } catch (err) {
240
- // Log but don't throw - continue with other configs
241
- logEvent('npm_prefix_path_update_failed', {
242
- configPath: config,
243
- error:
244
- err instanceof Error
245
- ? err.message.slice(0, 200)
246
- : String(err).slice(0, 200),
247
- })
248
- logError(`Failed to update shell config ${config}: ${err}`)
249
- }
250
- }
251
- }
252
- }
253
- } finally {
254
- releaseLock()
255
- }
256
- }
257
-
258
- export function getDefaultNpmPrefix(): string {
259
- return join(homedir(), '.npm-global')
260
- }
261
-
262
- export function getPermissionsCommand(npmPrefix: string): string {
263
- const windowsCommand = `icacls "${npmPrefix}" /grant "%USERNAME%:(OI)(CI)F"`
264
- const prefixPath = npmPrefix || '$(npm -g config get prefix)'
265
- const unixCommand = `sudo chown -R $USER:$(id -gn) ${prefixPath} && sudo chmod -R u+w ${prefixPath}`
266
-
267
- return platform === 'win32' ? windowsCommand : unixCommand
268
- }
269
-
270
- export async function getLatestVersion(): Promise<string | null> {
271
- // 1) Try npm CLI (fast when available)
272
- try {
273
- const abortController = new AbortController()
274
- setTimeout(() => abortController.abort(), 5000)
275
- const result = await execFileNoThrow(
276
- 'npm',
277
- ['view', MACRO.PACKAGE_URL, 'version'],
278
- abortController.signal,
279
- )
280
- if (result.code === 0) {
281
- const v = result.stdout.trim()
282
- if (v) return v
283
- }
284
- } catch {}
285
-
286
- // 2) Fallback: fetch npm registry (works in Bun/Node without npm)
287
- try {
288
- const controller = new AbortController()
289
- const timer = setTimeout(() => controller.abort(), 5000)
290
- const res = await fetch(
291
- `https://registry.npmjs.org/${encodeURIComponent(MACRO.PACKAGE_URL)}`,
292
- {
293
- method: 'GET',
294
- headers: {
295
- Accept: 'application/vnd.npm.install-v1+json',
296
- 'User-Agent': `${PRODUCT_NAME}/${MACRO.VERSION}`,
297
- },
298
- signal: controller.signal,
299
- },
300
- )
301
- clearTimeout(timer)
302
- if (!res.ok) return null
303
- const json: any = await res.json().catch(() => null)
304
- const latest = json && json['dist-tags'] && json['dist-tags'].latest
305
- return typeof latest === 'string' ? latest : null
306
- } catch {
307
- return null
308
- }
309
- }
310
-
311
- export async function installGlobalPackage(): Promise<InstallStatus> {
312
- // Detect preferred package manager and install accordingly
313
- if (!acquireLock()) {
314
- logError('Another process is currently installing an update')
315
- // Log the lock contention to statsig
316
- logEvent('tengu_auto_updater_lock_contention', {
317
- pid: String(process.pid),
318
- currentVersion: MACRO.VERSION,
319
- })
320
- return 'in_progress'
321
- }
322
-
323
- try {
324
- const manager = await detectPackageManager()
325
- if (manager === 'npm') {
326
- const { hasPermissions } = await checkNpmPermissions()
327
- if (!hasPermissions) {
328
- return 'no_permissions'
329
- }
330
- // Stream实时输出,减少用户等待感
331
- const code = await runStreaming('npm', ['install', '-g', MACRO.PACKAGE_URL])
332
- if (code !== 0) {
333
- logError(`Failed to install new version via npm (exit ${code})`)
334
- return 'install_failed'
335
- }
336
- return 'success'
337
- }
338
-
339
- if (manager === 'bun') {
340
- const code = await runStreaming('bun', ['add', '-g', `${MACRO.PACKAGE_URL}@latest`])
341
- if (code !== 0) {
342
- logError(`Failed to install new version via bun (exit ${code})`)
343
- return 'install_failed'
344
- }
345
- return 'success'
346
- }
347
-
348
- // Fallback to npm if unknown
349
- const { hasPermissions } = await checkNpmPermissions()
350
- if (!hasPermissions) return 'no_permissions'
351
- const code = await runStreaming('npm', ['install', '-g', MACRO.PACKAGE_URL])
352
- if (code !== 0) return 'install_failed'
353
- return 'success'
354
- } finally {
355
- // Ensure we always release the lock
356
- releaseLock()
357
- }
358
- }
359
-
360
- export type PackageManager = 'npm' | 'bun'
361
-
362
- export async function detectPackageManager(): Promise<PackageManager> {
363
- // Respect explicit override if provided later via config/env (future-proof)
364
- try {
365
- // Heuristic 1: npm available and global root resolvable
366
- const npmRoot = await execFileNoThrow('npm', ['-g', 'root'])
367
- if (npmRoot.code === 0 && npmRoot.stdout.trim()) {
368
- return 'npm'
369
- }
370
- } catch {}
371
-
372
- try {
373
- // Heuristic 2: running on a system with bun and installed path hints bun
374
- const bunVer = await execFileNoThrow('bun', ['--version'])
375
- if (bunVer.code === 0) {
376
- // BUN_INSTALL defaults to ~/.bun; if our package lives under that tree, prefer bun
377
- // If npm not detected but bun is available, choose bun
378
- return 'bun'
379
- }
380
- } catch {}
381
-
382
- // Default to npm when uncertain
383
- return 'npm'
384
- }
385
-
386
- function runStreaming(cmd: string, args: string[]): Promise<number> {
387
- return new Promise(resolve => {
388
- // 打印正在使用的包管理器与命令,增强透明度
389
- try {
390
- // eslint-disable-next-line no-console
391
- console.log(`> ${cmd} ${args.join(' ')}`)
392
- } catch {}
393
-
394
- const child = spawn(cmd, args, {
395
- stdio: 'inherit',
396
- env: process.env,
397
- })
398
- child.on('close', code => resolve(code ?? 0))
399
- child.on('error', () => resolve(1))
400
- })
401
- }
402
-
403
- /**
404
- * Generate human-friendly update commands for the detected package manager.
405
- * Also includes an alternative manager command as fallback for users.
406
- */
407
- export async function getUpdateCommandSuggestions(): Promise<string[]> {
408
- // Prefer Bun first, then npm (consistent, simple UX). Include @latest.
409
- return [
410
- `bun add -g ${MACRO.PACKAGE_URL}@latest`,
411
- `npm install -g ${MACRO.PACKAGE_URL}@latest`,
412
- ]
413
- }
414
-
415
- /**
416
- * Non-blocking update notifier (daily)
417
- * - Respects CI and disabled auto-updater
418
- * - Uses env.hasInternetAccess() to quickly skip offline cases
419
- * - Stores last check timestamp + last suggested version in global config
420
- */
421
- export async function checkAndNotifyUpdate(): Promise<void> {
422
- try {
423
- if (process.env.NODE_ENV === 'test') return
424
- if (await isAutoUpdaterDisabled()) return
425
- if (await env.getIsDocker()) return
426
- if (!(await env.hasInternetAccess())) return
427
-
428
- const config: any = getGlobalConfig()
429
- const now = Date.now()
430
- const DAY_MS = 24 * 60 * 60 * 1000
431
- const lastCheck = Number(config.lastUpdateCheckAt || 0)
432
- if (lastCheck && now - lastCheck < DAY_MS) return
433
-
434
- const latest = await getLatestVersion()
435
- if (!latest) {
436
- // Still record the check to avoid spamming
437
- saveGlobalConfig({ ...config, lastUpdateCheckAt: now })
438
- return
439
- }
440
-
441
- if (gt(latest, MACRO.VERSION)) {
442
- // Update stored state and print a low-noise hint
443
- saveGlobalConfig({
444
- ...config,
445
- lastUpdateCheckAt: now,
446
- lastSuggestedVersion: latest,
447
- })
448
- const suggestions = await getUpdateCommandSuggestions()
449
- const first = suggestions[0]
450
- console.log(`New version available: ${latest}. Recommended: ${first}`)
451
- } else {
452
- saveGlobalConfig({ ...config, lastUpdateCheckAt: now })
453
- }
454
- } catch (error) {
455
- // Never block or throw; just log and move on
456
- logError(`update-notify: ${error}`)
457
- }
458
- }
@@ -1,20 +0,0 @@
1
- import { memoize } from 'lodash-es'
2
- import { checkGate } from '../services/statsig'
3
- import {
4
- GATE_TOKEN_EFFICIENT_TOOLS,
5
- BETA_HEADER_TOKEN_EFFICIENT_TOOLS,
6
- CLAUDE_CODE_20250219_BETA_HEADER,
7
- } from '../constants/betas.js'
8
-
9
- export const getBetas = memoize(async (): Promise<string[]> => {
10
- const betaHeaders = [CLAUDE_CODE_20250219_BETA_HEADER]
11
-
12
- if (process.env.USER_TYPE === 'ant' || process.env.SWE_BENCH) {
13
- const useTokenEfficientTools = await checkGate(GATE_TOKEN_EFFICIENT_TOOLS)
14
- if (useTokenEfficientTools) {
15
- betaHeaders.push(BETA_HEADER_TOKEN_EFFICIENT_TOOLS)
16
- }
17
- }
18
-
19
- return betaHeaders
20
- })
@@ -1,14 +0,0 @@
1
- import { execFileNoThrow } from './execFileNoThrow'
2
-
3
- export async function openBrowser(url: string): Promise<boolean> {
4
- const platform = process.platform
5
- const command =
6
- platform === 'win32' ? 'start' : platform === 'darwin' ? 'open' : 'xdg-open'
7
-
8
- try {
9
- const { code } = await execFileNoThrow(command, [url])
10
- return code === 0
11
- } catch (_) {
12
- return false
13
- }
14
- }
@@ -1,72 +0,0 @@
1
- import { promises as fs } from 'fs'
2
- import { join } from 'path'
3
- import { logError } from './log'
4
- import { CACHE_PATHS } from './log'
5
-
6
- const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000
7
-
8
- export type CleanupResult = {
9
- messages: number
10
- errors: number
11
- }
12
-
13
- export function convertFileNameToDate(filename: string): Date {
14
- const isoStr = filename
15
- .split('.')[0]!
16
- .replace(/T(\d{2})-(\d{2})-(\d{2})-(\d{3})Z/, 'T$1:$2:$3.$4Z')
17
- return new Date(isoStr)
18
- }
19
-
20
- export async function cleanupOldMessageFiles(): Promise<CleanupResult> {
21
- const messagePath = CACHE_PATHS.messages()
22
- const errorPath = CACHE_PATHS.errors()
23
- const thirtyDaysAgo = new Date(Date.now() - THIRTY_DAYS_MS)
24
- const deletedCounts: CleanupResult = { messages: 0, errors: 0 }
25
-
26
- for (const path of [messagePath, errorPath]) {
27
- try {
28
- const files = await fs.readdir(path)
29
-
30
- for (const file of files) {
31
- try {
32
- // Convert filename format where all ':.' were replaced with '-'
33
- const timestamp = convertFileNameToDate(file)
34
- if (timestamp < thirtyDaysAgo) {
35
- await fs.unlink(join(path, file))
36
- // Increment the appropriate counter
37
- if (path === messagePath) {
38
- deletedCounts.messages++
39
- } else {
40
- deletedCounts.errors++
41
- }
42
- }
43
- } catch (error: unknown) {
44
- // Log but continue processing other files
45
- logError(
46
- `Failed to process file ${file}: ${error instanceof Error ? error.message : String(error)}`,
47
- )
48
- }
49
- }
50
- } catch (error: unknown) {
51
- // Ignore if directory doesn't exist
52
- if (
53
- error instanceof Error &&
54
- 'code' in error &&
55
- error.code !== 'ENOENT'
56
- ) {
57
- logError(
58
- `Failed to cleanup directory ${path}: ${error instanceof Error ? error.message : String(error)}`,
59
- )
60
- }
61
- }
62
- }
63
-
64
- return deletedCounts
65
- }
66
-
67
- export function cleanupOldMessageFilesInBackground(): void {
68
- const immediate = setImmediate(cleanupOldMessageFiles)
69
-
70
- // Prevent the setImmediate from keeping the process alive
71
- immediate.unref()
72
- }