@shareai-lab/kode 1.1.23-dev.1 → 1.1.23

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/screens/REPL.tsx"],
4
- "sourcesContent": ["import { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { Box, Newline, Static, Text } from 'ink'\nimport ProjectOnboarding, {\n markProjectOnboardingComplete,\n} from '../ProjectOnboarding.js'\nimport { CostThresholdDialog } from '../components/CostThresholdDialog'\nimport * as React from 'react'\nimport { useEffect, useMemo, useRef, useState, useCallback } from 'react'\nimport { Command } from '../commands'\nimport { Logo } from '../components/Logo'\nimport { Message } from '../components/Message'\nimport { MessageResponse } from '../components/MessageResponse'\nimport { MessageSelector } from '../components/MessageSelector'\nimport {\n PermissionRequest,\n type ToolUseConfirm,\n} from '../components/permissions/PermissionRequest.js'\nimport PromptInput from '../components/PromptInput'\nimport { Spinner } from '../components/Spinner'\nimport { getSystemPrompt } from '../constants/prompts'\nimport { getContext } from '../context'\nimport { getTotalCost, useCostSummary } from '../cost-tracker'\nimport { useLogStartupTime } from '../hooks/useLogStartupTime'\nimport { addToHistory } from '../history'\nimport { useApiKeyVerification } from '../hooks/useApiKeyVerification'\nimport { useCancelRequest } from '../hooks/useCancelRequest'\nimport useCanUseTool from '../hooks/useCanUseTool'\nimport { useLogMessages } from '../hooks/useLogMessages'\nimport { PermissionProvider } from '../context/PermissionContext'\nimport { ModeIndicator } from '../components/ModeIndicator'\nimport {\n setMessagesGetter,\n setMessagesSetter,\n setModelConfigChangeHandler,\n} from '../messages'\nimport {\n type AssistantMessage,\n type BinaryFeedbackResult,\n type Message as MessageType,\n type ProgressMessage,\n query,\n} from '../query.js'\nimport type { WrappedClient } from '../services/mcpClient'\nimport type { Tool } from '../Tool'\n// Auto-updater removed; only show a new version banner passed from CLI\nimport { getGlobalConfig, saveGlobalConfig } from '../utils/config'\nimport { MACRO } from '../constants/macros'\nimport { logEvent } from '../services/statsig'\nimport { getNextAvailableLogForkNumber } from '../utils/log'\nimport {\n getErroredToolUseMessages,\n getInProgressToolUseIDs,\n getLastAssistantMessageId,\n getToolUseID,\n getUnresolvedToolUseIDs,\n INTERRUPT_MESSAGE,\n isNotEmptyMessage,\n type NormalizedMessage,\n normalizeMessages,\n normalizeMessagesForAPI,\n processUserInput,\n reorderMessages,\n extractTag,\n createAssistantMessage,\n} from '../utils/messages.js'\nimport { getModelManager, ModelManager } from '../utils/model'\nimport { clearTerminal, updateTerminalTitle } from '../utils/terminal'\nimport { BinaryFeedback } from '../components/binary-feedback/BinaryFeedback'\nimport { getMaxThinkingTokens } from '../utils/thinking'\nimport { getOriginalCwd } from '../utils/state'\nimport { handleHashCommand } from '../commands/terminalSetup'\nimport { debug as debugLogger } from '../utils/debugLogger'\n\ntype Props = {\n commands: Command[]\n safeMode?: boolean\n debug?: boolean\n initialForkNumber?: number | undefined\n initialPrompt: string | undefined\n // A unique name for the message log file, used to identify the fork\n messageLogName: string\n shouldShowPromptInput: boolean\n tools: Tool[]\n verbose: boolean | undefined\n // Initial messages to populate the REPL with\n initialMessages?: MessageType[]\n // MCP clients\n mcpClients?: WrappedClient[]\n // Flag to indicate if current model is default\n isDefaultModel?: boolean\n // Update banner info passed from CLI before first render\n initialUpdateVersion?: string | null\n initialUpdateCommands?: string[] | null\n}\n\nexport type BinaryFeedbackContext = {\n m1: AssistantMessage\n m2: AssistantMessage\n resolve: (result: BinaryFeedbackResult) => void\n}\n\nexport function REPL({\n commands,\n safeMode,\n debug = false,\n initialForkNumber = 0,\n initialPrompt,\n messageLogName,\n shouldShowPromptInput,\n tools,\n verbose: verboseFromCLI,\n initialMessages,\n mcpClients = [],\n isDefaultModel = true,\n initialUpdateVersion,\n initialUpdateCommands,\n}: Props): React.ReactNode {\n // Cache verbose config to avoid synchronous file reads on every render\n const [verboseConfig] = useState(() => verboseFromCLI ?? getGlobalConfig().verbose)\n const verbose = verboseConfig\n\n // Used to force the logo to re-render and conversation log to use a new file\n const [forkNumber, setForkNumber] = useState(\n getNextAvailableLogForkNumber(messageLogName, initialForkNumber, 0),\n )\n\n const [\n forkConvoWithMessagesOnTheNextRender,\n setForkConvoWithMessagesOnTheNextRender,\n ] = useState<MessageType[] | null>(null)\n\n // \uD83D\uDD27 Simplified AbortController management - inspired by reference system\n const [abortController, setAbortController] = useState<AbortController | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n // No auto-updater state\n const [toolJSX, setToolJSX] = useState<{\n jsx: React.ReactNode | null\n shouldHidePromptInput: boolean\n } | null>(null)\n const [toolUseConfirm, setToolUseConfirm] = useState<ToolUseConfirm | null>(\n null,\n )\n const [messages, setMessages] = useState<MessageType[]>(initialMessages ?? [])\n const [inputValue, setInputValue] = useState('')\n const [inputMode, setInputMode] = useState<'bash' | 'prompt' | 'koding'>(\n 'prompt',\n )\n const [submitCount, setSubmitCount] = useState(0)\n const [isMessageSelectorVisible, setIsMessageSelectorVisible] =\n useState(false)\n const [showCostDialog, setShowCostDialog] = useState(false)\n const [haveShownCostDialog, setHaveShownCostDialog] = useState(\n getGlobalConfig().hasAcknowledgedCostThreshold,\n )\n\n const [binaryFeedbackContext, setBinaryFeedbackContext] =\n useState<BinaryFeedbackContext | null>(null)\n // New version banner: passed in from CLI to guarantee top placement\n const updateAvailableVersion = initialUpdateVersion ?? null\n const updateCommands = initialUpdateCommands ?? null\n // No separate Static for banner; it renders inside Logo\n\n const getBinaryFeedbackResponse = useCallback(\n (\n m1: AssistantMessage,\n m2: AssistantMessage,\n ): Promise<BinaryFeedbackResult> => {\n return new Promise<BinaryFeedbackResult>(resolvePromise => {\n setBinaryFeedbackContext({\n m1,\n m2,\n resolve: resolvePromise,\n })\n })\n },\n [],\n )\n\n const readFileTimestamps = useRef<{\n [filename: string]: number\n }>({})\n\n const { status: apiKeyStatus, reverify } = useApiKeyVerification()\n function onCancel() {\n if (!isLoading) {\n return\n }\n setIsLoading(false)\n if (toolUseConfirm) {\n toolUseConfirm.onAbort()\n } else if (abortController && !abortController.signal.aborted) {\n abortController.abort()\n }\n }\n\n useCancelRequest(\n setToolJSX,\n setToolUseConfirm,\n setBinaryFeedbackContext,\n onCancel,\n isLoading,\n isMessageSelectorVisible,\n abortController?.signal,\n )\n\n useEffect(() => {\n if (forkConvoWithMessagesOnTheNextRender) {\n setForkNumber(_ => _ + 1)\n setForkConvoWithMessagesOnTheNextRender(null)\n setMessages(forkConvoWithMessagesOnTheNextRender)\n }\n }, [forkConvoWithMessagesOnTheNextRender])\n\n useEffect(() => {\n const totalCost = getTotalCost()\n if (totalCost >= 5 /* $5 */ && !showCostDialog && !haveShownCostDialog) {\n logEvent('tengu_cost_threshold_reached', {})\n setShowCostDialog(true)\n }\n }, [messages, showCostDialog, haveShownCostDialog])\n\n // Update banner is provided by CLI at startup; no async check here.\n\n const canUseTool = useCanUseTool(setToolUseConfirm)\n\n async function onInit() {\n reverify()\n\n if (!initialPrompt) {\n return\n }\n\n setIsLoading(true)\n\n const newAbortController = new AbortController()\n setAbortController(newAbortController)\n\n // \uD83D\uDD27 Force fresh config read to ensure model switching works\n const model = new ModelManager(getGlobalConfig()).getModelName('main')\n const newMessages = await processUserInput(\n initialPrompt,\n 'prompt',\n setToolJSX,\n {\n abortController: newAbortController,\n options: {\n commands,\n forkNumber,\n messageLogName,\n tools,\n verbose,\n maxThinkingTokens: 0,\n },\n messageId: getLastAssistantMessageId(messages),\n setForkConvoWithMessagesOnTheNextRender,\n readFileTimestamps: readFileTimestamps.current,\n },\n null,\n )\n\n if (newMessages.length) {\n for (const message of newMessages) {\n if (message.type === 'user') {\n addToHistory(initialPrompt)\n // TODO: setHistoryIndex\n }\n }\n setMessages(_ => [..._, ...newMessages])\n\n // The last message is an assistant message if the user input was a bash command,\n // or if the user input was an invalid slash command.\n const lastMessage = newMessages[newMessages.length - 1]!\n if (lastMessage.type === 'assistant') {\n setAbortController(null)\n setIsLoading(false)\n return\n }\n\n const [systemPrompt, context, model, maxThinkingTokens] =\n await Promise.all([\n getSystemPrompt(),\n getContext(),\n new ModelManager(getGlobalConfig()).getModelName('main'),\n getMaxThinkingTokens([...messages, ...newMessages]),\n ])\n\n for await (const message of query(\n [...messages, ...newMessages],\n systemPrompt,\n context,\n canUseTool,\n {\n options: {\n commands,\n forkNumber,\n messageLogName,\n tools,\n verbose,\n safeMode,\n maxThinkingTokens,\n },\n messageId: getLastAssistantMessageId([...messages, ...newMessages]),\n readFileTimestamps: readFileTimestamps.current,\n abortController: newAbortController,\n setToolJSX,\n },\n getBinaryFeedbackResponse,\n )) {\n setMessages(oldMessages => [...oldMessages, message])\n }\n } else {\n addToHistory(initialPrompt)\n // TODO: setHistoryIndex\n }\n\n setHaveShownCostDialog(\n getGlobalConfig().hasAcknowledgedCostThreshold || false,\n )\n\n // \uD83D\uDD27 Fix: Clean up state after onInit completion\n setIsLoading(false)\n setAbortController(null)\n }\n\n async function onQuery(newMessages: MessageType[], passedAbortController?: AbortController) {\n // Use passed AbortController or create new one\n const controllerToUse = passedAbortController || new AbortController()\n if (!passedAbortController) {\n setAbortController(controllerToUse)\n }\n\n // Check if this is a Koding request based on last message's options\n const isKodingRequest =\n newMessages.length > 0 &&\n newMessages[0].type === 'user' &&\n 'options' in newMessages[0] &&\n newMessages[0].options?.isKodingRequest === true\n\n setMessages(oldMessages => [...oldMessages, ...newMessages])\n\n // Mark onboarding as complete when any user message is sent to Claude\n markProjectOnboardingComplete()\n\n // The last message is an assistant message if the user input was a bash command,\n // or if the user input was an invalid slash command.\n const lastMessage = newMessages[newMessages.length - 1]!\n\n // Update terminal title based on user message\n if (\n lastMessage.type === 'user' &&\n typeof lastMessage.message.content === 'string'\n ) {\n // updateTerminalTitle(lastMessage.message.content)\n }\n if (lastMessage.type === 'assistant') {\n setAbortController(null)\n setIsLoading(false)\n return\n }\n\n const [systemPrompt, context, model, maxThinkingTokens] =\n await Promise.all([\n getSystemPrompt(),\n getContext(),\n new ModelManager(getGlobalConfig()).getModelName('main'),\n getMaxThinkingTokens([...messages, lastMessage]),\n ])\n\n let lastAssistantMessage: MessageType | null = null\n\n // query the API\n for await (const message of query(\n [...messages, lastMessage],\n systemPrompt,\n context,\n canUseTool,\n {\n options: {\n commands,\n forkNumber,\n messageLogName,\n tools,\n verbose,\n safeMode,\n maxThinkingTokens,\n // If this came from Koding mode, pass that along\n isKodingRequest: isKodingRequest || undefined,\n },\n messageId: getLastAssistantMessageId([...messages, lastMessage]),\n readFileTimestamps: readFileTimestamps.current,\n abortController: controllerToUse,\n setToolJSX,\n },\n getBinaryFeedbackResponse,\n )) {\n setMessages(oldMessages => [...oldMessages, message])\n\n // Keep track of the last assistant message for Koding mode\n if (message.type === 'assistant') {\n lastAssistantMessage = message\n }\n }\n\n // If this was a Koding request and we got an assistant message back,\n // save it to AGENTS.md (and CLAUDE.md if exists)\n if (\n isKodingRequest &&\n lastAssistantMessage &&\n lastAssistantMessage.type === 'assistant'\n ) {\n try {\n const content =\n typeof lastAssistantMessage.message.content === 'string'\n ? lastAssistantMessage.message.content\n : lastAssistantMessage.message.content\n .filter(block => block.type === 'text')\n .map(block => (block.type === 'text' ? block.text : ''))\n .join('\\n')\n\n // Add the content to AGENTS.md (and CLAUDE.md if exists)\n if (content && content.trim().length > 0) {\n handleHashCommand(content)\n }\n } catch (error) {\n console.error('Error saving response to project docs:', error)\n }\n }\n\n setIsLoading(false)\n }\n\n // Register cost summary tracker\n useCostSummary()\n\n // Register messages getter and setter\n useEffect(() => {\n const getMessages = () => messages\n setMessagesGetter(getMessages)\n setMessagesSetter(setMessages)\n }, [messages])\n\n // Register model config change handler for UI refresh\n useEffect(() => {\n setModelConfigChangeHandler(() => {\n setForkNumber(prev => prev + 1)\n })\n }, [])\n\n // Record transcripts locally, for debugging and conversation recovery\n useLogMessages(messages, messageLogName, forkNumber)\n\n // Log startup time\n useLogStartupTime()\n\n // Initial load\n useEffect(() => {\n onInit()\n // TODO: fix this\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const normalizedMessages = useMemo(\n () => normalizeMessages(messages).filter(isNotEmptyMessage),\n [messages],\n )\n\n const unresolvedToolUseIDs = useMemo(\n () => getUnresolvedToolUseIDs(normalizedMessages),\n [normalizedMessages],\n )\n\n const inProgressToolUseIDs = useMemo(\n () => getInProgressToolUseIDs(normalizedMessages),\n [normalizedMessages],\n )\n\n const erroredToolUseIDs = useMemo(\n () =>\n new Set(\n getErroredToolUseMessages(normalizedMessages).map(\n _ => (_.message.content[0]! as ToolUseBlockParam).id,\n ),\n ),\n [normalizedMessages],\n )\n\n const messagesJSX = useMemo(() => {\n return [\n {\n type: 'static',\n jsx: (\n <Box flexDirection=\"column\" key={`logo${forkNumber}`}>\n <Logo\n mcpClients={mcpClients}\n isDefaultModel={isDefaultModel}\n updateBannerVersion={updateAvailableVersion}\n updateBannerCommands={updateCommands}\n />\n <ProjectOnboarding workspaceDir={getOriginalCwd()} />\n </Box>\n ),\n },\n ...reorderMessages(normalizedMessages).map(_ => {\n const toolUseID = getToolUseID(_)\n const message =\n _.type === 'progress' ? (\n _.content.message.content[0]?.type === 'text' &&\n // TaskTool interrupts use Progress messages without extra \u23BF \n // since <Message /> component already adds the margin\n _.content.message.content[0].text === INTERRUPT_MESSAGE ? (\n <Message\n message={_.content}\n messages={_.normalizedMessages}\n addMargin={false}\n tools={_.tools}\n verbose={verbose ?? false}\n debug={debug}\n erroredToolUseIDs={new Set()}\n inProgressToolUseIDs={new Set()}\n unresolvedToolUseIDs={new Set()}\n shouldAnimate={false}\n shouldShowDot={false}\n />\n ) : (\n <MessageResponse children={\n <Message\n message={_.content}\n messages={_.normalizedMessages}\n addMargin={false}\n tools={_.tools}\n verbose={verbose ?? false}\n debug={debug}\n erroredToolUseIDs={new Set()}\n inProgressToolUseIDs={new Set()}\n unresolvedToolUseIDs={\n new Set([\n (_.content.message.content[0]! as ToolUseBlockParam).id,\n ])\n }\n shouldAnimate={false}\n shouldShowDot={false}\n />\n } />\n )\n ) : (\n <Message\n message={_}\n messages={normalizedMessages}\n addMargin={true}\n tools={tools}\n verbose={verbose}\n debug={debug}\n erroredToolUseIDs={erroredToolUseIDs}\n inProgressToolUseIDs={inProgressToolUseIDs}\n shouldAnimate={\n !toolJSX &&\n !toolUseConfirm &&\n !isMessageSelectorVisible &&\n (!toolUseID || inProgressToolUseIDs.has(toolUseID))\n }\n shouldShowDot={true}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n />\n )\n\n const type = shouldRenderStatically(\n _,\n normalizedMessages,\n unresolvedToolUseIDs,\n )\n ? 'static'\n : 'transient'\n\n if (debug) {\n return {\n type,\n jsx: (\n <Box\n borderStyle=\"single\"\n borderColor={type === 'static' ? 'green' : 'red'}\n key={_.uuid}\n width=\"100%\"\n >\n {message}\n </Box>\n ),\n }\n }\n\n return {\n type,\n jsx: (\n <Box key={_.uuid} width=\"100%\">\n {message}\n </Box>\n ),\n }\n }),\n ]\n }, [\n forkNumber,\n normalizedMessages,\n tools,\n verbose,\n debug,\n erroredToolUseIDs,\n inProgressToolUseIDs,\n toolJSX,\n toolUseConfirm,\n isMessageSelectorVisible,\n unresolvedToolUseIDs,\n mcpClients,\n isDefaultModel,\n ])\n\n // only show the dialog once not loading\n const showingCostDialog = !isLoading && showCostDialog\n\n return (\n <PermissionProvider \n isBypassPermissionsModeAvailable={!safeMode}\n children={\n <React.Fragment>\n {/* Update banner now renders inside Logo for stable placement */}\n <ModeIndicator />\n <React.Fragment key={`static-messages-${forkNumber}`}>\n <Static\n items={messagesJSX.filter(_ => _.type === 'static')}\n children={(item: any) => item.jsx}\n />\n </React.Fragment>\n {messagesJSX.filter(_ => _.type === 'transient').map(_ => _.jsx)}\n <Box\n borderColor=\"red\"\n borderStyle={debug ? 'single' : undefined}\n flexDirection=\"column\"\n width=\"100%\"\n >\n {!toolJSX && !toolUseConfirm && !binaryFeedbackContext && isLoading && (\n <Spinner />\n )}\n {toolJSX ? toolJSX.jsx : null}\n {!toolJSX && binaryFeedbackContext && !isMessageSelectorVisible && (\n <BinaryFeedback\n m1={binaryFeedbackContext.m1}\n m2={binaryFeedbackContext.m2}\n resolve={result => {\n binaryFeedbackContext.resolve(result)\n setTimeout(() => setBinaryFeedbackContext(null), 0)\n }}\n verbose={verbose}\n normalizedMessages={normalizedMessages}\n tools={tools}\n debug={debug}\n erroredToolUseIDs={erroredToolUseIDs}\n inProgressToolUseIDs={inProgressToolUseIDs}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n />\n )}\n {!toolJSX &&\n toolUseConfirm &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext && (\n <PermissionRequest\n toolUseConfirm={toolUseConfirm}\n onDone={() => setToolUseConfirm(null)}\n verbose={verbose}\n />\n )}\n {!toolJSX &&\n !toolUseConfirm &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext &&\n showingCostDialog && (\n <CostThresholdDialog\n onDone={() => {\n setShowCostDialog(false)\n setHaveShownCostDialog(true)\n const projectConfig = getGlobalConfig()\n saveGlobalConfig({\n ...projectConfig,\n hasAcknowledgedCostThreshold: true,\n })\n logEvent('tengu_cost_threshold_acknowledged', {})\n }}\n />\n )}\n\n {!toolUseConfirm &&\n !toolJSX?.shouldHidePromptInput &&\n shouldShowPromptInput &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext &&\n !showingCostDialog && (\n <>\n <PromptInput\n commands={commands}\n forkNumber={forkNumber}\n messageLogName={messageLogName}\n tools={tools}\n isDisabled={apiKeyStatus === 'invalid'}\n isLoading={isLoading}\n onQuery={onQuery}\n debug={debug}\n verbose={verbose}\n messages={messages}\n setToolJSX={setToolJSX}\n input={inputValue}\n onInputChange={setInputValue}\n mode={inputMode}\n onModeChange={setInputMode}\n submitCount={submitCount}\n onSubmitCountChange={setSubmitCount}\n setIsLoading={setIsLoading}\n setAbortController={setAbortController}\n onShowMessageSelector={() =>\n setIsMessageSelectorVisible(prev => !prev)\n }\n setForkConvoWithMessagesOnTheNextRender={\n setForkConvoWithMessagesOnTheNextRender\n }\n readFileTimestamps={readFileTimestamps.current}\n abortController={abortController}\n onModelChange={() => setForkNumber(prev => prev + 1)}\n />\n </>\n )}\n </Box>\n {isMessageSelectorVisible && (\n <MessageSelector\n erroredToolUseIDs={erroredToolUseIDs}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n messages={normalizeMessagesForAPI(messages)}\n onSelect={async message => {\n setIsMessageSelectorVisible(false)\n\n // If the user selected the current prompt, do nothing\n if (!messages.includes(message)) {\n return\n }\n\n // Cancel tool use calls/requests\n onCancel()\n\n // Hack: make sure the \"Interrupted by user\" message is\n // rendered in response to the cancellation. Otherwise,\n // the screen will be cleared but there will remain a\n // vestigial \"Interrupted by user\" message at the top.\n setImmediate(async () => {\n // Clear messages, and re-render\n await clearTerminal()\n setMessages([])\n setForkConvoWithMessagesOnTheNextRender(\n messages.slice(0, messages.indexOf(message)),\n )\n\n // Populate/reset the prompt input\n if (typeof message.message.content === 'string') {\n setInputValue(message.message.content)\n }\n })\n }}\n onEscape={() => setIsMessageSelectorVisible(false)}\n tools={tools}\n />\n )}\n {/** Fix occasional rendering artifact */}\n <Newline />\n </React.Fragment>\n }\n />\n )\n}\n\nfunction shouldRenderStatically(\n message: NormalizedMessage,\n messages: NormalizedMessage[],\n unresolvedToolUseIDs: Set<string>,\n): boolean {\n switch (message.type) {\n case 'user':\n case 'assistant': {\n const toolUseID = getToolUseID(message)\n if (!toolUseID) {\n return true\n }\n if (unresolvedToolUseIDs.has(toolUseID)) {\n return false\n }\n\n const correspondingProgressMessage = messages.find(\n _ => _.type === 'progress' && _.toolUseID === toolUseID,\n ) as ProgressMessage | null\n if (!correspondingProgressMessage) {\n return true\n }\n\n return !intersects(\n unresolvedToolUseIDs,\n correspondingProgressMessage.siblingToolUseIDs,\n )\n }\n case 'progress':\n return !intersects(unresolvedToolUseIDs, message.siblingToolUseIDs)\n }\n}\n\nfunction intersects<A>(a: Set<A>, b: Set<A>): boolean {\n return a.size > 0 && b.size > 0 && [...a].some(_ => b.has(_))\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { Box, Newline, Static, Text } from 'ink'\nimport ProjectOnboarding, {\n markProjectOnboardingComplete,\n} from '../ProjectOnboarding.js'\nimport { CostThresholdDialog } from '../components/CostThresholdDialog'\nimport * as React from 'react'\nimport { useEffect, useMemo, useRef, useState, useCallback } from 'react'\nimport { Command } from '../commands'\nimport { Logo } from '../components/Logo'\nimport { Message } from '../components/Message'\nimport { MessageResponse } from '../components/MessageResponse'\nimport { MessageSelector } from '../components/MessageSelector'\nimport {\n PermissionRequest,\n type ToolUseConfirm,\n} from '../components/permissions/PermissionRequest.js'\nimport PromptInput from '../components/PromptInput'\nimport { Spinner } from '../components/Spinner'\nimport { getSystemPrompt } from '../constants/prompts'\nimport { getContext } from '../context'\nimport { getTotalCost, useCostSummary } from '../cost-tracker'\nimport { useLogStartupTime } from '../hooks/useLogStartupTime'\nimport { addToHistory } from '../history'\nimport { useApiKeyVerification } from '../hooks/useApiKeyVerification'\nimport { useCancelRequest } from '../hooks/useCancelRequest'\nimport useCanUseTool from '../hooks/useCanUseTool'\nimport { useLogMessages } from '../hooks/useLogMessages'\nimport { PermissionProvider } from '../context/PermissionContext'\nimport { ModeIndicator } from '../components/ModeIndicator'\nimport {\n setMessagesGetter,\n setMessagesSetter,\n setModelConfigChangeHandler,\n} from '../messages'\nimport {\n type AssistantMessage,\n type BinaryFeedbackResult,\n type Message as MessageType,\n type ProgressMessage,\n query,\n} from '../query.js'\nimport type { WrappedClient } from '../services/mcpClient'\nimport type { Tool } from '../Tool'\nimport { AutoUpdaterResult } from '../utils/autoUpdater'\nimport { getGlobalConfig, saveGlobalConfig } from '../utils/config'\nimport { MACRO } from '../constants/macros'\nimport { logEvent } from '../services/statsig'\nimport { getNextAvailableLogForkNumber } from '../utils/log'\nimport {\n getErroredToolUseMessages,\n getInProgressToolUseIDs,\n getLastAssistantMessageId,\n getToolUseID,\n getUnresolvedToolUseIDs,\n INTERRUPT_MESSAGE,\n isNotEmptyMessage,\n type NormalizedMessage,\n normalizeMessages,\n normalizeMessagesForAPI,\n processUserInput,\n reorderMessages,\n extractTag,\n createAssistantMessage,\n} from '../utils/messages.js'\nimport { getModelManager, ModelManager } from '../utils/model'\nimport { clearTerminal, updateTerminalTitle } from '../utils/terminal'\nimport { BinaryFeedback } from '../components/binary-feedback/BinaryFeedback'\nimport { getMaxThinkingTokens } from '../utils/thinking'\nimport { getOriginalCwd } from '../utils/state'\nimport { handleHashCommand } from '../commands/terminalSetup'\nimport { debug as debugLogger } from '../utils/debugLogger'\n\ntype Props = {\n commands: Command[]\n safeMode?: boolean\n debug?: boolean\n initialForkNumber?: number | undefined\n initialPrompt: string | undefined\n // A unique name for the message log file, used to identify the fork\n messageLogName: string\n shouldShowPromptInput: boolean\n tools: Tool[]\n verbose: boolean | undefined\n // Initial messages to populate the REPL with\n initialMessages?: MessageType[]\n // MCP clients\n mcpClients?: WrappedClient[]\n // Flag to indicate if current model is default\n isDefaultModel?: boolean\n // Update banner info passed from CLI before first render\n initialUpdateVersion?: string | null\n initialUpdateCommands?: string[] | null\n}\n\nexport type BinaryFeedbackContext = {\n m1: AssistantMessage\n m2: AssistantMessage\n resolve: (result: BinaryFeedbackResult) => void\n}\n\nexport function REPL({\n commands,\n safeMode,\n debug = false,\n initialForkNumber = 0,\n initialPrompt,\n messageLogName,\n shouldShowPromptInput,\n tools,\n verbose: verboseFromCLI,\n initialMessages,\n mcpClients = [],\n isDefaultModel = true,\n initialUpdateVersion,\n initialUpdateCommands,\n}: Props): React.ReactNode {\n // Cache verbose config to avoid synchronous file reads on every render\n const [verboseConfig] = useState(() => verboseFromCLI ?? getGlobalConfig().verbose)\n const verbose = verboseConfig\n\n // Used to force the logo to re-render and conversation log to use a new file\n const [forkNumber, setForkNumber] = useState(\n getNextAvailableLogForkNumber(messageLogName, initialForkNumber, 0),\n )\n\n const [\n forkConvoWithMessagesOnTheNextRender,\n setForkConvoWithMessagesOnTheNextRender,\n ] = useState<MessageType[] | null>(null)\n\n // \uD83D\uDD27 Simplified AbortController management - inspired by reference system\n const [abortController, setAbortController] = useState<AbortController | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n const [autoUpdaterResult, setAutoUpdaterResult] =\n useState<AutoUpdaterResult | null>(null)\n const [toolJSX, setToolJSX] = useState<{\n jsx: React.ReactNode | null\n shouldHidePromptInput: boolean\n } | null>(null)\n const [toolUseConfirm, setToolUseConfirm] = useState<ToolUseConfirm | null>(\n null,\n )\n const [messages, setMessages] = useState<MessageType[]>(initialMessages ?? [])\n const [inputValue, setInputValue] = useState('')\n const [inputMode, setInputMode] = useState<'bash' | 'prompt' | 'koding'>(\n 'prompt',\n )\n const [submitCount, setSubmitCount] = useState(0)\n const [isMessageSelectorVisible, setIsMessageSelectorVisible] =\n useState(false)\n const [showCostDialog, setShowCostDialog] = useState(false)\n const [haveShownCostDialog, setHaveShownCostDialog] = useState(\n getGlobalConfig().hasAcknowledgedCostThreshold,\n )\n\n const [binaryFeedbackContext, setBinaryFeedbackContext] =\n useState<BinaryFeedbackContext | null>(null)\n // New version banner: passed in from CLI to guarantee top placement\n const updateAvailableVersion = initialUpdateVersion ?? null\n const updateCommands = initialUpdateCommands ?? null\n // No separate Static for banner; it renders inside Logo\n\n const getBinaryFeedbackResponse = useCallback(\n (\n m1: AssistantMessage,\n m2: AssistantMessage,\n ): Promise<BinaryFeedbackResult> => {\n return new Promise<BinaryFeedbackResult>(resolvePromise => {\n setBinaryFeedbackContext({\n m1,\n m2,\n resolve: resolvePromise,\n })\n })\n },\n [],\n )\n\n const readFileTimestamps = useRef<{\n [filename: string]: number\n }>({})\n\n const { status: apiKeyStatus, reverify } = useApiKeyVerification()\n function onCancel() {\n if (!isLoading) {\n return\n }\n setIsLoading(false)\n if (toolUseConfirm) {\n toolUseConfirm.onAbort()\n } else if (abortController && !abortController.signal.aborted) {\n abortController.abort()\n }\n }\n\n useCancelRequest(\n setToolJSX,\n setToolUseConfirm,\n setBinaryFeedbackContext,\n onCancel,\n isLoading,\n isMessageSelectorVisible,\n abortController?.signal,\n )\n\n useEffect(() => {\n if (forkConvoWithMessagesOnTheNextRender) {\n setForkNumber(_ => _ + 1)\n setForkConvoWithMessagesOnTheNextRender(null)\n setMessages(forkConvoWithMessagesOnTheNextRender)\n }\n }, [forkConvoWithMessagesOnTheNextRender])\n\n useEffect(() => {\n const totalCost = getTotalCost()\n if (totalCost >= 5 /* $5 */ && !showCostDialog && !haveShownCostDialog) {\n logEvent('tengu_cost_threshold_reached', {})\n setShowCostDialog(true)\n }\n }, [messages, showCostDialog, haveShownCostDialog])\n\n // Update banner is provided by CLI at startup; no async check here.\n\n const canUseTool = useCanUseTool(setToolUseConfirm)\n\n async function onInit() {\n reverify()\n\n if (!initialPrompt) {\n return\n }\n\n setIsLoading(true)\n\n const newAbortController = new AbortController()\n setAbortController(newAbortController)\n\n // \uD83D\uDD27 Force fresh config read to ensure model switching works\n const model = new ModelManager(getGlobalConfig()).getModelName('main')\n const newMessages = await processUserInput(\n initialPrompt,\n 'prompt',\n setToolJSX,\n {\n abortController: newAbortController,\n options: {\n commands,\n forkNumber,\n messageLogName,\n tools,\n verbose,\n maxThinkingTokens: 0,\n },\n messageId: getLastAssistantMessageId(messages),\n setForkConvoWithMessagesOnTheNextRender,\n readFileTimestamps: readFileTimestamps.current,\n },\n null,\n )\n\n if (newMessages.length) {\n for (const message of newMessages) {\n if (message.type === 'user') {\n addToHistory(initialPrompt)\n // TODO: setHistoryIndex\n }\n }\n setMessages(_ => [..._, ...newMessages])\n\n // The last message is an assistant message if the user input was a bash command,\n // or if the user input was an invalid slash command.\n const lastMessage = newMessages[newMessages.length - 1]!\n if (lastMessage.type === 'assistant') {\n setAbortController(null)\n setIsLoading(false)\n return\n }\n\n const [systemPrompt, context, model, maxThinkingTokens] =\n await Promise.all([\n getSystemPrompt(),\n getContext(),\n new ModelManager(getGlobalConfig()).getModelName('main'),\n getMaxThinkingTokens([...messages, ...newMessages]),\n ])\n\n for await (const message of query(\n [...messages, ...newMessages],\n systemPrompt,\n context,\n canUseTool,\n {\n options: {\n commands,\n forkNumber,\n messageLogName,\n tools,\n verbose,\n safeMode,\n maxThinkingTokens,\n },\n messageId: getLastAssistantMessageId([...messages, ...newMessages]),\n readFileTimestamps: readFileTimestamps.current,\n abortController: newAbortController,\n setToolJSX,\n },\n getBinaryFeedbackResponse,\n )) {\n setMessages(oldMessages => [...oldMessages, message])\n }\n } else {\n addToHistory(initialPrompt)\n // TODO: setHistoryIndex\n }\n\n setHaveShownCostDialog(\n getGlobalConfig().hasAcknowledgedCostThreshold || false,\n )\n\n // \uD83D\uDD27 Fix: Clean up state after onInit completion\n setIsLoading(false)\n setAbortController(null)\n }\n\n async function onQuery(newMessages: MessageType[], passedAbortController?: AbortController) {\n // Use passed AbortController or create new one\n const controllerToUse = passedAbortController || new AbortController()\n if (!passedAbortController) {\n setAbortController(controllerToUse)\n }\n\n // Check if this is a Koding request based on last message's options\n const isKodingRequest =\n newMessages.length > 0 &&\n newMessages[0].type === 'user' &&\n 'options' in newMessages[0] &&\n newMessages[0].options?.isKodingRequest === true\n\n setMessages(oldMessages => [...oldMessages, ...newMessages])\n\n // Mark onboarding as complete when any user message is sent to Claude\n markProjectOnboardingComplete()\n\n // The last message is an assistant message if the user input was a bash command,\n // or if the user input was an invalid slash command.\n const lastMessage = newMessages[newMessages.length - 1]!\n\n // Update terminal title based on user message\n if (\n lastMessage.type === 'user' &&\n typeof lastMessage.message.content === 'string'\n ) {\n // updateTerminalTitle(lastMessage.message.content)\n }\n if (lastMessage.type === 'assistant') {\n setAbortController(null)\n setIsLoading(false)\n return\n }\n\n const [systemPrompt, context, model, maxThinkingTokens] =\n await Promise.all([\n getSystemPrompt(),\n getContext(),\n new ModelManager(getGlobalConfig()).getModelName('main'),\n getMaxThinkingTokens([...messages, lastMessage]),\n ])\n\n let lastAssistantMessage: MessageType | null = null\n\n // query the API\n for await (const message of query(\n [...messages, lastMessage],\n systemPrompt,\n context,\n canUseTool,\n {\n options: {\n commands,\n forkNumber,\n messageLogName,\n tools,\n verbose,\n safeMode,\n maxThinkingTokens,\n // If this came from Koding mode, pass that along\n isKodingRequest: isKodingRequest || undefined,\n },\n messageId: getLastAssistantMessageId([...messages, lastMessage]),\n readFileTimestamps: readFileTimestamps.current,\n abortController: controllerToUse,\n setToolJSX,\n },\n getBinaryFeedbackResponse,\n )) {\n setMessages(oldMessages => [...oldMessages, message])\n\n // Keep track of the last assistant message for Koding mode\n if (message.type === 'assistant') {\n lastAssistantMessage = message\n }\n }\n\n // If this was a Koding request and we got an assistant message back,\n // save it to AGENTS.md (and CLAUDE.md if exists)\n if (\n isKodingRequest &&\n lastAssistantMessage &&\n lastAssistantMessage.type === 'assistant'\n ) {\n try {\n const content =\n typeof lastAssistantMessage.message.content === 'string'\n ? lastAssistantMessage.message.content\n : lastAssistantMessage.message.content\n .filter(block => block.type === 'text')\n .map(block => (block.type === 'text' ? block.text : ''))\n .join('\\n')\n\n // Add the content to AGENTS.md (and CLAUDE.md if exists)\n if (content && content.trim().length > 0) {\n handleHashCommand(content)\n }\n } catch (error) {\n console.error('Error saving response to project docs:', error)\n }\n }\n\n setIsLoading(false)\n }\n\n // Register cost summary tracker\n useCostSummary()\n\n // Register messages getter and setter\n useEffect(() => {\n const getMessages = () => messages\n setMessagesGetter(getMessages)\n setMessagesSetter(setMessages)\n }, [messages])\n\n // Register model config change handler for UI refresh\n useEffect(() => {\n setModelConfigChangeHandler(() => {\n setForkNumber(prev => prev + 1)\n })\n }, [])\n\n // Record transcripts locally, for debugging and conversation recovery\n useLogMessages(messages, messageLogName, forkNumber)\n\n // Log startup time\n useLogStartupTime()\n\n // Initial load\n useEffect(() => {\n onInit()\n // TODO: fix this\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const normalizedMessages = useMemo(\n () => normalizeMessages(messages).filter(isNotEmptyMessage),\n [messages],\n )\n\n const unresolvedToolUseIDs = useMemo(\n () => getUnresolvedToolUseIDs(normalizedMessages),\n [normalizedMessages],\n )\n\n const inProgressToolUseIDs = useMemo(\n () => getInProgressToolUseIDs(normalizedMessages),\n [normalizedMessages],\n )\n\n const erroredToolUseIDs = useMemo(\n () =>\n new Set(\n getErroredToolUseMessages(normalizedMessages).map(\n _ => (_.message.content[0]! as ToolUseBlockParam).id,\n ),\n ),\n [normalizedMessages],\n )\n\n const messagesJSX = useMemo(() => {\n return [\n {\n type: 'static',\n jsx: (\n <Box flexDirection=\"column\" key={`logo${forkNumber}`}>\n <Logo\n mcpClients={mcpClients}\n isDefaultModel={isDefaultModel}\n updateBannerVersion={updateAvailableVersion}\n updateBannerCommands={updateCommands}\n />\n <ProjectOnboarding workspaceDir={getOriginalCwd()} />\n </Box>\n ),\n },\n ...reorderMessages(normalizedMessages).map(_ => {\n const toolUseID = getToolUseID(_)\n const message =\n _.type === 'progress' ? (\n _.content.message.content[0]?.type === 'text' &&\n // TaskTool interrupts use Progress messages without extra \u23BF \n // since <Message /> component already adds the margin\n _.content.message.content[0].text === INTERRUPT_MESSAGE ? (\n <Message\n message={_.content}\n messages={_.normalizedMessages}\n addMargin={false}\n tools={_.tools}\n verbose={verbose ?? false}\n debug={debug}\n erroredToolUseIDs={new Set()}\n inProgressToolUseIDs={new Set()}\n unresolvedToolUseIDs={new Set()}\n shouldAnimate={false}\n shouldShowDot={false}\n />\n ) : (\n <MessageResponse children={\n <Message\n message={_.content}\n messages={_.normalizedMessages}\n addMargin={false}\n tools={_.tools}\n verbose={verbose ?? false}\n debug={debug}\n erroredToolUseIDs={new Set()}\n inProgressToolUseIDs={new Set()}\n unresolvedToolUseIDs={\n new Set([\n (_.content.message.content[0]! as ToolUseBlockParam).id,\n ])\n }\n shouldAnimate={false}\n shouldShowDot={false}\n />\n } />\n )\n ) : (\n <Message\n message={_}\n messages={normalizedMessages}\n addMargin={true}\n tools={tools}\n verbose={verbose}\n debug={debug}\n erroredToolUseIDs={erroredToolUseIDs}\n inProgressToolUseIDs={inProgressToolUseIDs}\n shouldAnimate={\n !toolJSX &&\n !toolUseConfirm &&\n !isMessageSelectorVisible &&\n (!toolUseID || inProgressToolUseIDs.has(toolUseID))\n }\n shouldShowDot={true}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n />\n )\n\n const type = shouldRenderStatically(\n _,\n normalizedMessages,\n unresolvedToolUseIDs,\n )\n ? 'static'\n : 'transient'\n\n if (debug) {\n return {\n type,\n jsx: (\n <Box\n borderStyle=\"single\"\n borderColor={type === 'static' ? 'green' : 'red'}\n key={_.uuid}\n width=\"100%\"\n >\n {message}\n </Box>\n ),\n }\n }\n\n return {\n type,\n jsx: (\n <Box key={_.uuid} width=\"100%\">\n {message}\n </Box>\n ),\n }\n }),\n ]\n }, [\n forkNumber,\n normalizedMessages,\n tools,\n verbose,\n debug,\n erroredToolUseIDs,\n inProgressToolUseIDs,\n toolJSX,\n toolUseConfirm,\n isMessageSelectorVisible,\n unresolvedToolUseIDs,\n mcpClients,\n isDefaultModel,\n ])\n\n // only show the dialog once not loading\n const showingCostDialog = !isLoading && showCostDialog\n\n return (\n <PermissionProvider \n isBypassPermissionsModeAvailable={!safeMode}\n children={\n <React.Fragment>\n {/* Update banner now renders inside Logo for stable placement */}\n <ModeIndicator />\n <React.Fragment key={`static-messages-${forkNumber}`}>\n <Static\n items={messagesJSX.filter(_ => _.type === 'static')}\n children={(item: any) => item.jsx}\n />\n </React.Fragment>\n {messagesJSX.filter(_ => _.type === 'transient').map(_ => _.jsx)}\n <Box\n borderColor=\"red\"\n borderStyle={debug ? 'single' : undefined}\n flexDirection=\"column\"\n width=\"100%\"\n >\n {!toolJSX && !toolUseConfirm && !binaryFeedbackContext && isLoading && (\n <Spinner />\n )}\n {toolJSX ? toolJSX.jsx : null}\n {!toolJSX && binaryFeedbackContext && !isMessageSelectorVisible && (\n <BinaryFeedback\n m1={binaryFeedbackContext.m1}\n m2={binaryFeedbackContext.m2}\n resolve={result => {\n binaryFeedbackContext.resolve(result)\n setTimeout(() => setBinaryFeedbackContext(null), 0)\n }}\n verbose={verbose}\n normalizedMessages={normalizedMessages}\n tools={tools}\n debug={debug}\n erroredToolUseIDs={erroredToolUseIDs}\n inProgressToolUseIDs={inProgressToolUseIDs}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n />\n )}\n {!toolJSX &&\n toolUseConfirm &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext && (\n <PermissionRequest\n toolUseConfirm={toolUseConfirm}\n onDone={() => setToolUseConfirm(null)}\n verbose={verbose}\n />\n )}\n {!toolJSX &&\n !toolUseConfirm &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext &&\n showingCostDialog && (\n <CostThresholdDialog\n onDone={() => {\n setShowCostDialog(false)\n setHaveShownCostDialog(true)\n const projectConfig = getGlobalConfig()\n saveGlobalConfig({\n ...projectConfig,\n hasAcknowledgedCostThreshold: true,\n })\n logEvent('tengu_cost_threshold_acknowledged', {})\n }}\n />\n )}\n\n {!toolUseConfirm &&\n !toolJSX?.shouldHidePromptInput &&\n shouldShowPromptInput &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext &&\n !showingCostDialog && (\n <>\n <PromptInput\n commands={commands}\n forkNumber={forkNumber}\n messageLogName={messageLogName}\n tools={tools}\n isDisabled={apiKeyStatus === 'invalid'}\n isLoading={isLoading}\n onQuery={onQuery}\n debug={debug}\n verbose={verbose}\n messages={messages}\n setToolJSX={setToolJSX}\n onAutoUpdaterResult={setAutoUpdaterResult}\n autoUpdaterResult={autoUpdaterResult}\n input={inputValue}\n onInputChange={setInputValue}\n mode={inputMode}\n onModeChange={setInputMode}\n submitCount={submitCount}\n onSubmitCountChange={setSubmitCount}\n setIsLoading={setIsLoading}\n setAbortController={setAbortController}\n onShowMessageSelector={() =>\n setIsMessageSelectorVisible(prev => !prev)\n }\n setForkConvoWithMessagesOnTheNextRender={\n setForkConvoWithMessagesOnTheNextRender\n }\n readFileTimestamps={readFileTimestamps.current}\n abortController={abortController}\n onModelChange={() => setForkNumber(prev => prev + 1)}\n />\n </>\n )}\n </Box>\n {isMessageSelectorVisible && (\n <MessageSelector\n erroredToolUseIDs={erroredToolUseIDs}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n messages={normalizeMessagesForAPI(messages)}\n onSelect={async message => {\n setIsMessageSelectorVisible(false)\n\n // If the user selected the current prompt, do nothing\n if (!messages.includes(message)) {\n return\n }\n\n // Cancel tool use calls/requests\n onCancel()\n\n // Hack: make sure the \"Interrupted by user\" message is\n // rendered in response to the cancellation. Otherwise,\n // the screen will be cleared but there will remain a\n // vestigial \"Interrupted by user\" message at the top.\n setImmediate(async () => {\n // Clear messages, and re-render\n await clearTerminal()\n setMessages([])\n setForkConvoWithMessagesOnTheNextRender(\n messages.slice(0, messages.indexOf(message)),\n )\n\n // Populate/reset the prompt input\n if (typeof message.message.content === 'string') {\n setInputValue(message.message.content)\n }\n })\n }}\n onEscape={() => setIsMessageSelectorVisible(false)}\n tools={tools}\n />\n )}\n {/** Fix occasional rendering artifact */}\n <Newline />\n </React.Fragment>\n }\n />\n )\n}\n\nfunction shouldRenderStatically(\n message: NormalizedMessage,\n messages: NormalizedMessage[],\n unresolvedToolUseIDs: Set<string>,\n): boolean {\n switch (message.type) {\n case 'user':\n case 'assistant': {\n const toolUseID = getToolUseID(message)\n if (!toolUseID) {\n return true\n }\n if (unresolvedToolUseIDs.has(toolUseID)) {\n return false\n }\n\n const correspondingProgressMessage = messages.find(\n _ => _.type === 'progress' && _.toolUseID === toolUseID,\n ) as ProgressMessage | null\n if (!correspondingProgressMessage) {\n return true\n }\n\n return !intersects(\n unresolvedToolUseIDs,\n correspondingProgressMessage.siblingToolUseIDs,\n )\n }\n case 'progress':\n return !intersects(unresolvedToolUseIDs, message.siblingToolUseIDs)\n }\n}\n\nfunction intersects<A>(a: Set<A>, b: Set<A>): boolean {\n return a.size > 0 && b.size > 0 && [...a].some(_ => b.has(_))\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["model"]
7
7
  }
@@ -1,6 +1,22 @@
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";
1
14
  import { execFileNoThrow } from "./execFileNoThrow.js";
15
+ import { spawn } from "child_process";
2
16
  import { logError } from "./log.js";
3
- import { getDynamicConfig } from "../services/statsig.js";
17
+ import { accessSync } from "fs";
18
+ import { CLAUDE_BASE_DIR } from "./env.js";
19
+ import { logEvent, getDynamicConfig } from "../services/statsig.js";
4
20
  import { lt, gt } from "semver";
5
21
  import { MACRO } from "../constants/macros.js";
6
22
  import { PRODUCT_NAME } from "../constants/product.js";
@@ -14,17 +30,170 @@ async function assertMinVersion() {
14
30
  );
15
31
  if (versionConfig.minVersion && lt(MACRO.VERSION, versionConfig.minVersion)) {
16
32
  const suggestions = await getUpdateCommandSuggestions();
17
- console.error(
18
- `Your ${PRODUCT_NAME} version ${MACRO.VERSION} is below the minimum supported ${versionConfig.minVersion}.
19
- Update using one of:
20
- ` + suggestions.map((c) => ` ${c}`).join("\n")
21
- );
33
+ const cmdLines = suggestions.map((c) => ` ${c}`).join("\n");
22
34
  process.exit(1);
23
35
  }
24
36
  } catch (error) {
25
37
  logError(`Error checking minimum version: ${error}`);
26
38
  }
27
39
  }
40
+ const LOCK_FILE_PATH = join(CLAUDE_BASE_DIR, ".update.lock");
41
+ const LOCK_TIMEOUT_MS = 5 * 60 * 1e3;
42
+ function acquireLock() {
43
+ try {
44
+ if (!existsSync(CLAUDE_BASE_DIR)) {
45
+ mkdirSync(CLAUDE_BASE_DIR, { recursive: true });
46
+ }
47
+ if (existsSync(LOCK_FILE_PATH)) {
48
+ const stats = statSync(LOCK_FILE_PATH);
49
+ const age = Date.now() - stats.mtimeMs;
50
+ if (age < LOCK_TIMEOUT_MS) {
51
+ return false;
52
+ }
53
+ try {
54
+ unlinkSync(LOCK_FILE_PATH);
55
+ } catch (err) {
56
+ logError(`Failed to remove stale lock file: ${err}`);
57
+ return false;
58
+ }
59
+ }
60
+ writeFileSync(LOCK_FILE_PATH, `${process.pid}`, "utf8");
61
+ return true;
62
+ } catch (err) {
63
+ logError(`Failed to acquire lock: ${err}`);
64
+ return false;
65
+ }
66
+ }
67
+ function releaseLock() {
68
+ try {
69
+ if (existsSync(LOCK_FILE_PATH)) {
70
+ const lockData = readFileSync(LOCK_FILE_PATH, "utf8");
71
+ if (lockData === `${process.pid}`) {
72
+ unlinkSync(LOCK_FILE_PATH);
73
+ }
74
+ }
75
+ } catch (err) {
76
+ logError(`Failed to release lock: ${err}`);
77
+ }
78
+ }
79
+ async function checkNpmPermissions() {
80
+ try {
81
+ const prefixResult = await execFileNoThrow("npm", [
82
+ "-g",
83
+ "config",
84
+ "get",
85
+ "prefix"
86
+ ]);
87
+ if (prefixResult.code !== 0) {
88
+ logError("Failed to check npm permissions");
89
+ return { hasPermissions: false, npmPrefix: null };
90
+ }
91
+ const prefix = prefixResult.stdout.trim();
92
+ let testWriteResult = false;
93
+ try {
94
+ accessSync(prefix, constants.W_OK);
95
+ testWriteResult = true;
96
+ } catch {
97
+ testWriteResult = false;
98
+ }
99
+ if (testWriteResult) {
100
+ return { hasPermissions: true, npmPrefix: prefix };
101
+ }
102
+ logError("Insufficient permissions for global npm install.");
103
+ return { hasPermissions: false, npmPrefix: prefix };
104
+ } catch (error) {
105
+ logError(`Failed to verify npm global install permissions: ${error}`);
106
+ return { hasPermissions: false, npmPrefix: null };
107
+ }
108
+ }
109
+ async function setupNewPrefix(prefix) {
110
+ if (!acquireLock()) {
111
+ logEvent("tengu_auto_updater_prefix_lock_contention", {
112
+ pid: String(process.pid),
113
+ currentVersion: MACRO.VERSION,
114
+ prefix
115
+ });
116
+ throw new Error("Another process is currently setting up npm prefix");
117
+ }
118
+ try {
119
+ if (!existsSync(prefix)) {
120
+ mkdirSync(prefix, { recursive: true });
121
+ }
122
+ const setPrefix = await execFileNoThrow("npm", [
123
+ "-g",
124
+ "config",
125
+ "set",
126
+ "prefix",
127
+ prefix
128
+ ]);
129
+ if (setPrefix.code !== 0) {
130
+ throw new Error(`Failed to set npm prefix: ${setPrefix.stderr}`);
131
+ }
132
+ const pathUpdate = `
133
+ # npm global path
134
+ export PATH="${prefix}/bin:$PATH"
135
+ `;
136
+ if (platform === "win32") {
137
+ const setxResult = await execFileNoThrow("setx", [
138
+ "PATH",
139
+ `${process.env.PATH};${prefix}`
140
+ ]);
141
+ if (setxResult.code !== 0) {
142
+ throw new Error(
143
+ `Failed to update PATH on Windows: ${setxResult.stderr}`
144
+ );
145
+ }
146
+ } else {
147
+ const shellConfigs = [
148
+ // Bash
149
+ join(homedir(), ".bashrc"),
150
+ join(homedir(), ".bash_profile"),
151
+ // Zsh
152
+ join(homedir(), ".zshrc"),
153
+ // Fish
154
+ join(homedir(), ".config", "fish", "config.fish")
155
+ ];
156
+ for (const config of shellConfigs) {
157
+ if (existsSync(config)) {
158
+ try {
159
+ const content = readFileSync(config, "utf8");
160
+ if (!content.includes(prefix)) {
161
+ if (config.includes("fish")) {
162
+ const fishPath = `
163
+ # npm global path
164
+ set -gx PATH ${prefix}/bin $PATH
165
+ `;
166
+ appendFileSync(config, fishPath);
167
+ } else {
168
+ appendFileSync(config, pathUpdate);
169
+ }
170
+ logEvent("npm_prefix_path_updated", {
171
+ configPath: config
172
+ });
173
+ }
174
+ } catch (err) {
175
+ logEvent("npm_prefix_path_update_failed", {
176
+ configPath: config,
177
+ error: err instanceof Error ? err.message.slice(0, 200) : String(err).slice(0, 200)
178
+ });
179
+ logError(`Failed to update shell config ${config}: ${err}`);
180
+ }
181
+ }
182
+ }
183
+ }
184
+ } finally {
185
+ releaseLock();
186
+ }
187
+ }
188
+ function getDefaultNpmPrefix() {
189
+ return join(homedir(), ".npm-global");
190
+ }
191
+ function getPermissionsCommand(npmPrefix) {
192
+ const windowsCommand = `icacls "${npmPrefix}" /grant "%USERNAME%:(OI)(CI)F"`;
193
+ const prefixPath = npmPrefix || "$(npm -g config get prefix)";
194
+ const unixCommand = `sudo chown -R $USER:$(id -gn) ${prefixPath} && sudo chmod -R u+w ${prefixPath}`;
195
+ return platform === "win32" ? windowsCommand : unixCommand;
196
+ }
28
197
  async function getLatestVersion() {
29
198
  try {
30
199
  const abortController = new AbortController();
@@ -63,6 +232,77 @@ async function getLatestVersion() {
63
232
  return null;
64
233
  }
65
234
  }
235
+ async function installGlobalPackage() {
236
+ if (!acquireLock()) {
237
+ logError("Another process is currently installing an update");
238
+ logEvent("tengu_auto_updater_lock_contention", {
239
+ pid: String(process.pid),
240
+ currentVersion: MACRO.VERSION
241
+ });
242
+ return "in_progress";
243
+ }
244
+ try {
245
+ const manager = await detectPackageManager();
246
+ if (manager === "npm") {
247
+ const { hasPermissions: hasPermissions2 } = await checkNpmPermissions();
248
+ if (!hasPermissions2) {
249
+ return "no_permissions";
250
+ }
251
+ const code2 = await runStreaming("npm", ["install", "-g", MACRO.PACKAGE_URL]);
252
+ if (code2 !== 0) {
253
+ logError(`Failed to install new version via npm (exit ${code2})`);
254
+ return "install_failed";
255
+ }
256
+ return "success";
257
+ }
258
+ if (manager === "bun") {
259
+ const code2 = await runStreaming("bun", ["add", "-g", `${MACRO.PACKAGE_URL}@latest`]);
260
+ if (code2 !== 0) {
261
+ logError(`Failed to install new version via bun (exit ${code2})`);
262
+ return "install_failed";
263
+ }
264
+ return "success";
265
+ }
266
+ const { hasPermissions } = await checkNpmPermissions();
267
+ if (!hasPermissions) return "no_permissions";
268
+ const code = await runStreaming("npm", ["install", "-g", MACRO.PACKAGE_URL]);
269
+ if (code !== 0) return "install_failed";
270
+ return "success";
271
+ } finally {
272
+ releaseLock();
273
+ }
274
+ }
275
+ async function detectPackageManager() {
276
+ try {
277
+ const npmRoot = await execFileNoThrow("npm", ["-g", "root"]);
278
+ if (npmRoot.code === 0 && npmRoot.stdout.trim()) {
279
+ return "npm";
280
+ }
281
+ } catch {
282
+ }
283
+ try {
284
+ const bunVer = await execFileNoThrow("bun", ["--version"]);
285
+ if (bunVer.code === 0) {
286
+ return "bun";
287
+ }
288
+ } catch {
289
+ }
290
+ return "npm";
291
+ }
292
+ function runStreaming(cmd, args) {
293
+ return new Promise((resolve) => {
294
+ try {
295
+ console.log(`> ${cmd} ${args.join(" ")}`);
296
+ } catch {
297
+ }
298
+ const child = spawn(cmd, args, {
299
+ stdio: "inherit",
300
+ env: process.env
301
+ });
302
+ child.on("close", (code) => resolve(code ?? 0));
303
+ child.on("error", () => resolve(1));
304
+ });
305
+ }
66
306
  async function getUpdateCommandSuggestions() {
67
307
  return [
68
308
  `bun add -g ${MACRO.PACKAGE_URL}@latest`,
@@ -94,7 +334,9 @@ async function checkAndNotifyUpdate() {
94
334
  const suggestions = await getUpdateCommandSuggestions();
95
335
  console.log(`New version available: ${latest} (current: ${MACRO.VERSION})`);
96
336
  console.log("Run the following command to update:");
97
- for (const command of suggestions) console.log(` ${command}`);
337
+ for (const command of suggestions) {
338
+ console.log(` ${command}`);
339
+ }
98
340
  } else {
99
341
  saveGlobalConfig({ ...config, lastUpdateCheckAt: now });
100
342
  }
@@ -103,9 +345,16 @@ async function checkAndNotifyUpdate() {
103
345
  }
104
346
  }
105
347
  export {
348
+ LOCK_FILE_PATH,
106
349
  assertMinVersion,
107
350
  checkAndNotifyUpdate,
351
+ checkNpmPermissions,
352
+ detectPackageManager,
353
+ getDefaultNpmPrefix,
108
354
  getLatestVersion,
109
- getUpdateCommandSuggestions
355
+ getPermissionsCommand,
356
+ getUpdateCommandSuggestions,
357
+ installGlobalPackage,
358
+ setupNewPrefix
110
359
  };
111
360
  //# sourceMappingURL=autoUpdater.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/autoUpdater.ts"],
4
- "sourcesContent": ["import { execFileNoThrow } from './execFileNoThrow'\nimport { logError } from './log'\nimport { getDynamicConfig } from '../services/statsig'\nimport { lt, gt } from 'semver'\nimport { MACRO } from '../constants/macros'\nimport { PRODUCT_NAME } from '../constants/product'\nimport { getGlobalConfig, saveGlobalConfig, isAutoUpdaterDisabled } from './config'\nimport { env } from './env'\n\nexport type VersionConfig = {\n minVersion: string\n}\n\n// Ensure current version meets minimum supported version; exit if too old\nexport async function assertMinVersion(): Promise<void> {\n try {\n const versionConfig = await getDynamicConfig<VersionConfig>(\n 'tengu_version_config',\n { minVersion: '0.0.0' },\n )\n if (versionConfig.minVersion && lt(MACRO.VERSION, versionConfig.minVersion)) {\n const suggestions = await getUpdateCommandSuggestions()\n // Intentionally minimal: caller may print its own message; we just exit\n // eslint-disable-next-line no-console\n console.error(\n `Your ${PRODUCT_NAME} version ${MACRO.VERSION} is below the minimum supported ${versionConfig.minVersion}.\\n` +\n 'Update using one of:\\n' +\n suggestions.map(c => ` ${c}`).join('\\n'),\n )\n process.exit(1)\n }\n } catch (error) {\n logError(`Error checking minimum version: ${error}`)\n }\n}\n\n// Get latest version from npm (via npm CLI or HTTP fallback)\nexport async function getLatestVersion(): Promise<string | null> {\n // Prefer npm CLI (fast when available)\n try {\n const abortController = new AbortController()\n setTimeout(() => abortController.abort(), 5000)\n const result = await execFileNoThrow(\n 'npm',\n ['view', MACRO.PACKAGE_URL, 'version'],\n abortController.signal,\n )\n if (result.code === 0) {\n const v = result.stdout.trim()\n if (v) return v\n }\n } catch {}\n\n // Fallback: query npm registry directly\n try {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), 5000)\n const res = await fetch(\n `https://registry.npmjs.org/${encodeURIComponent(MACRO.PACKAGE_URL)}`,\n {\n method: 'GET',\n headers: {\n Accept: 'application/vnd.npm.install-v1+json',\n 'User-Agent': `${PRODUCT_NAME}/${MACRO.VERSION}`,\n },\n signal: controller.signal,\n },\n )\n clearTimeout(timer)\n if (!res.ok) return null\n const json: any = await res.json().catch(() => null)\n const latest = json && json['dist-tags'] && json['dist-tags'].latest\n return typeof latest === 'string' ? latest : null\n } catch {\n return null\n }\n}\n\n// Suggest manual update commands; prefer Bun first, then npm\nexport async function getUpdateCommandSuggestions(): Promise<string[]> {\n return [\n `bun add -g ${MACRO.PACKAGE_URL}@latest`,\n `npm install -g ${MACRO.PACKAGE_URL}@latest`,\n ]\n}\n\n// Optional: background notifier that prints a simple banner\nexport async function checkAndNotifyUpdate(): Promise<void> {\n try {\n if (process.env.NODE_ENV === 'test') return\n if (await isAutoUpdaterDisabled()) return\n if (await env.getIsDocker()) return\n if (!(await env.hasInternetAccess())) return\n\n const config: any = getGlobalConfig()\n const now = Date.now()\n const DAY_MS = 24 * 60 * 60 * 1000\n const lastCheck = Number(config.lastUpdateCheckAt || 0)\n if (lastCheck && now - lastCheck < DAY_MS) return\n\n const latest = await getLatestVersion()\n if (!latest) {\n saveGlobalConfig({ ...config, lastUpdateCheckAt: now })\n return\n }\n\n if (gt(latest, MACRO.VERSION)) {\n saveGlobalConfig({\n ...config,\n lastUpdateCheckAt: now,\n lastSuggestedVersion: latest,\n })\n const suggestions = await getUpdateCommandSuggestions()\n // eslint-disable-next-line no-console\n console.log(`New version available: ${latest} (current: ${MACRO.VERSION})`)\n console.log('Run the following command to update:')\n for (const command of suggestions) console.log(` ${command}`)\n } else {\n saveGlobalConfig({ ...config, lastUpdateCheckAt: now })\n }\n } catch (error) {\n logError(`update-notify: ${error}`)\n }\n}\n\n"],
5
- "mappings": "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",
6
- "names": []
4
+ "sourcesContent": ["import { homedir } from 'os'\nimport { join } from 'path'\nimport {\n existsSync,\n mkdirSync,\n appendFileSync,\n readFileSync,\n constants,\n writeFileSync,\n unlinkSync,\n statSync,\n} from 'fs'\nimport { platform } from 'process'\nimport { execFileNoThrow } from './execFileNoThrow'\nimport { spawn } from 'child_process'\nimport { logError } from './log'\nimport { accessSync } from 'fs'\nimport { CLAUDE_BASE_DIR } from './env'\nimport { logEvent, getDynamicConfig } from '../services/statsig'\nimport { lt, gt } from 'semver'\nimport { MACRO } from '../constants/macros'\nimport { PRODUCT_COMMAND, PRODUCT_NAME } from '../constants/product'\nimport { getGlobalConfig, saveGlobalConfig, isAutoUpdaterDisabled } from './config'\nimport { env } from './env'\nexport type InstallStatus =\n | 'success'\n | 'no_permissions'\n | 'install_failed'\n | 'in_progress'\n\nexport type AutoUpdaterResult = {\n version: string | null\n status: InstallStatus\n}\n\nexport type VersionConfig = {\n minVersion: string\n}\n\n/**\n * Checks if the current version meets the minimum required version from Statsig config\n * Terminates the process with an error message if the version is too old\n */\nexport async function assertMinVersion(): Promise<void> {\n try {\n const versionConfig = await getDynamicConfig<VersionConfig>(\n 'tengu_version_config',\n { minVersion: '0.0.0' },\n )\n\n if (\n versionConfig.minVersion &&\n lt(MACRO.VERSION, versionConfig.minVersion)\n ) {\n const suggestions = await getUpdateCommandSuggestions()\n const cmdLines = suggestions.map(c => ` ${c}`).join('\\n')\n process.exit(1)\n }\n } catch (error) {\n logError(`Error checking minimum version: ${error}`)\n }\n}\n\n// Lock file for auto-updater to prevent concurrent updates\nexport const LOCK_FILE_PATH = join(CLAUDE_BASE_DIR, '.update.lock')\nconst LOCK_TIMEOUT_MS = 5 * 60 * 1000 // 5 minute timeout for locks\n\n/**\n * Attempts to acquire a lock for auto-updater\n * @returns {boolean} true if lock was acquired, false if another process holds the lock\n */\nfunction acquireLock(): boolean {\n try {\n // Ensure the base directory exists\n if (!existsSync(CLAUDE_BASE_DIR)) {\n mkdirSync(CLAUDE_BASE_DIR, { recursive: true })\n }\n\n // Check if lock file exists and is not stale\n if (existsSync(LOCK_FILE_PATH)) {\n const stats = statSync(LOCK_FILE_PATH)\n const age = Date.now() - stats.mtimeMs\n\n // If lock file is older than timeout, consider it stale\n if (age < LOCK_TIMEOUT_MS) {\n return false\n }\n\n // Lock is stale, we can take over\n try {\n unlinkSync(LOCK_FILE_PATH)\n } catch (err) {\n logError(`Failed to remove stale lock file: ${err}`)\n return false\n }\n }\n\n // Create lock file with current pid\n writeFileSync(LOCK_FILE_PATH, `${process.pid}`, 'utf8')\n return true\n } catch (err) {\n logError(`Failed to acquire lock: ${err}`)\n return false\n }\n}\n\n/**\n * Releases the update lock if it's held by this process\n */\nfunction releaseLock(): void {\n try {\n if (existsSync(LOCK_FILE_PATH)) {\n const lockData = readFileSync(LOCK_FILE_PATH, 'utf8')\n if (lockData === `${process.pid}`) {\n unlinkSync(LOCK_FILE_PATH)\n }\n }\n } catch (err) {\n logError(`Failed to release lock: ${err}`)\n }\n}\n\nexport async function checkNpmPermissions(): Promise<{\n hasPermissions: boolean\n npmPrefix: string | null\n}> {\n try {\n const prefixResult = await execFileNoThrow('npm', [\n '-g',\n 'config',\n 'get',\n 'prefix',\n ])\n if (prefixResult.code !== 0) {\n logError('Failed to check npm permissions')\n return { hasPermissions: false, npmPrefix: null }\n }\n\n const prefix = prefixResult.stdout.trim()\n\n let testWriteResult = false\n try {\n accessSync(prefix, constants.W_OK)\n testWriteResult = true\n } catch {\n testWriteResult = false\n }\n\n if (testWriteResult) {\n return { hasPermissions: true, npmPrefix: prefix }\n }\n\n logError('Insufficient permissions for global npm install.')\n return { hasPermissions: false, npmPrefix: prefix }\n } catch (error) {\n logError(`Failed to verify npm global install permissions: ${error}`)\n return { hasPermissions: false, npmPrefix: null }\n }\n}\n\nexport async function setupNewPrefix(prefix: string): Promise<void> {\n if (!acquireLock()) {\n // Log the lock contention to statsig\n logEvent('tengu_auto_updater_prefix_lock_contention', {\n pid: String(process.pid),\n currentVersion: MACRO.VERSION,\n prefix,\n })\n throw new Error('Another process is currently setting up npm prefix')\n }\n\n try {\n // Create directory if it doesn't exist\n if (!existsSync(prefix)) {\n mkdirSync(prefix, { recursive: true })\n }\n\n // Set npm prefix\n const setPrefix = await execFileNoThrow('npm', [\n '-g',\n 'config',\n 'set',\n 'prefix',\n prefix,\n ])\n\n if (setPrefix.code !== 0) {\n throw new Error(`Failed to set npm prefix: ${setPrefix.stderr}`)\n }\n\n // Update shell config files\n const pathUpdate = `\\n# npm global path\\nexport PATH=\"${prefix}/bin:$PATH\"\\n`\n\n if (platform === 'win32') {\n // On Windows, update user PATH environment variable\n const setxResult = await execFileNoThrow('setx', [\n 'PATH',\n `${process.env.PATH};${prefix}`,\n ])\n if (setxResult.code !== 0) {\n throw new Error(\n `Failed to update PATH on Windows: ${setxResult.stderr}`,\n )\n }\n } else {\n // Unix-like systems\n const shellConfigs = [\n // Bash\n join(homedir(), '.bashrc'),\n join(homedir(), '.bash_profile'),\n // Zsh\n join(homedir(), '.zshrc'),\n // Fish\n join(homedir(), '.config', 'fish', 'config.fish'),\n ]\n\n for (const config of shellConfigs) {\n if (existsSync(config)) {\n try {\n const content = readFileSync(config, 'utf8')\n if (!content.includes(prefix)) {\n if (config.includes('fish')) {\n // Fish shell has different syntax\n const fishPath = `\\n# npm global path\\nset -gx PATH ${prefix}/bin $PATH\\n`\n appendFileSync(config, fishPath)\n } else {\n appendFileSync(config, pathUpdate)\n }\n\n logEvent('npm_prefix_path_updated', {\n configPath: config,\n })\n }\n } catch (err) {\n // Log but don't throw - continue with other configs\n logEvent('npm_prefix_path_update_failed', {\n configPath: config,\n error:\n err instanceof Error\n ? err.message.slice(0, 200)\n : String(err).slice(0, 200),\n })\n logError(`Failed to update shell config ${config}: ${err}`)\n }\n }\n }\n }\n } finally {\n releaseLock()\n }\n}\n\nexport function getDefaultNpmPrefix(): string {\n return join(homedir(), '.npm-global')\n}\n\nexport function getPermissionsCommand(npmPrefix: string): string {\n const windowsCommand = `icacls \"${npmPrefix}\" /grant \"%USERNAME%:(OI)(CI)F\"`\n const prefixPath = npmPrefix || '$(npm -g config get prefix)'\n const unixCommand = `sudo chown -R $USER:$(id -gn) ${prefixPath} && sudo chmod -R u+w ${prefixPath}`\n\n return platform === 'win32' ? windowsCommand : unixCommand\n}\n\nexport async function getLatestVersion(): Promise<string | null> {\n // 1) Try npm CLI (fast when available)\n try {\n const abortController = new AbortController()\n setTimeout(() => abortController.abort(), 5000)\n const result = await execFileNoThrow(\n 'npm',\n ['view', MACRO.PACKAGE_URL, 'version'],\n abortController.signal,\n )\n if (result.code === 0) {\n const v = result.stdout.trim()\n if (v) return v\n }\n } catch {}\n\n // 2) Fallback: fetch npm registry (works in Bun/Node without npm)\n try {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), 5000)\n const res = await fetch(\n `https://registry.npmjs.org/${encodeURIComponent(MACRO.PACKAGE_URL)}`,\n {\n method: 'GET',\n headers: {\n Accept: 'application/vnd.npm.install-v1+json',\n 'User-Agent': `${PRODUCT_NAME}/${MACRO.VERSION}`,\n },\n signal: controller.signal,\n },\n )\n clearTimeout(timer)\n if (!res.ok) return null\n const json: any = await res.json().catch(() => null)\n const latest = json && json['dist-tags'] && json['dist-tags'].latest\n return typeof latest === 'string' ? latest : null\n } catch {\n return null\n }\n}\n\nexport async function installGlobalPackage(): Promise<InstallStatus> {\n // Detect preferred package manager and install accordingly\n if (!acquireLock()) {\n logError('Another process is currently installing an update')\n // Log the lock contention to statsig\n logEvent('tengu_auto_updater_lock_contention', {\n pid: String(process.pid),\n currentVersion: MACRO.VERSION,\n })\n return 'in_progress'\n }\n\n try {\n const manager = await detectPackageManager()\n if (manager === 'npm') {\n const { hasPermissions } = await checkNpmPermissions()\n if (!hasPermissions) {\n return 'no_permissions'\n }\n // Stream\u5B9E\u65F6\u8F93\u51FA\uFF0C\u51CF\u5C11\u7528\u6237\u7B49\u5F85\u611F\n const code = await runStreaming('npm', ['install', '-g', MACRO.PACKAGE_URL])\n if (code !== 0) {\n logError(`Failed to install new version via npm (exit ${code})`)\n return 'install_failed'\n }\n return 'success'\n }\n\n if (manager === 'bun') {\n const code = await runStreaming('bun', ['add', '-g', `${MACRO.PACKAGE_URL}@latest`])\n if (code !== 0) {\n logError(`Failed to install new version via bun (exit ${code})`)\n return 'install_failed'\n }\n return 'success'\n }\n\n // Fallback to npm if unknown\n const { hasPermissions } = await checkNpmPermissions()\n if (!hasPermissions) return 'no_permissions'\n const code = await runStreaming('npm', ['install', '-g', MACRO.PACKAGE_URL])\n if (code !== 0) return 'install_failed'\n return 'success'\n } finally {\n // Ensure we always release the lock\n releaseLock()\n }\n}\n\nexport type PackageManager = 'npm' | 'bun'\n\nexport async function detectPackageManager(): Promise<PackageManager> {\n // Respect explicit override if provided later via config/env (future-proof)\n try {\n // Heuristic 1: npm available and global root resolvable\n const npmRoot = await execFileNoThrow('npm', ['-g', 'root'])\n if (npmRoot.code === 0 && npmRoot.stdout.trim()) {\n return 'npm'\n }\n } catch {}\n\n try {\n // Heuristic 2: running on a system with bun and installed path hints bun\n const bunVer = await execFileNoThrow('bun', ['--version'])\n if (bunVer.code === 0) {\n // BUN_INSTALL defaults to ~/.bun; if our package lives under that tree, prefer bun\n // If npm not detected but bun is available, choose bun\n return 'bun'\n }\n } catch {}\n\n // Default to npm when uncertain\n return 'npm'\n}\n\nfunction runStreaming(cmd: string, args: string[]): Promise<number> {\n return new Promise(resolve => {\n // \u6253\u5370\u6B63\u5728\u4F7F\u7528\u7684\u5305\u7BA1\u7406\u5668\u4E0E\u547D\u4EE4\uFF0C\u589E\u5F3A\u900F\u660E\u5EA6\n try {\n // eslint-disable-next-line no-console\n console.log(`> ${cmd} ${args.join(' ')}`)\n } catch {}\n\n const child = spawn(cmd, args, {\n stdio: 'inherit',\n env: process.env,\n })\n child.on('close', code => resolve(code ?? 0))\n child.on('error', () => resolve(1))\n })\n}\n\n/**\n * Generate human-friendly update commands for the detected package manager.\n * Also includes an alternative manager command as fallback for users.\n */\nexport async function getUpdateCommandSuggestions(): Promise<string[]> {\n // Prefer Bun first, then npm (consistent, simple UX). Include @latest.\n return [\n `bun add -g ${MACRO.PACKAGE_URL}@latest`,\n `npm install -g ${MACRO.PACKAGE_URL}@latest`,\n ]\n}\n\n/**\n * Non-blocking update notifier (daily)\n * - Respects CI and disabled auto-updater\n * - Uses env.hasInternetAccess() to quickly skip offline cases\n * - Stores last check timestamp + last suggested version in global config\n */\nexport async function checkAndNotifyUpdate(): Promise<void> {\n try {\n if (process.env.NODE_ENV === 'test') return\n if (await isAutoUpdaterDisabled()) return\n if (await env.getIsDocker()) return\n if (!(await env.hasInternetAccess())) return\n\n const config: any = getGlobalConfig()\n const now = Date.now()\n const DAY_MS = 24 * 60 * 60 * 1000\n const lastCheck = Number(config.lastUpdateCheckAt || 0)\n if (lastCheck && now - lastCheck < DAY_MS) return\n\n const latest = await getLatestVersion()\n if (!latest) {\n // Still record the check to avoid spamming\n saveGlobalConfig({ ...config, lastUpdateCheckAt: now })\n return\n }\n\n if (gt(latest, MACRO.VERSION)) {\n // Update stored state and print a low-noise hint\n saveGlobalConfig({\n ...config,\n lastUpdateCheckAt: now,\n lastSuggestedVersion: latest,\n })\n const suggestions = await getUpdateCommandSuggestions()\n console.log(`New version available: ${latest} (current: ${MACRO.VERSION})`)\n console.log('Run the following command to update:')\n for (const command of suggestions) {\n console.log(` ${command}`)\n }\n } else {\n saveGlobalConfig({ ...config, lastUpdateCheckAt: now })\n }\n } catch (error) {\n // Never block or throw; just log and move on\n logError(`update-notify: ${error}`)\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["hasPermissions", "code"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shareai-lab/kode",
3
- "version": "1.1.23-dev.1",
3
+ "version": "1.1.23",
4
4
  "bin": {
5
5
  "kode": "cli.js",
6
6
  "kwa": "cli.js",