@xortex/xcode 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +171 -0
- package/bin/xcode +127 -0
- package/bin/xcode-test +84 -0
- package/bin/xcode.cmd +31 -0
- package/constants/apiLimits.ts +94 -0
- package/constants/betas.ts +52 -0
- package/constants/common.ts +33 -0
- package/constants/cyberRiskInstruction.ts +24 -0
- package/constants/errorIds.ts +15 -0
- package/constants/figures.ts +45 -0
- package/constants/files.ts +156 -0
- package/constants/github-app.ts +144 -0
- package/constants/keys.ts +11 -0
- package/constants/messages.ts +1 -0
- package/constants/oauth.ts +234 -0
- package/constants/outputStyles.ts +216 -0
- package/constants/product.ts +76 -0
- package/constants/prompts.ts +939 -0
- package/constants/spinnerVerbs.ts +204 -0
- package/constants/system.ts +95 -0
- package/constants/systemPromptSections.ts +68 -0
- package/constants/toolLimits.ts +56 -0
- package/constants/tools.ts +112 -0
- package/constants/turnCompletionVerbs.ts +12 -0
- package/constants/xml.ts +86 -0
- package/entrypoints/agentSdkTypes.ts +443 -0
- package/entrypoints/cli.tsx +307 -0
- package/entrypoints/init.ts +340 -0
- package/entrypoints/mcp.ts +196 -0
- package/entrypoints/sandboxTypes.ts +156 -0
- package/entrypoints/sdk/controlSchemas.ts +663 -0
- package/entrypoints/sdk/coreSchemas.ts +1889 -0
- package/entrypoints/sdk/coreTypes.generated.ts +2 -0
- package/entrypoints/sdk/coreTypes.ts +62 -0
- package/entrypoints/sdk/runtimeTypes.ts +140 -0
- package/entrypoints/sdk/sdkUtilityTypes.ts +3 -0
- package/entrypoints/sdk/toolTypes.ts +90 -0
- package/main.tsx +4686 -0
- package/package.json +120 -0
- package/services/AgentSummary/agentSummary.ts +179 -0
- package/services/MagicDocs/magicDocs.ts +254 -0
- package/services/MagicDocs/prompts.ts +127 -0
- package/services/PromptSuggestion/promptSuggestion.ts +523 -0
- package/services/PromptSuggestion/speculation.ts +991 -0
- package/services/SessionMemory/prompts.ts +324 -0
- package/services/SessionMemory/sessionMemory.ts +495 -0
- package/services/SessionMemory/sessionMemoryUtils.ts +207 -0
- package/services/analytics/config.ts +38 -0
- package/services/analytics/datadog.ts +307 -0
- package/services/analytics/firstPartyEventLogger.ts +449 -0
- package/services/analytics/firstPartyEventLoggingExporter.ts +806 -0
- package/services/analytics/growthbook.ts +1155 -0
- package/services/analytics/index.ts +173 -0
- package/services/analytics/metadata.ts +973 -0
- package/services/analytics/sink.ts +114 -0
- package/services/analytics/sinkKillswitch.ts +25 -0
- package/services/api/adminRequests.ts +119 -0
- package/services/api/bootstrap.ts +141 -0
- package/services/api/claude.ts +3422 -0
- package/services/api/client.ts +406 -0
- package/services/api/dumpPrompts.ts +226 -0
- package/services/api/emptyUsage.ts +22 -0
- package/services/api/errorUtils.ts +260 -0
- package/services/api/errors.ts +1207 -0
- package/services/api/filesApi.ts +748 -0
- package/services/api/firstTokenDate.ts +60 -0
- package/services/api/gemini.ts +359 -0
- package/services/api/geminiAdapter.ts +123 -0
- package/services/api/geminiClient.ts +291 -0
- package/services/api/grove.ts +357 -0
- package/services/api/logging.ts +788 -0
- package/services/api/metricsOptOut.ts +159 -0
- package/services/api/openRouterClient.ts +453 -0
- package/services/api/overageCreditGrant.ts +137 -0
- package/services/api/promptCacheBreakDetection.ts +727 -0
- package/services/api/referral.ts +281 -0
- package/services/api/sessionIngress.ts +514 -0
- package/services/api/ultrareviewQuota.ts +38 -0
- package/services/api/usage.ts +63 -0
- package/services/api/withRetry.ts +822 -0
- package/services/autoDream/autoDream.ts +324 -0
- package/services/autoDream/config.ts +21 -0
- package/services/autoDream/consolidationLock.ts +140 -0
- package/services/autoDream/consolidationPrompt.ts +65 -0
- package/services/awaySummary.ts +74 -0
- package/services/claudeAiLimits.ts +515 -0
- package/services/claudeAiLimitsHook.ts +23 -0
- package/services/compact/apiMicrocompact.ts +153 -0
- package/services/compact/autoCompact.ts +351 -0
- package/services/compact/compact.ts +1705 -0
- package/services/compact/compactWarningHook.ts +16 -0
- package/services/compact/compactWarningState.ts +18 -0
- package/services/compact/grouping.ts +63 -0
- package/services/compact/microCompact.ts +530 -0
- package/services/compact/postCompactCleanup.ts +77 -0
- package/services/compact/prompt.ts +374 -0
- package/services/compact/sessionMemoryCompact.ts +630 -0
- package/services/compact/timeBasedMCConfig.ts +43 -0
- package/services/diagnosticTracking.ts +397 -0
- package/services/extractMemories/extractMemories.ts +517 -0
- package/services/extractMemories/prompts.ts +154 -0
- package/services/internalLogging.ts +90 -0
- package/services/lsp/LSPClient.ts +447 -0
- package/services/lsp/LSPDiagnosticRegistry.ts +386 -0
- package/services/lsp/LSPServerInstance.ts +511 -0
- package/services/lsp/LSPServerManager.ts +420 -0
- package/services/lsp/config.ts +79 -0
- package/services/lsp/manager.ts +289 -0
- package/services/lsp/passiveFeedback.ts +328 -0
- package/services/mcp/InProcessTransport.ts +63 -0
- package/services/mcp/MCPConnectionManager.tsx +73 -0
- package/services/mcp/SdkControlTransport.ts +136 -0
- package/services/mcp/auth.ts +2465 -0
- package/services/mcp/channelAllowlist.ts +76 -0
- package/services/mcp/channelNotification.ts +316 -0
- package/services/mcp/channelPermissions.ts +240 -0
- package/services/mcp/claudeai.ts +164 -0
- package/services/mcp/client.ts +3348 -0
- package/services/mcp/config.ts +1578 -0
- package/services/mcp/elicitationHandler.ts +313 -0
- package/services/mcp/envExpansion.ts +38 -0
- package/services/mcp/headersHelper.ts +138 -0
- package/services/mcp/mcpStringUtils.ts +106 -0
- package/services/mcp/normalization.ts +23 -0
- package/services/mcp/oauthPort.ts +78 -0
- package/services/mcp/officialRegistry.ts +72 -0
- package/services/mcp/types.ts +258 -0
- package/services/mcp/useManageMCPConnections.ts +1141 -0
- package/services/mcp/utils.ts +575 -0
- package/services/mcp/vscodeSdkMcp.ts +112 -0
- package/services/mcp/xaa.ts +511 -0
- package/services/mcp/xaaIdpLogin.ts +487 -0
- package/services/mcpServerApproval.tsx +41 -0
- package/services/mockRateLimits.ts +882 -0
- package/services/notifier.ts +156 -0
- package/services/oauth/auth-code-listener.ts +211 -0
- package/services/oauth/client.ts +566 -0
- package/services/oauth/crypto.ts +23 -0
- package/services/oauth/getOauthProfile.ts +53 -0
- package/services/oauth/index.ts +198 -0
- package/services/plugins/PluginInstallationManager.ts +184 -0
- package/services/plugins/pluginCliCommands.ts +344 -0
- package/services/plugins/pluginOperations.ts +1088 -0
- package/services/policyLimits/index.ts +663 -0
- package/services/policyLimits/types.ts +27 -0
- package/services/preventSleep.ts +165 -0
- package/services/rateLimitMessages.ts +344 -0
- package/services/rateLimitMocking.ts +144 -0
- package/services/remoteManagedSettings/index.ts +638 -0
- package/services/remoteManagedSettings/securityCheck.tsx +74 -0
- package/services/remoteManagedSettings/syncCache.ts +112 -0
- package/services/remoteManagedSettings/syncCacheState.ts +96 -0
- package/services/remoteManagedSettings/types.ts +31 -0
- package/services/settingsSync/index.ts +581 -0
- package/services/settingsSync/types.ts +67 -0
- package/services/teamMemorySync/index.ts +1256 -0
- package/services/teamMemorySync/secretScanner.ts +324 -0
- package/services/teamMemorySync/teamMemSecretGuard.ts +44 -0
- package/services/teamMemorySync/types.ts +156 -0
- package/services/teamMemorySync/watcher.ts +387 -0
- package/services/tips/tipHistory.ts +17 -0
- package/services/tips/tipRegistry.ts +686 -0
- package/services/tips/tipScheduler.ts +58 -0
- package/services/tokenEstimation.ts +495 -0
- package/services/toolUseSummary/toolUseSummaryGenerator.ts +112 -0
- package/services/tools/StreamingToolExecutor.ts +530 -0
- package/services/tools/toolExecution.ts +1745 -0
- package/services/tools/toolHooks.ts +650 -0
- package/services/tools/toolOrchestration.ts +188 -0
- package/services/vcr.ts +406 -0
- package/services/voice.ts +525 -0
- package/services/voiceKeyterms.ts +106 -0
- package/services/voiceStreamSTT.ts +544 -0
- package/tools/AgentTool/AgentTool.tsx +1398 -0
- package/tools/AgentTool/UI.tsx +872 -0
- package/tools/AgentTool/agentColorManager.ts +66 -0
- package/tools/AgentTool/agentDisplay.ts +104 -0
- package/tools/AgentTool/agentMemory.ts +177 -0
- package/tools/AgentTool/agentMemorySnapshot.ts +197 -0
- package/tools/AgentTool/agentToolUtils.ts +686 -0
- package/tools/AgentTool/built-in/claudeCodeGuideAgent.ts +205 -0
- package/tools/AgentTool/built-in/exploreAgent.ts +83 -0
- package/tools/AgentTool/built-in/generalPurposeAgent.ts +34 -0
- package/tools/AgentTool/built-in/planAgent.ts +92 -0
- package/tools/AgentTool/built-in/statuslineSetup.ts +144 -0
- package/tools/AgentTool/built-in/verificationAgent.ts +152 -0
- package/tools/AgentTool/builtInAgents.ts +72 -0
- package/tools/AgentTool/constants.ts +12 -0
- package/tools/AgentTool/forkSubagent.ts +210 -0
- package/tools/AgentTool/loadAgentsDir.ts +755 -0
- package/tools/AgentTool/prompt.ts +287 -0
- package/tools/AgentTool/resumeAgent.ts +265 -0
- package/tools/AgentTool/runAgent.ts +973 -0
- package/tools/AskUserQuestionTool/AskUserQuestionTool.tsx +266 -0
- package/tools/AskUserQuestionTool/prompt.ts +44 -0
- package/tools/BashTool/BashTool.tsx +1144 -0
- package/tools/BashTool/BashToolResultMessage.tsx +191 -0
- package/tools/BashTool/UI.tsx +185 -0
- package/tools/BashTool/bashCommandHelpers.ts +265 -0
- package/tools/BashTool/bashPermissions.ts +2621 -0
- package/tools/BashTool/bashSecurity.ts +2592 -0
- package/tools/BashTool/commandSemantics.ts +140 -0
- package/tools/BashTool/commentLabel.ts +13 -0
- package/tools/BashTool/destructiveCommandWarning.ts +102 -0
- package/tools/BashTool/modeValidation.ts +115 -0
- package/tools/BashTool/pathValidation.ts +1303 -0
- package/tools/BashTool/prompt.ts +369 -0
- package/tools/BashTool/readOnlyValidation.ts +1990 -0
- package/tools/BashTool/sedEditParser.ts +322 -0
- package/tools/BashTool/sedValidation.ts +684 -0
- package/tools/BashTool/shouldUseSandbox.ts +153 -0
- package/tools/BashTool/toolName.ts +2 -0
- package/tools/BashTool/utils.ts +223 -0
- package/tools/BriefTool/BriefTool.ts +204 -0
- package/tools/BriefTool/UI.tsx +101 -0
- package/tools/BriefTool/attachments.ts +110 -0
- package/tools/BriefTool/prompt.ts +22 -0
- package/tools/BriefTool/upload.ts +174 -0
- package/tools/ConfigTool/ConfigTool.ts +467 -0
- package/tools/ConfigTool/UI.tsx +38 -0
- package/tools/ConfigTool/constants.ts +1 -0
- package/tools/ConfigTool/prompt.ts +93 -0
- package/tools/ConfigTool/supportedSettings.ts +211 -0
- package/tools/EnterPlanModeTool/EnterPlanModeTool.ts +126 -0
- package/tools/EnterPlanModeTool/UI.tsx +33 -0
- package/tools/EnterPlanModeTool/constants.ts +1 -0
- package/tools/EnterPlanModeTool/prompt.ts +170 -0
- package/tools/EnterWorktreeTool/EnterWorktreeTool.ts +127 -0
- package/tools/EnterWorktreeTool/UI.tsx +20 -0
- package/tools/EnterWorktreeTool/constants.ts +1 -0
- package/tools/EnterWorktreeTool/prompt.ts +30 -0
- package/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts +493 -0
- package/tools/ExitPlanModeTool/UI.tsx +82 -0
- package/tools/ExitPlanModeTool/constants.ts +2 -0
- package/tools/ExitPlanModeTool/prompt.ts +29 -0
- package/tools/ExitWorktreeTool/ExitWorktreeTool.ts +329 -0
- package/tools/ExitWorktreeTool/UI.tsx +25 -0
- package/tools/ExitWorktreeTool/constants.ts +1 -0
- package/tools/ExitWorktreeTool/prompt.ts +32 -0
- package/tools/FileEditTool/FileEditTool.ts +625 -0
- package/tools/FileEditTool/UI.tsx +289 -0
- package/tools/FileEditTool/constants.ts +11 -0
- package/tools/FileEditTool/prompt.ts +28 -0
- package/tools/FileEditTool/types.ts +85 -0
- package/tools/FileEditTool/utils.ts +775 -0
- package/tools/FileReadTool/FileReadTool.ts +1183 -0
- package/tools/FileReadTool/UI.tsx +185 -0
- package/tools/FileReadTool/imageProcessor.ts +94 -0
- package/tools/FileReadTool/limits.ts +92 -0
- package/tools/FileReadTool/prompt.ts +49 -0
- package/tools/FileWriteTool/FileWriteTool.ts +434 -0
- package/tools/FileWriteTool/UI.tsx +405 -0
- package/tools/FileWriteTool/prompt.ts +18 -0
- package/tools/GlobTool/GlobTool.ts +198 -0
- package/tools/GlobTool/UI.tsx +63 -0
- package/tools/GlobTool/prompt.ts +7 -0
- package/tools/GrepTool/GrepTool.ts +577 -0
- package/tools/GrepTool/UI.tsx +201 -0
- package/tools/GrepTool/prompt.ts +18 -0
- package/tools/LSPTool/LSPTool.ts +860 -0
- package/tools/LSPTool/UI.tsx +228 -0
- package/tools/LSPTool/formatters.ts +592 -0
- package/tools/LSPTool/prompt.ts +21 -0
- package/tools/LSPTool/schemas.ts +215 -0
- package/tools/LSPTool/symbolContext.ts +90 -0
- package/tools/ListMcpResourcesTool/ListMcpResourcesTool.ts +123 -0
- package/tools/ListMcpResourcesTool/UI.tsx +29 -0
- package/tools/ListMcpResourcesTool/prompt.ts +20 -0
- package/tools/MCPTool/MCPTool.ts +77 -0
- package/tools/MCPTool/UI.tsx +403 -0
- package/tools/MCPTool/classifyForCollapse.ts +604 -0
- package/tools/MCPTool/prompt.ts +3 -0
- package/tools/McpAuthTool/McpAuthTool.ts +215 -0
- package/tools/NotebookEditTool/NotebookEditTool.ts +490 -0
- package/tools/NotebookEditTool/UI.tsx +93 -0
- package/tools/NotebookEditTool/constants.ts +2 -0
- package/tools/NotebookEditTool/prompt.ts +3 -0
- package/tools/PowerShellTool/PowerShellTool.tsx +1001 -0
- package/tools/PowerShellTool/UI.tsx +131 -0
- package/tools/PowerShellTool/clmTypes.ts +211 -0
- package/tools/PowerShellTool/commandSemantics.ts +142 -0
- package/tools/PowerShellTool/commonParameters.ts +30 -0
- package/tools/PowerShellTool/destructiveCommandWarning.ts +109 -0
- package/tools/PowerShellTool/gitSafety.ts +176 -0
- package/tools/PowerShellTool/modeValidation.ts +404 -0
- package/tools/PowerShellTool/pathValidation.ts +2049 -0
- package/tools/PowerShellTool/powershellPermissions.ts +1648 -0
- package/tools/PowerShellTool/powershellSecurity.ts +1090 -0
- package/tools/PowerShellTool/prompt.ts +145 -0
- package/tools/PowerShellTool/readOnlyValidation.ts +1823 -0
- package/tools/PowerShellTool/toolName.ts +2 -0
- package/tools/REPLTool/constants.ts +46 -0
- package/tools/REPLTool/primitiveTools.ts +39 -0
- package/tools/ReadMcpResourceTool/ReadMcpResourceTool.ts +158 -0
- package/tools/ReadMcpResourceTool/UI.tsx +37 -0
- package/tools/ReadMcpResourceTool/prompt.ts +16 -0
- package/tools/RemoteTriggerTool/RemoteTriggerTool.ts +161 -0
- package/tools/RemoteTriggerTool/UI.tsx +17 -0
- package/tools/RemoteTriggerTool/prompt.ts +15 -0
- package/tools/ScheduleCronTool/CronCreateTool.ts +157 -0
- package/tools/ScheduleCronTool/CronDeleteTool.ts +95 -0
- package/tools/ScheduleCronTool/CronListTool.ts +97 -0
- package/tools/ScheduleCronTool/UI.tsx +60 -0
- package/tools/ScheduleCronTool/prompt.ts +135 -0
- package/tools/SendMessageTool/SendMessageTool.ts +917 -0
- package/tools/SendMessageTool/UI.tsx +31 -0
- package/tools/SendMessageTool/constants.ts +1 -0
- package/tools/SendMessageTool/prompt.ts +49 -0
- package/tools/SkillTool/SkillTool.ts +1108 -0
- package/tools/SkillTool/UI.tsx +128 -0
- package/tools/SkillTool/constants.ts +1 -0
- package/tools/SkillTool/prompt.ts +241 -0
- package/tools/SleepTool/prompt.ts +17 -0
- package/tools/SyntheticOutputTool/SyntheticOutputTool.ts +163 -0
- package/tools/TaskCreateTool/TaskCreateTool.ts +138 -0
- package/tools/TaskCreateTool/constants.ts +1 -0
- package/tools/TaskCreateTool/prompt.ts +56 -0
- package/tools/TaskGetTool/TaskGetTool.ts +128 -0
- package/tools/TaskGetTool/constants.ts +1 -0
- package/tools/TaskGetTool/prompt.ts +24 -0
- package/tools/TaskListTool/TaskListTool.ts +116 -0
- package/tools/TaskListTool/constants.ts +1 -0
- package/tools/TaskListTool/prompt.ts +49 -0
- package/tools/TaskOutputTool/TaskOutputTool.tsx +584 -0
- package/tools/TaskOutputTool/constants.ts +1 -0
- package/tools/TaskStopTool/TaskStopTool.ts +131 -0
- package/tools/TaskStopTool/UI.tsx +41 -0
- package/tools/TaskStopTool/prompt.ts +8 -0
- package/tools/TaskUpdateTool/TaskUpdateTool.ts +406 -0
- package/tools/TaskUpdateTool/constants.ts +1 -0
- package/tools/TaskUpdateTool/prompt.ts +77 -0
- package/tools/TeamCreateTool/TeamCreateTool.ts +240 -0
- package/tools/TeamCreateTool/UI.tsx +6 -0
- package/tools/TeamCreateTool/constants.ts +1 -0
- package/tools/TeamCreateTool/prompt.ts +113 -0
- package/tools/TeamDeleteTool/TeamDeleteTool.ts +139 -0
- package/tools/TeamDeleteTool/UI.tsx +20 -0
- package/tools/TeamDeleteTool/constants.ts +1 -0
- package/tools/TeamDeleteTool/prompt.ts +16 -0
- package/tools/TodoWriteTool/TodoWriteTool.ts +115 -0
- package/tools/TodoWriteTool/constants.ts +1 -0
- package/tools/TodoWriteTool/prompt.ts +184 -0
- package/tools/ToolSearchTool/ToolSearchTool.ts +471 -0
- package/tools/ToolSearchTool/constants.ts +1 -0
- package/tools/ToolSearchTool/prompt.ts +121 -0
- package/tools/TungstenTool/TungstenTool.ts +4 -0
- package/tools/WebFetchTool/UI.tsx +72 -0
- package/tools/WebFetchTool/WebFetchTool.ts +318 -0
- package/tools/WebFetchTool/preapproved.ts +166 -0
- package/tools/WebFetchTool/prompt.ts +46 -0
- package/tools/WebFetchTool/utils.ts +530 -0
- package/tools/WebSearchTool/UI.tsx +101 -0
- package/tools/WebSearchTool/WebSearchTool.ts +435 -0
- package/tools/WebSearchTool/prompt.ts +34 -0
- package/tools/WorkflowTool/constants.ts +2 -0
- package/tools/XMemIngestTool/XMemIngestTool.ts +140 -0
- package/tools/XMemIngestTool/prompt.ts +13 -0
- package/tools/XMemRetrieveTool/XMemRetrieveTool.ts +177 -0
- package/tools/XMemRetrieveTool/prompt.ts +16 -0
- package/tools/XMemSearchTool/XMemSearchTool.ts +172 -0
- package/tools/XMemSearchTool/prompt.ts +11 -0
- package/tools/shared/gitOperationTracking.ts +277 -0
- package/tools/shared/spawnMultiAgent.ts +1093 -0
- package/tools/testing/TestingPermissionTool.tsx +74 -0
- package/tools/utils.ts +40 -0
- package/utils/CircularBuffer.ts +84 -0
- package/utils/Cursor.ts +1530 -0
- package/utils/QueryGuard.ts +121 -0
- package/utils/Shell.ts +474 -0
- package/utils/ShellCommand.ts +465 -0
- package/utils/abortController.ts +99 -0
- package/utils/activityManager.ts +164 -0
- package/utils/advisor.ts +145 -0
- package/utils/agentContext.ts +178 -0
- package/utils/agentId.ts +99 -0
- package/utils/agentSwarmsEnabled.ts +44 -0
- package/utils/agenticSessionSearch.ts +307 -0
- package/utils/analyzeContext.ts +1382 -0
- package/utils/ansiToPng.ts +334 -0
- package/utils/ansiToSvg.ts +272 -0
- package/utils/api.ts +718 -0
- package/utils/apiPreconnect.ts +71 -0
- package/utils/appleTerminalBackup.ts +124 -0
- package/utils/argumentSubstitution.ts +145 -0
- package/utils/array.ts +13 -0
- package/utils/asciicast.ts +239 -0
- package/utils/attachments.ts +4091 -0
- package/utils/attribution.ts +393 -0
- package/utils/auth.ts +2002 -0
- package/utils/authFileDescriptor.ts +196 -0
- package/utils/authPortable.ts +19 -0
- package/utils/autoModeDenials.ts +26 -0
- package/utils/autoRunIssue.tsx +122 -0
- package/utils/autoUpdater.ts +561 -0
- package/utils/aws.ts +74 -0
- package/utils/awsAuthStatusManager.ts +81 -0
- package/utils/axios.ts +8 -0
- package/utils/background/remote/preconditions.ts +235 -0
- package/utils/background/remote/remoteSession.ts +98 -0
- package/utils/backgroundHousekeeping.ts +94 -0
- package/utils/bash/ParsedCommand.ts +318 -0
- package/utils/bash/ShellSnapshot.ts +582 -0
- package/utils/bash/ast.ts +2679 -0
- package/utils/bash/bashParser.ts +4436 -0
- package/utils/bash/bashPipeCommand.ts +294 -0
- package/utils/bash/commands.ts +1339 -0
- package/utils/bash/heredoc.ts +733 -0
- package/utils/bash/parser.ts +230 -0
- package/utils/bash/prefix.ts +204 -0
- package/utils/bash/registry.ts +53 -0
- package/utils/bash/shellCompletion.ts +259 -0
- package/utils/bash/shellPrefix.ts +28 -0
- package/utils/bash/shellQuote.ts +304 -0
- package/utils/bash/shellQuoting.ts +128 -0
- package/utils/bash/specs/alias.ts +14 -0
- package/utils/bash/specs/index.ts +18 -0
- package/utils/bash/specs/nohup.ts +13 -0
- package/utils/bash/specs/pyright.ts +91 -0
- package/utils/bash/specs/sleep.ts +13 -0
- package/utils/bash/specs/srun.ts +31 -0
- package/utils/bash/specs/time.ts +13 -0
- package/utils/bash/specs/timeout.ts +20 -0
- package/utils/bash/treeSitterAnalysis.ts +506 -0
- package/utils/betas.ts +434 -0
- package/utils/billing.ts +78 -0
- package/utils/binaryCheck.ts +53 -0
- package/utils/browser.ts +68 -0
- package/utils/bufferedWriter.ts +100 -0
- package/utils/bundledMode.ts +22 -0
- package/utils/caCerts.ts +115 -0
- package/utils/caCertsConfig.ts +88 -0
- package/utils/cachePaths.ts +38 -0
- package/utils/classifierApprovals.ts +88 -0
- package/utils/classifierApprovalsHook.ts +17 -0
- package/utils/claudeCodeHints.ts +193 -0
- package/utils/claudeDesktop.ts +152 -0
- package/utils/claudeInChrome/chromeNativeHost.ts +527 -0
- package/utils/claudeInChrome/common.ts +540 -0
- package/utils/claudeInChrome/mcpServer.ts +292 -0
- package/utils/claudeInChrome/prompt.ts +83 -0
- package/utils/claudeInChrome/setup.ts +400 -0
- package/utils/claudeInChrome/setupPortable.ts +233 -0
- package/utils/claudeInChrome/toolRendering.tsx +262 -0
- package/utils/claudemd.ts +1479 -0
- package/utils/cleanup.ts +602 -0
- package/utils/cleanupRegistry.ts +25 -0
- package/utils/cliArgs.ts +60 -0
- package/utils/cliHighlight.ts +54 -0
- package/utils/codeIndexing.ts +206 -0
- package/utils/collapseBackgroundBashNotifications.ts +84 -0
- package/utils/collapseHookSummaries.ts +59 -0
- package/utils/collapseReadSearch.ts +1109 -0
- package/utils/collapseTeammateShutdowns.ts +55 -0
- package/utils/color-diff-mock.ts +27 -0
- package/utils/combinedAbortSignal.ts +47 -0
- package/utils/commandLifecycle.ts +21 -0
- package/utils/commitAttribution.ts +961 -0
- package/utils/completionCache.ts +166 -0
- package/utils/computerUse/appNames.ts +196 -0
- package/utils/computerUse/cleanup.ts +86 -0
- package/utils/computerUse/common.ts +61 -0
- package/utils/computerUse/computerUseLock.ts +215 -0
- package/utils/computerUse/drainRunLoop.ts +79 -0
- package/utils/computerUse/escHotkey.ts +54 -0
- package/utils/computerUse/executor.ts +658 -0
- package/utils/computerUse/gates.ts +72 -0
- package/utils/computerUse/hostAdapter.ts +69 -0
- package/utils/computerUse/inputLoader.ts +30 -0
- package/utils/computerUse/mcpServer.ts +106 -0
- package/utils/computerUse/setup.ts +53 -0
- package/utils/computerUse/swiftLoader.ts +23 -0
- package/utils/computerUse/toolRendering.tsx +125 -0
- package/utils/computerUse/wrapper.tsx +336 -0
- package/utils/concurrentSessions.ts +204 -0
- package/utils/config.ts +1817 -0
- package/utils/configConstants.ts +21 -0
- package/utils/contentArray.ts +51 -0
- package/utils/context.ts +221 -0
- package/utils/contextAnalysis.ts +272 -0
- package/utils/contextSuggestions.ts +235 -0
- package/utils/controlMessageCompat.ts +32 -0
- package/utils/conversationRecovery.ts +597 -0
- package/utils/cron.ts +308 -0
- package/utils/cronJitterConfig.ts +75 -0
- package/utils/cronScheduler.ts +565 -0
- package/utils/cronTasks.ts +458 -0
- package/utils/cronTasksLock.ts +195 -0
- package/utils/crossProjectResume.ts +75 -0
- package/utils/crypto.ts +13 -0
- package/utils/cwd.ts +32 -0
- package/utils/debug.ts +268 -0
- package/utils/debugFilter.ts +157 -0
- package/utils/deepLink/banner.ts +123 -0
- package/utils/deepLink/parseDeepLink.ts +170 -0
- package/utils/deepLink/protocolHandler.ts +136 -0
- package/utils/deepLink/registerProtocol.ts +348 -0
- package/utils/deepLink/terminalLauncher.ts +557 -0
- package/utils/deepLink/terminalPreference.ts +54 -0
- package/utils/desktopDeepLink.ts +236 -0
- package/utils/detectRepository.ts +178 -0
- package/utils/diagLogs.ts +94 -0
- package/utils/diff.ts +177 -0
- package/utils/directMemberMessage.ts +69 -0
- package/utils/displayTags.ts +51 -0
- package/utils/doctorContextWarnings.ts +265 -0
- package/utils/doctorDiagnostic.ts +625 -0
- package/utils/dxt/helpers.ts +88 -0
- package/utils/dxt/zip.ts +226 -0
- package/utils/earlyInput.ts +191 -0
- package/utils/editor.ts +183 -0
- package/utils/effort.ts +329 -0
- package/utils/embeddedTools.ts +29 -0
- package/utils/env.ts +347 -0
- package/utils/envDynamic.ts +151 -0
- package/utils/envUtils.ts +183 -0
- package/utils/envValidation.ts +38 -0
- package/utils/errorLogSink.ts +235 -0
- package/utils/errors.ts +238 -0
- package/utils/exampleCommands.ts +184 -0
- package/utils/execFileNoThrow.ts +150 -0
- package/utils/execFileNoThrowPortable.ts +89 -0
- package/utils/execSyncWrapper.ts +38 -0
- package/utils/exportRenderer.tsx +98 -0
- package/utils/extraUsage.ts +23 -0
- package/utils/fastMode.ts +532 -0
- package/utils/file.ts +584 -0
- package/utils/fileHistory.ts +1115 -0
- package/utils/fileOperationAnalytics.ts +71 -0
- package/utils/filePersistence/filePersistence.ts +287 -0
- package/utils/filePersistence/outputsScanner.ts +126 -0
- package/utils/fileRead.ts +102 -0
- package/utils/fileReadCache.ts +96 -0
- package/utils/fileStateCache.ts +142 -0
- package/utils/findExecutable.ts +17 -0
- package/utils/fingerprint.ts +76 -0
- package/utils/forkedAgent.ts +689 -0
- package/utils/format.ts +308 -0
- package/utils/formatBriefTimestamp.ts +81 -0
- package/utils/fpsTracker.ts +47 -0
- package/utils/frontmatterParser.ts +370 -0
- package/utils/fsOperations.ts +770 -0
- package/utils/fullscreen.ts +202 -0
- package/utils/generatedFiles.ts +136 -0
- package/utils/generators.ts +88 -0
- package/utils/genericProcessUtils.ts +184 -0
- package/utils/getWorktreePaths.ts +70 -0
- package/utils/getWorktreePathsPortable.ts +27 -0
- package/utils/ghPrStatus.ts +106 -0
- package/utils/git/gitConfigParser.ts +277 -0
- package/utils/git/gitFilesystem.ts +699 -0
- package/utils/git/gitignore.ts +99 -0
- package/utils/git.ts +926 -0
- package/utils/gitDiff.ts +532 -0
- package/utils/gitSettings.ts +18 -0
- package/utils/github/ghAuthStatus.ts +29 -0
- package/utils/githubRepoPathMapping.ts +162 -0
- package/utils/glob.ts +130 -0
- package/utils/gracefulShutdown.ts +529 -0
- package/utils/groupToolUses.ts +182 -0
- package/utils/handlePromptSubmit.ts +610 -0
- package/utils/hash.ts +46 -0
- package/utils/headlessProfiler.ts +178 -0
- package/utils/heapDumpService.ts +303 -0
- package/utils/heatmap.ts +198 -0
- package/utils/highlightMatch.tsx +28 -0
- package/utils/hooks/AsyncHookRegistry.ts +309 -0
- package/utils/hooks/apiQueryHookHelper.ts +141 -0
- package/utils/hooks/execAgentHook.ts +339 -0
- package/utils/hooks/execHttpHook.ts +242 -0
- package/utils/hooks/execPromptHook.ts +211 -0
- package/utils/hooks/fileChangedWatcher.ts +191 -0
- package/utils/hooks/hookEvents.ts +192 -0
- package/utils/hooks/hookHelpers.ts +83 -0
- package/utils/hooks/hooksConfigManager.ts +400 -0
- package/utils/hooks/hooksConfigSnapshot.ts +133 -0
- package/utils/hooks/hooksSettings.ts +271 -0
- package/utils/hooks/postSamplingHooks.ts +70 -0
- package/utils/hooks/registerFrontmatterHooks.ts +67 -0
- package/utils/hooks/registerSkillHooks.ts +64 -0
- package/utils/hooks/sessionHooks.ts +447 -0
- package/utils/hooks/skillImprovement.ts +267 -0
- package/utils/hooks/ssrfGuard.ts +294 -0
- package/utils/hooks.ts +5022 -0
- package/utils/horizontalScroll.ts +137 -0
- package/utils/http.ts +136 -0
- package/utils/hyperlink.ts +39 -0
- package/utils/iTermBackup.ts +73 -0
- package/utils/ide.ts +1494 -0
- package/utils/idePathConversion.ts +90 -0
- package/utils/idleTimeout.ts +53 -0
- package/utils/imagePaste.ts +416 -0
- package/utils/imageResizer.ts +880 -0
- package/utils/imageStore.ts +167 -0
- package/utils/imageValidation.ts +104 -0
- package/utils/immediateCommand.ts +15 -0
- package/utils/inProcessTeammateHelpers.ts +102 -0
- package/utils/ink.ts +26 -0
- package/utils/intl.ts +94 -0
- package/utils/jetbrains.ts +191 -0
- package/utils/json.ts +277 -0
- package/utils/jsonRead.ts +16 -0
- package/utils/keyboardShortcuts.ts +14 -0
- package/utils/lazySchema.ts +8 -0
- package/utils/listSessionsImpl.ts +454 -0
- package/utils/localInstaller.ts +162 -0
- package/utils/lockfile.ts +43 -0
- package/utils/log.ts +362 -0
- package/utils/logoV2Utils.ts +347 -0
- package/utils/mailbox.ts +73 -0
- package/utils/managedEnv.ts +199 -0
- package/utils/managedEnvConstants.ts +191 -0
- package/utils/markdown.ts +381 -0
- package/utils/markdownConfigLoader.ts +600 -0
- package/utils/mcp/dateTimeParser.ts +121 -0
- package/utils/mcp/elicitationValidation.ts +336 -0
- package/utils/mcpInstructionsDelta.ts +130 -0
- package/utils/mcpOutputStorage.ts +189 -0
- package/utils/mcpValidation.ts +208 -0
- package/utils/mcpWebSocketTransport.ts +200 -0
- package/utils/memoize.ts +269 -0
- package/utils/memory/types.ts +12 -0
- package/utils/memory/versions.ts +8 -0
- package/utils/memoryFileDetection.ts +289 -0
- package/utils/messagePredicates.ts +8 -0
- package/utils/messageQueueManager.ts +547 -0
- package/utils/messages/mappers.ts +290 -0
- package/utils/messages/systemInit.ts +96 -0
- package/utils/messages.ts +5520 -0
- package/utils/model/agent.ts +157 -0
- package/utils/model/aliases.ts +35 -0
- package/utils/model/antModels.ts +64 -0
- package/utils/model/bedrock.ts +265 -0
- package/utils/model/check1mAccess.ts +72 -0
- package/utils/model/configs.ts +158 -0
- package/utils/model/contextWindowUpgradeCheck.ts +47 -0
- package/utils/model/deprecation.ts +101 -0
- package/utils/model/model.ts +654 -0
- package/utils/model/modelAllowlist.ts +170 -0
- package/utils/model/modelCapabilities.ts +118 -0
- package/utils/model/modelOptions.ts +589 -0
- package/utils/model/modelStrings.ts +170 -0
- package/utils/model/modelSupportOverrides.ts +50 -0
- package/utils/model/providers.ts +42 -0
- package/utils/model/validateModel.ts +159 -0
- package/utils/modelCost.ts +231 -0
- package/utils/modifiers.ts +36 -0
- package/utils/mtls.ts +179 -0
- package/utils/nativeInstaller/download.ts +523 -0
- package/utils/nativeInstaller/index.ts +18 -0
- package/utils/nativeInstaller/installer.ts +1708 -0
- package/utils/nativeInstaller/packageManagers.ts +336 -0
- package/utils/nativeInstaller/pidLock.ts +433 -0
- package/utils/notebook.ts +224 -0
- package/utils/objectGroupBy.ts +18 -0
- package/utils/pasteStore.ts +104 -0
- package/utils/path.ts +155 -0
- package/utils/pdf.ts +300 -0
- package/utils/pdfUtils.ts +70 -0
- package/utils/peerAddress.ts +21 -0
- package/utils/permissions/PermissionMode.ts +141 -0
- package/utils/permissions/PermissionPromptToolResultSchema.ts +127 -0
- package/utils/permissions/PermissionResult.ts +35 -0
- package/utils/permissions/PermissionRule.ts +40 -0
- package/utils/permissions/PermissionUpdate.ts +389 -0
- package/utils/permissions/PermissionUpdateSchema.ts +78 -0
- package/utils/permissions/autoModeState.ts +39 -0
- package/utils/permissions/bashClassifier.ts +61 -0
- package/utils/permissions/bypassPermissionsKillswitch.ts +155 -0
- package/utils/permissions/classifierDecision.ts +98 -0
- package/utils/permissions/classifierShared.ts +39 -0
- package/utils/permissions/dangerousPatterns.ts +80 -0
- package/utils/permissions/denialTracking.ts +45 -0
- package/utils/permissions/filesystem.ts +1777 -0
- package/utils/permissions/getNextPermissionMode.ts +101 -0
- package/utils/permissions/pathValidation.ts +485 -0
- package/utils/permissions/permissionExplainer.ts +250 -0
- package/utils/permissions/permissionRuleParser.ts +198 -0
- package/utils/permissions/permissionSetup.ts +1532 -0
- package/utils/permissions/permissions.ts +1486 -0
- package/utils/permissions/permissionsLoader.ts +296 -0
- package/utils/permissions/shadowedRuleDetection.ts +234 -0
- package/utils/permissions/shellRuleMatching.ts +228 -0
- package/utils/permissions/yoloClassifier.ts +1495 -0
- package/utils/planModeV2.ts +95 -0
- package/utils/plans.ts +397 -0
- package/utils/platform.ts +150 -0
- package/utils/plugins/addDirPluginSettings.ts +71 -0
- package/utils/plugins/cacheUtils.ts +196 -0
- package/utils/plugins/dependencyResolver.ts +305 -0
- package/utils/plugins/fetchTelemetry.ts +135 -0
- package/utils/plugins/gitAvailability.ts +69 -0
- package/utils/plugins/headlessPluginInstall.ts +174 -0
- package/utils/plugins/hintRecommendation.ts +164 -0
- package/utils/plugins/installCounts.ts +292 -0
- package/utils/plugins/installedPluginsManager.ts +1268 -0
- package/utils/plugins/loadPluginAgents.ts +348 -0
- package/utils/plugins/loadPluginCommands.ts +946 -0
- package/utils/plugins/loadPluginHooks.ts +287 -0
- package/utils/plugins/loadPluginOutputStyles.ts +178 -0
- package/utils/plugins/lspPluginIntegration.ts +387 -0
- package/utils/plugins/lspRecommendation.ts +374 -0
- package/utils/plugins/managedPlugins.ts +27 -0
- package/utils/plugins/marketplaceHelpers.ts +592 -0
- package/utils/plugins/marketplaceManager.ts +2643 -0
- package/utils/plugins/mcpPluginIntegration.ts +634 -0
- package/utils/plugins/mcpbHandler.ts +968 -0
- package/utils/plugins/officialMarketplace.ts +25 -0
- package/utils/plugins/officialMarketplaceGcs.ts +216 -0
- package/utils/plugins/officialMarketplaceStartupCheck.ts +439 -0
- package/utils/plugins/orphanedPluginFilter.ts +114 -0
- package/utils/plugins/parseMarketplaceInput.ts +162 -0
- package/utils/plugins/performStartupChecks.tsx +70 -0
- package/utils/plugins/pluginAutoupdate.ts +284 -0
- package/utils/plugins/pluginBlocklist.ts +127 -0
- package/utils/plugins/pluginDirectories.ts +178 -0
- package/utils/plugins/pluginFlagging.ts +208 -0
- package/utils/plugins/pluginIdentifier.ts +123 -0
- package/utils/plugins/pluginInstallationHelpers.ts +595 -0
- package/utils/plugins/pluginLoader.ts +3302 -0
- package/utils/plugins/pluginOptionsStorage.ts +400 -0
- package/utils/plugins/pluginPolicy.ts +20 -0
- package/utils/plugins/pluginStartupCheck.ts +341 -0
- package/utils/plugins/pluginVersioning.ts +157 -0
- package/utils/plugins/reconciler.ts +265 -0
- package/utils/plugins/refresh.ts +215 -0
- package/utils/plugins/schemas.ts +1681 -0
- package/utils/plugins/validatePlugin.ts +903 -0
- package/utils/plugins/walkPluginMarkdown.ts +69 -0
- package/utils/plugins/zipCache.ts +406 -0
- package/utils/plugins/zipCacheAdapters.ts +164 -0
- package/utils/powershell/dangerousCmdlets.ts +185 -0
- package/utils/powershell/parser.ts +1804 -0
- package/utils/powershell/staticPrefix.ts +316 -0
- package/utils/preflightChecks.tsx +151 -0
- package/utils/privacyLevel.ts +55 -0
- package/utils/process.ts +68 -0
- package/utils/processUserInput/processBashCommand.tsx +140 -0
- package/utils/processUserInput/processSlashCommand.tsx +922 -0
- package/utils/processUserInput/processTextPrompt.ts +100 -0
- package/utils/processUserInput/processUserInput.ts +605 -0
- package/utils/profilerBase.ts +46 -0
- package/utils/promptCategory.ts +49 -0
- package/utils/promptEditor.ts +188 -0
- package/utils/promptShellExecution.ts +183 -0
- package/utils/proxy.ts +426 -0
- package/utils/queryContext.ts +179 -0
- package/utils/queryHelpers.ts +552 -0
- package/utils/queryProfiler.ts +301 -0
- package/utils/queueProcessor.ts +95 -0
- package/utils/readEditContext.ts +227 -0
- package/utils/readFileInRange.ts +383 -0
- package/utils/releaseNotes.ts +360 -0
- package/utils/renderOptions.ts +113 -0
- package/utils/ripgrep.ts +679 -0
- package/utils/sandbox/sandbox-adapter.ts +985 -0
- package/utils/sandbox/sandbox-ui-utils.ts +12 -0
- package/utils/sanitization.ts +91 -0
- package/utils/screenshotClipboard.ts +121 -0
- package/utils/sdkEventQueue.ts +134 -0
- package/utils/secureStorage/fallbackStorage.ts +70 -0
- package/utils/secureStorage/index.ts +17 -0
- package/utils/secureStorage/keychainPrefetch.ts +116 -0
- package/utils/secureStorage/macOsKeychainHelpers.ts +111 -0
- package/utils/secureStorage/macOsKeychainStorage.ts +231 -0
- package/utils/secureStorage/plainTextStorage.ts +84 -0
- package/utils/semanticBoolean.ts +29 -0
- package/utils/semanticNumber.ts +36 -0
- package/utils/semver.ts +59 -0
- package/utils/sequential.ts +56 -0
- package/utils/sessionActivity.ts +133 -0
- package/utils/sessionEnvVars.ts +22 -0
- package/utils/sessionEnvironment.ts +166 -0
- package/utils/sessionFileAccessHooks.ts +250 -0
- package/utils/sessionIngressAuth.ts +140 -0
- package/utils/sessionRestore.ts +551 -0
- package/utils/sessionStart.ts +232 -0
- package/utils/sessionState.ts +150 -0
- package/utils/sessionStorage.ts +5105 -0
- package/utils/sessionStoragePortable.ts +793 -0
- package/utils/sessionTitle.ts +129 -0
- package/utils/sessionUrl.ts +64 -0
- package/utils/set.ts +53 -0
- package/utils/settings/allErrors.ts +32 -0
- package/utils/settings/applySettingsChange.ts +92 -0
- package/utils/settings/changeDetector.ts +488 -0
- package/utils/settings/constants.ts +202 -0
- package/utils/settings/internalWrites.ts +37 -0
- package/utils/settings/managedPath.ts +34 -0
- package/utils/settings/mdm/constants.ts +81 -0
- package/utils/settings/mdm/rawRead.ts +130 -0
- package/utils/settings/mdm/settings.ts +316 -0
- package/utils/settings/permissionValidation.ts +262 -0
- package/utils/settings/pluginOnlyPolicy.ts +60 -0
- package/utils/settings/schemaOutput.ts +8 -0
- package/utils/settings/settings.ts +1015 -0
- package/utils/settings/settingsCache.ts +80 -0
- package/utils/settings/toolValidationConfig.ts +103 -0
- package/utils/settings/types.ts +1149 -0
- package/utils/settings/validateEditTool.ts +45 -0
- package/utils/settings/validation.ts +265 -0
- package/utils/settings/validationTips.ts +164 -0
- package/utils/shell/bashProvider.ts +255 -0
- package/utils/shell/outputLimits.ts +14 -0
- package/utils/shell/powershellDetection.ts +107 -0
- package/utils/shell/powershellProvider.ts +123 -0
- package/utils/shell/prefix.ts +367 -0
- package/utils/shell/readOnlyCommandValidation.ts +1893 -0
- package/utils/shell/resolveDefaultShell.ts +14 -0
- package/utils/shell/shellProvider.ts +33 -0
- package/utils/shell/shellToolUtils.ts +22 -0
- package/utils/shell/specPrefix.ts +241 -0
- package/utils/shellConfig.ts +167 -0
- package/utils/sideQuery.ts +222 -0
- package/utils/sideQuestion.ts +155 -0
- package/utils/signal.ts +43 -0
- package/utils/sinks.ts +16 -0
- package/utils/skills/skillChangeDetector.ts +311 -0
- package/utils/slashCommandParsing.ts +60 -0
- package/utils/sleep.ts +84 -0
- package/utils/sliceAnsi.ts +91 -0
- package/utils/slowOperations.ts +286 -0
- package/utils/standaloneAgent.ts +23 -0
- package/utils/startupProfiler.ts +194 -0
- package/utils/staticRender.tsx +116 -0
- package/utils/stats.ts +1061 -0
- package/utils/statsCache.ts +434 -0
- package/utils/status.tsx +362 -0
- package/utils/statusNoticeDefinitions.tsx +198 -0
- package/utils/statusNoticeHelpers.ts +20 -0
- package/utils/stream.ts +76 -0
- package/utils/streamJsonStdoutGuard.ts +123 -0
- package/utils/streamlinedTransform.ts +201 -0
- package/utils/stringUtils.ts +235 -0
- package/utils/subprocessEnv.ts +99 -0
- package/utils/suggestions/commandSuggestions.ts +567 -0
- package/utils/suggestions/directoryCompletion.ts +263 -0
- package/utils/suggestions/shellHistoryCompletion.ts +119 -0
- package/utils/suggestions/skillUsageTracking.ts +55 -0
- package/utils/suggestions/slackChannelSuggestions.ts +209 -0
- package/utils/swarm/It2SetupPrompt.tsx +380 -0
- package/utils/swarm/backends/ITermBackend.ts +370 -0
- package/utils/swarm/backends/InProcessBackend.ts +339 -0
- package/utils/swarm/backends/PaneBackendExecutor.ts +354 -0
- package/utils/swarm/backends/TmuxBackend.ts +764 -0
- package/utils/swarm/backends/detection.ts +128 -0
- package/utils/swarm/backends/it2Setup.ts +245 -0
- package/utils/swarm/backends/registry.ts +464 -0
- package/utils/swarm/backends/teammateModeSnapshot.ts +87 -0
- package/utils/swarm/backends/types.ts +311 -0
- package/utils/swarm/constants.ts +33 -0
- package/utils/swarm/inProcessRunner.ts +1552 -0
- package/utils/swarm/leaderPermissionBridge.ts +54 -0
- package/utils/swarm/permissionSync.ts +928 -0
- package/utils/swarm/reconnection.ts +119 -0
- package/utils/swarm/spawnInProcess.ts +328 -0
- package/utils/swarm/spawnUtils.ts +146 -0
- package/utils/swarm/teamHelpers.ts +683 -0
- package/utils/swarm/teammateInit.ts +129 -0
- package/utils/swarm/teammateLayoutManager.ts +107 -0
- package/utils/swarm/teammateModel.ts +10 -0
- package/utils/swarm/teammatePromptAddendum.ts +18 -0
- package/utils/systemDirectories.ts +74 -0
- package/utils/systemPrompt.ts +123 -0
- package/utils/systemPromptType.ts +14 -0
- package/utils/systemTheme.ts +119 -0
- package/utils/taggedId.ts +54 -0
- package/utils/task/TaskOutput.ts +390 -0
- package/utils/task/diskOutput.ts +451 -0
- package/utils/task/framework.ts +308 -0
- package/utils/task/outputFormatting.ts +38 -0
- package/utils/task/sdkProgress.ts +36 -0
- package/utils/tasks.ts +862 -0
- package/utils/teamDiscovery.ts +81 -0
- package/utils/teamMemoryOps.ts +88 -0
- package/utils/teammate.ts +292 -0
- package/utils/teammateContext.ts +96 -0
- package/utils/teammateMailbox.ts +1183 -0
- package/utils/telemetry/betaSessionTracing.ts +491 -0
- package/utils/telemetry/bigqueryExporter.ts +252 -0
- package/utils/telemetry/events.ts +75 -0
- package/utils/telemetry/instrumentation.ts +825 -0
- package/utils/telemetry/logger.ts +26 -0
- package/utils/telemetry/perfettoTracing.ts +1120 -0
- package/utils/telemetry/pluginTelemetry.ts +289 -0
- package/utils/telemetry/sessionTracing.ts +927 -0
- package/utils/telemetry/skillLoadedEvent.ts +39 -0
- package/utils/telemetryAttributes.ts +71 -0
- package/utils/teleport/api.ts +466 -0
- package/utils/teleport/environmentSelection.ts +77 -0
- package/utils/teleport/environments.ts +120 -0
- package/utils/teleport/gitBundle.ts +292 -0
- package/utils/teleport.tsx +1226 -0
- package/utils/tempfile.ts +31 -0
- package/utils/terminal.ts +131 -0
- package/utils/terminalPanel.ts +191 -0
- package/utils/textHighlighting.ts +166 -0
- package/utils/theme.ts +639 -0
- package/utils/thinking.ts +162 -0
- package/utils/timeouts.ts +39 -0
- package/utils/tmuxSocket.ts +427 -0
- package/utils/todo/types.ts +18 -0
- package/utils/tokenBudget.ts +73 -0
- package/utils/tokens.ts +261 -0
- package/utils/toolErrors.ts +132 -0
- package/utils/toolPool.ts +79 -0
- package/utils/toolResultStorage.ts +1040 -0
- package/utils/toolSchemaCache.ts +26 -0
- package/utils/toolSearch.ts +756 -0
- package/utils/transcriptSearch.ts +202 -0
- package/utils/treeify.ts +170 -0
- package/utils/truncate.ts +179 -0
- package/utils/ultraplan/ccrSession.ts +349 -0
- package/utils/ultraplan/keyword.ts +127 -0
- package/utils/ultraplan/prompt.txt +1 -0
- package/utils/unaryLogging.ts +39 -0
- package/utils/undercover.ts +89 -0
- package/utils/user.ts +194 -0
- package/utils/userAgent.ts +10 -0
- package/utils/userPromptKeywords.ts +27 -0
- package/utils/uuid.ts +27 -0
- package/utils/warningHandler.ts +121 -0
- package/utils/which.ts +82 -0
- package/utils/windowsPaths.ts +173 -0
- package/utils/withResolvers.ts +13 -0
- package/utils/words.ts +800 -0
- package/utils/workloadContext.ts +57 -0
- package/utils/worktree.ts +1519 -0
- package/utils/worktreeModeEnabled.ts +11 -0
- package/utils/xdg.ts +65 -0
- package/utils/xmem.ts +6 -0
- package/utils/xml.ts +16 -0
- package/utils/yaml.ts +15 -0
- package/utils/zodToJsonSchema.ts +23 -0
|
@@ -0,0 +1,1120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Perfetto Tracing for Claude Code (Ant-only)
|
|
3
|
+
*
|
|
4
|
+
* This module generates traces in the Chrome Trace Event format that can be
|
|
5
|
+
* viewed in ui.perfetto.dev or Chrome's chrome://tracing.
|
|
6
|
+
*
|
|
7
|
+
* NOTE: This feature is ant-only and eliminated from external builds.
|
|
8
|
+
*
|
|
9
|
+
* The trace file includes:
|
|
10
|
+
* - Agent hierarchy (parent-child relationships in a swarm)
|
|
11
|
+
* - API requests with TTFT, TTLT, prompt length, cache stats, msg ID, speculative flag
|
|
12
|
+
* - Tool executions with name, duration, and token usage
|
|
13
|
+
* - User input waiting time
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* 1. Enable via CLAUDE_CODE_PERFETTO_TRACE=1 or CLAUDE_CODE_PERFETTO_TRACE=<path>
|
|
17
|
+
* 2. Optionally set CLAUDE_CODE_PERFETTO_WRITE_INTERVAL_S=<positive integer> to write the
|
|
18
|
+
* trace file periodically (default: write only on exit).
|
|
19
|
+
* 3. Run Claude Code normally
|
|
20
|
+
* 4. Trace file is written to ~/.claude/traces/trace-<session-id>.json
|
|
21
|
+
* or to the specified path
|
|
22
|
+
* 5. Open in ui.perfetto.dev to visualize
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { feature } from 'bun:bundle'
|
|
26
|
+
import { mkdirSync, writeFileSync } from 'fs'
|
|
27
|
+
import { mkdir, writeFile } from 'fs/promises'
|
|
28
|
+
import { dirname, join } from 'path'
|
|
29
|
+
import { getSessionId } from '../../bootstrap/state.js'
|
|
30
|
+
import { registerCleanup } from '../cleanupRegistry.js'
|
|
31
|
+
import { logForDebugging } from '../debug.js'
|
|
32
|
+
import {
|
|
33
|
+
getClaudeConfigHomeDir,
|
|
34
|
+
isEnvDefinedFalsy,
|
|
35
|
+
isEnvTruthy,
|
|
36
|
+
} from '../envUtils.js'
|
|
37
|
+
import { errorMessage } from '../errors.js'
|
|
38
|
+
import { djb2Hash } from '../hash.js'
|
|
39
|
+
import { jsonStringify } from '../slowOperations.js'
|
|
40
|
+
import { getAgentId, getAgentName, getParentSessionId } from '../teammate.js'
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Chrome Trace Event format types
|
|
44
|
+
* See: https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
export type TraceEventPhase =
|
|
48
|
+
| 'B' // Begin duration event
|
|
49
|
+
| 'E' // End duration event
|
|
50
|
+
| 'X' // Complete event (with duration)
|
|
51
|
+
| 'i' // Instant event
|
|
52
|
+
| 'C' // Counter event
|
|
53
|
+
| 'b' // Async begin
|
|
54
|
+
| 'n' // Async instant
|
|
55
|
+
| 'e' // Async end
|
|
56
|
+
| 'M' // Metadata event
|
|
57
|
+
|
|
58
|
+
export type TraceEvent = {
|
|
59
|
+
name: string
|
|
60
|
+
cat: string
|
|
61
|
+
ph: TraceEventPhase
|
|
62
|
+
ts: number // Timestamp in microseconds
|
|
63
|
+
pid: number // Process ID (we use 1 for main, agent IDs for subagents)
|
|
64
|
+
tid: number // Thread ID (we use numeric hash of agent name or 1 for main)
|
|
65
|
+
dur?: number // Duration in microseconds (for 'X' events)
|
|
66
|
+
args?: Record<string, unknown>
|
|
67
|
+
id?: string // For async events
|
|
68
|
+
scope?: string
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Agent info for tracking hierarchy
|
|
73
|
+
*/
|
|
74
|
+
type AgentInfo = {
|
|
75
|
+
agentId: string
|
|
76
|
+
agentName: string
|
|
77
|
+
parentAgentId?: string
|
|
78
|
+
processId: number
|
|
79
|
+
threadId: number
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Pending span for tracking begin/end pairs
|
|
84
|
+
*/
|
|
85
|
+
type PendingSpan = {
|
|
86
|
+
name: string
|
|
87
|
+
category: string
|
|
88
|
+
startTime: number
|
|
89
|
+
agentInfo: AgentInfo
|
|
90
|
+
args: Record<string, unknown>
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Global state for the Perfetto tracer
|
|
94
|
+
let isEnabled = false
|
|
95
|
+
let tracePath: string | null = null
|
|
96
|
+
// Metadata events (ph: 'M' — process/thread names, parent links) are kept
|
|
97
|
+
// separate so they survive eviction — Perfetto UI needs them to label
|
|
98
|
+
// tracks. Bounded by agent count (~3 events per agent).
|
|
99
|
+
const metadataEvents: TraceEvent[] = []
|
|
100
|
+
const events: TraceEvent[] = []
|
|
101
|
+
// events[] cap. Cron-driven sessions run for days; 22 push sites × many
|
|
102
|
+
// turns would otherwise grow unboundedly (periodicWrite flushes to disk but
|
|
103
|
+
// does not truncate — it writes the full snapshot). At ~300B/event this is
|
|
104
|
+
// ~30MB, enough trace history for any debugging session. Eviction drops the
|
|
105
|
+
// oldest half when hit, amortized O(1).
|
|
106
|
+
const MAX_EVENTS = 100_000
|
|
107
|
+
const pendingSpans = new Map<string, PendingSpan>()
|
|
108
|
+
const agentRegistry = new Map<string, AgentInfo>()
|
|
109
|
+
let totalAgentCount = 0
|
|
110
|
+
let startTimeMs = 0
|
|
111
|
+
let spanIdCounter = 0
|
|
112
|
+
let traceWritten = false // Flag to avoid double writes
|
|
113
|
+
|
|
114
|
+
// Map agent IDs to numeric process IDs (Perfetto requires numeric IDs)
|
|
115
|
+
let processIdCounter = 1
|
|
116
|
+
const agentIdToProcessId = new Map<string, number>()
|
|
117
|
+
|
|
118
|
+
// Periodic write interval handle
|
|
119
|
+
let writeIntervalId: ReturnType<typeof setInterval> | null = null
|
|
120
|
+
|
|
121
|
+
const STALE_SPAN_TTL_MS = 30 * 60 * 1000 // 30 minutes
|
|
122
|
+
const STALE_SPAN_CLEANUP_INTERVAL_MS = 60 * 1000 // 1 minute
|
|
123
|
+
let staleSpanCleanupId: ReturnType<typeof setInterval> | null = null
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Convert a string to a numeric hash for use as thread ID
|
|
127
|
+
*/
|
|
128
|
+
function stringToNumericHash(str: string): number {
|
|
129
|
+
return Math.abs(djb2Hash(str)) || 1 // Ensure non-zero
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get or create a numeric process ID for an agent
|
|
134
|
+
*/
|
|
135
|
+
function getProcessIdForAgent(agentId: string): number {
|
|
136
|
+
const existing = agentIdToProcessId.get(agentId)
|
|
137
|
+
if (existing !== undefined) return existing
|
|
138
|
+
|
|
139
|
+
processIdCounter++
|
|
140
|
+
agentIdToProcessId.set(agentId, processIdCounter)
|
|
141
|
+
return processIdCounter
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Get current agent info
|
|
146
|
+
*/
|
|
147
|
+
function getCurrentAgentInfo(): AgentInfo {
|
|
148
|
+
const agentId = getAgentId() ?? getSessionId()
|
|
149
|
+
const agentName = getAgentName() ?? 'main'
|
|
150
|
+
const parentSessionId = getParentSessionId()
|
|
151
|
+
|
|
152
|
+
// Check if we've already registered this agent
|
|
153
|
+
const existing = agentRegistry.get(agentId)
|
|
154
|
+
if (existing) return existing
|
|
155
|
+
|
|
156
|
+
const info: AgentInfo = {
|
|
157
|
+
agentId,
|
|
158
|
+
agentName,
|
|
159
|
+
parentAgentId: parentSessionId,
|
|
160
|
+
processId: agentId === getSessionId() ? 1 : getProcessIdForAgent(agentId),
|
|
161
|
+
threadId: stringToNumericHash(agentName),
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
agentRegistry.set(agentId, info)
|
|
165
|
+
totalAgentCount++
|
|
166
|
+
return info
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Get timestamp in microseconds relative to trace start
|
|
171
|
+
*/
|
|
172
|
+
function getTimestamp(): number {
|
|
173
|
+
return (Date.now() - startTimeMs) * 1000
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Generate a unique span ID
|
|
178
|
+
*/
|
|
179
|
+
function generateSpanId(): string {
|
|
180
|
+
return `span_${++spanIdCounter}`
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Evict pending spans older than STALE_SPAN_TTL_MS.
|
|
185
|
+
* Mirrors the TTL cleanup pattern in sessionTracing.ts.
|
|
186
|
+
*/
|
|
187
|
+
function evictStaleSpans(): void {
|
|
188
|
+
const now = getTimestamp()
|
|
189
|
+
const ttlUs = STALE_SPAN_TTL_MS * 1000 // Convert ms to microseconds
|
|
190
|
+
for (const [spanId, span] of pendingSpans) {
|
|
191
|
+
if (now - span.startTime > ttlUs) {
|
|
192
|
+
// Emit an end event so the span shows up in the trace as incomplete
|
|
193
|
+
events.push({
|
|
194
|
+
name: span.name,
|
|
195
|
+
cat: span.category,
|
|
196
|
+
ph: 'E',
|
|
197
|
+
ts: now,
|
|
198
|
+
pid: span.agentInfo.processId,
|
|
199
|
+
tid: span.agentInfo.threadId,
|
|
200
|
+
args: {
|
|
201
|
+
...span.args,
|
|
202
|
+
evicted: true,
|
|
203
|
+
duration_ms: (now - span.startTime) / 1000,
|
|
204
|
+
},
|
|
205
|
+
})
|
|
206
|
+
pendingSpans.delete(spanId)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Build the full trace document (Chrome Trace JSON format).
|
|
213
|
+
*/
|
|
214
|
+
function buildTraceDocument(): string {
|
|
215
|
+
return jsonStringify({
|
|
216
|
+
traceEvents: [...metadataEvents, ...events],
|
|
217
|
+
metadata: {
|
|
218
|
+
session_id: getSessionId(),
|
|
219
|
+
trace_start_time: new Date(startTimeMs).toISOString(),
|
|
220
|
+
agent_count: totalAgentCount,
|
|
221
|
+
total_event_count: metadataEvents.length + events.length,
|
|
222
|
+
},
|
|
223
|
+
})
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Drop the oldest half of events[] when over MAX_EVENTS. Called from the
|
|
228
|
+
* stale-span cleanup interval (60s). The half-batch splice keeps this
|
|
229
|
+
* amortized O(1) — we don't pay splice cost per-push. A synthetic marker
|
|
230
|
+
* is inserted so the gap is visible in ui.perfetto.dev.
|
|
231
|
+
*/
|
|
232
|
+
function evictOldestEvents(): void {
|
|
233
|
+
if (events.length < MAX_EVENTS) return
|
|
234
|
+
const dropped = events.splice(0, MAX_EVENTS / 2)
|
|
235
|
+
events.unshift({
|
|
236
|
+
name: 'trace_truncated',
|
|
237
|
+
cat: '__metadata',
|
|
238
|
+
ph: 'i',
|
|
239
|
+
ts: dropped[dropped.length - 1]?.ts ?? 0,
|
|
240
|
+
pid: 1,
|
|
241
|
+
tid: 0,
|
|
242
|
+
args: { dropped_events: dropped.length },
|
|
243
|
+
})
|
|
244
|
+
logForDebugging(
|
|
245
|
+
`[Perfetto] Evicted ${dropped.length} oldest events (cap ${MAX_EVENTS})`,
|
|
246
|
+
)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Initialize Perfetto tracing
|
|
251
|
+
* Call this early in the application lifecycle
|
|
252
|
+
*/
|
|
253
|
+
export function initializePerfettoTracing(): void {
|
|
254
|
+
const envValue = process.env.CLAUDE_CODE_PERFETTO_TRACE
|
|
255
|
+
logForDebugging(
|
|
256
|
+
`[Perfetto] initializePerfettoTracing called, env value: ${envValue}`,
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
// Wrap in feature() for dead code elimination - entire block removed from external builds
|
|
260
|
+
if (feature('PERFETTO_TRACING')) {
|
|
261
|
+
if (!envValue || isEnvDefinedFalsy(envValue)) {
|
|
262
|
+
logForDebugging(
|
|
263
|
+
'[Perfetto] Tracing disabled (env var not set or disabled)',
|
|
264
|
+
)
|
|
265
|
+
return
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
isEnabled = true
|
|
269
|
+
startTimeMs = Date.now()
|
|
270
|
+
|
|
271
|
+
// Determine trace file path
|
|
272
|
+
if (isEnvTruthy(envValue)) {
|
|
273
|
+
const tracesDir = join(getClaudeConfigHomeDir(), 'traces')
|
|
274
|
+
tracePath = join(tracesDir, `trace-${getSessionId()}.json`)
|
|
275
|
+
} else {
|
|
276
|
+
// Use the provided path
|
|
277
|
+
tracePath = envValue
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
logForDebugging(
|
|
281
|
+
`[Perfetto] Tracing enabled, will write to: ${tracePath}, isEnabled=${isEnabled}`,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
// Start periodic full-trace write if CLAUDE_CODE_PERFETTO_WRITE_INTERVAL_S is a positive integer
|
|
285
|
+
const intervalSec = parseInt(
|
|
286
|
+
process.env.CLAUDE_CODE_PERFETTO_WRITE_INTERVAL_S ?? '',
|
|
287
|
+
10,
|
|
288
|
+
)
|
|
289
|
+
if (intervalSec > 0) {
|
|
290
|
+
writeIntervalId = setInterval(() => {
|
|
291
|
+
void periodicWrite()
|
|
292
|
+
}, intervalSec * 1000)
|
|
293
|
+
// Don't let the interval keep the process alive on its own
|
|
294
|
+
if (writeIntervalId.unref) writeIntervalId.unref()
|
|
295
|
+
logForDebugging(
|
|
296
|
+
`[Perfetto] Periodic write enabled, interval: ${intervalSec}s`,
|
|
297
|
+
)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Start stale span cleanup interval
|
|
301
|
+
staleSpanCleanupId = setInterval(() => {
|
|
302
|
+
evictStaleSpans()
|
|
303
|
+
evictOldestEvents()
|
|
304
|
+
}, STALE_SPAN_CLEANUP_INTERVAL_MS)
|
|
305
|
+
if (staleSpanCleanupId.unref) staleSpanCleanupId.unref()
|
|
306
|
+
|
|
307
|
+
// Register cleanup to write final trace on exit
|
|
308
|
+
registerCleanup(async () => {
|
|
309
|
+
logForDebugging('[Perfetto] Cleanup callback invoked')
|
|
310
|
+
await writePerfettoTrace()
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
// Also register a beforeExit handler as a fallback
|
|
314
|
+
// This ensures the trace is written even if cleanup registry is not called
|
|
315
|
+
process.on('beforeExit', () => {
|
|
316
|
+
logForDebugging('[Perfetto] beforeExit handler invoked')
|
|
317
|
+
void writePerfettoTrace()
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
// Register a synchronous exit handler as a last resort
|
|
321
|
+
// This is the final fallback to ensure trace is written before process exits
|
|
322
|
+
process.on('exit', () => {
|
|
323
|
+
if (!traceWritten) {
|
|
324
|
+
logForDebugging(
|
|
325
|
+
'[Perfetto] exit handler invoked, writing trace synchronously',
|
|
326
|
+
)
|
|
327
|
+
writePerfettoTraceSync()
|
|
328
|
+
}
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
// Emit process metadata events for main process
|
|
332
|
+
const mainAgent = getCurrentAgentInfo()
|
|
333
|
+
emitProcessMetadata(mainAgent)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Emit metadata events for a process/agent
|
|
339
|
+
*/
|
|
340
|
+
function emitProcessMetadata(agentInfo: AgentInfo): void {
|
|
341
|
+
if (!isEnabled) return
|
|
342
|
+
|
|
343
|
+
// Process name
|
|
344
|
+
metadataEvents.push({
|
|
345
|
+
name: 'process_name',
|
|
346
|
+
cat: '__metadata',
|
|
347
|
+
ph: 'M',
|
|
348
|
+
ts: 0,
|
|
349
|
+
pid: agentInfo.processId,
|
|
350
|
+
tid: 0,
|
|
351
|
+
args: { name: agentInfo.agentName },
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
// Thread name (same as process for now)
|
|
355
|
+
metadataEvents.push({
|
|
356
|
+
name: 'thread_name',
|
|
357
|
+
cat: '__metadata',
|
|
358
|
+
ph: 'M',
|
|
359
|
+
ts: 0,
|
|
360
|
+
pid: agentInfo.processId,
|
|
361
|
+
tid: agentInfo.threadId,
|
|
362
|
+
args: { name: agentInfo.agentName },
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
// Add parent info if available
|
|
366
|
+
if (agentInfo.parentAgentId) {
|
|
367
|
+
metadataEvents.push({
|
|
368
|
+
name: 'parent_agent',
|
|
369
|
+
cat: '__metadata',
|
|
370
|
+
ph: 'M',
|
|
371
|
+
ts: 0,
|
|
372
|
+
pid: agentInfo.processId,
|
|
373
|
+
tid: 0,
|
|
374
|
+
args: {
|
|
375
|
+
parent_agent_id: agentInfo.parentAgentId,
|
|
376
|
+
},
|
|
377
|
+
})
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Check if Perfetto tracing is enabled
|
|
383
|
+
*/
|
|
384
|
+
export function isPerfettoTracingEnabled(): boolean {
|
|
385
|
+
return isEnabled
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Register a new agent in the trace
|
|
390
|
+
* Call this when a subagent/teammate is spawned
|
|
391
|
+
*/
|
|
392
|
+
export function registerAgent(
|
|
393
|
+
agentId: string,
|
|
394
|
+
agentName: string,
|
|
395
|
+
parentAgentId?: string,
|
|
396
|
+
): void {
|
|
397
|
+
if (!isEnabled) return
|
|
398
|
+
|
|
399
|
+
const info: AgentInfo = {
|
|
400
|
+
agentId,
|
|
401
|
+
agentName,
|
|
402
|
+
parentAgentId,
|
|
403
|
+
processId: getProcessIdForAgent(agentId),
|
|
404
|
+
threadId: stringToNumericHash(agentName),
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
agentRegistry.set(agentId, info)
|
|
408
|
+
totalAgentCount++
|
|
409
|
+
emitProcessMetadata(info)
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Unregister an agent from the trace.
|
|
414
|
+
* Call this when an agent completes, fails, or is aborted to free memory.
|
|
415
|
+
*/
|
|
416
|
+
export function unregisterAgent(agentId: string): void {
|
|
417
|
+
if (!isEnabled) return
|
|
418
|
+
agentRegistry.delete(agentId)
|
|
419
|
+
agentIdToProcessId.delete(agentId)
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Start an API call span
|
|
424
|
+
*/
|
|
425
|
+
export function startLLMRequestPerfettoSpan(args: {
|
|
426
|
+
model: string
|
|
427
|
+
promptTokens?: number
|
|
428
|
+
messageId?: string
|
|
429
|
+
isSpeculative?: boolean
|
|
430
|
+
querySource?: string
|
|
431
|
+
}): string {
|
|
432
|
+
if (!isEnabled) return ''
|
|
433
|
+
|
|
434
|
+
const spanId = generateSpanId()
|
|
435
|
+
const agentInfo = getCurrentAgentInfo()
|
|
436
|
+
|
|
437
|
+
pendingSpans.set(spanId, {
|
|
438
|
+
name: 'API Call',
|
|
439
|
+
category: 'api',
|
|
440
|
+
startTime: getTimestamp(),
|
|
441
|
+
agentInfo,
|
|
442
|
+
args: {
|
|
443
|
+
model: args.model,
|
|
444
|
+
prompt_tokens: args.promptTokens,
|
|
445
|
+
message_id: args.messageId,
|
|
446
|
+
is_speculative: args.isSpeculative ?? false,
|
|
447
|
+
query_source: args.querySource,
|
|
448
|
+
},
|
|
449
|
+
})
|
|
450
|
+
|
|
451
|
+
// Emit begin event
|
|
452
|
+
events.push({
|
|
453
|
+
name: 'API Call',
|
|
454
|
+
cat: 'api',
|
|
455
|
+
ph: 'B',
|
|
456
|
+
ts: pendingSpans.get(spanId)!.startTime,
|
|
457
|
+
pid: agentInfo.processId,
|
|
458
|
+
tid: agentInfo.threadId,
|
|
459
|
+
args: pendingSpans.get(spanId)!.args,
|
|
460
|
+
})
|
|
461
|
+
|
|
462
|
+
return spanId
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* End an API call span with response metadata
|
|
467
|
+
*/
|
|
468
|
+
export function endLLMRequestPerfettoSpan(
|
|
469
|
+
spanId: string,
|
|
470
|
+
metadata: {
|
|
471
|
+
ttftMs?: number
|
|
472
|
+
ttltMs?: number
|
|
473
|
+
promptTokens?: number
|
|
474
|
+
outputTokens?: number
|
|
475
|
+
cacheReadTokens?: number
|
|
476
|
+
cacheCreationTokens?: number
|
|
477
|
+
messageId?: string
|
|
478
|
+
success?: boolean
|
|
479
|
+
error?: string
|
|
480
|
+
/** Time spent in pre-request setup (client creation, retries) before the successful attempt */
|
|
481
|
+
requestSetupMs?: number
|
|
482
|
+
/** Timestamps (Date.now()) of each attempt start — used to emit retry sub-spans */
|
|
483
|
+
attemptStartTimes?: number[]
|
|
484
|
+
},
|
|
485
|
+
): void {
|
|
486
|
+
if (!isEnabled || !spanId) return
|
|
487
|
+
|
|
488
|
+
const pending = pendingSpans.get(spanId)
|
|
489
|
+
if (!pending) return
|
|
490
|
+
|
|
491
|
+
const endTime = getTimestamp()
|
|
492
|
+
const duration = endTime - pending.startTime
|
|
493
|
+
|
|
494
|
+
const promptTokens =
|
|
495
|
+
metadata.promptTokens ?? (pending.args.prompt_tokens as number | undefined)
|
|
496
|
+
const ttftMs = metadata.ttftMs
|
|
497
|
+
const ttltMs = metadata.ttltMs
|
|
498
|
+
const outputTokens = metadata.outputTokens
|
|
499
|
+
const cacheReadTokens = metadata.cacheReadTokens
|
|
500
|
+
|
|
501
|
+
// Compute derived metrics
|
|
502
|
+
// ITPS: input tokens per second (prompt processing speed)
|
|
503
|
+
const itps =
|
|
504
|
+
ttftMs !== undefined && promptTokens !== undefined && ttftMs > 0
|
|
505
|
+
? Math.round((promptTokens / (ttftMs / 1000)) * 100) / 100
|
|
506
|
+
: undefined
|
|
507
|
+
|
|
508
|
+
// OTPS: output tokens per second (sampling speed)
|
|
509
|
+
const samplingMs =
|
|
510
|
+
ttltMs !== undefined && ttftMs !== undefined ? ttltMs - ttftMs : undefined
|
|
511
|
+
const otps =
|
|
512
|
+
samplingMs !== undefined && outputTokens !== undefined && samplingMs > 0
|
|
513
|
+
? Math.round((outputTokens / (samplingMs / 1000)) * 100) / 100
|
|
514
|
+
: undefined
|
|
515
|
+
|
|
516
|
+
// Cache hit rate: percentage of prompt tokens from cache
|
|
517
|
+
const cacheHitRate =
|
|
518
|
+
cacheReadTokens !== undefined &&
|
|
519
|
+
promptTokens !== undefined &&
|
|
520
|
+
promptTokens > 0
|
|
521
|
+
? Math.round((cacheReadTokens / promptTokens) * 10000) / 100
|
|
522
|
+
: undefined
|
|
523
|
+
|
|
524
|
+
const requestSetupMs = metadata.requestSetupMs
|
|
525
|
+
const attemptStartTimes = metadata.attemptStartTimes
|
|
526
|
+
|
|
527
|
+
// Merge metadata with original args
|
|
528
|
+
const args = {
|
|
529
|
+
...pending.args,
|
|
530
|
+
ttft_ms: ttftMs,
|
|
531
|
+
ttlt_ms: ttltMs,
|
|
532
|
+
prompt_tokens: promptTokens,
|
|
533
|
+
output_tokens: outputTokens,
|
|
534
|
+
cache_read_tokens: cacheReadTokens,
|
|
535
|
+
cache_creation_tokens: metadata.cacheCreationTokens,
|
|
536
|
+
message_id: metadata.messageId ?? pending.args.message_id,
|
|
537
|
+
success: metadata.success ?? true,
|
|
538
|
+
error: metadata.error,
|
|
539
|
+
duration_ms: duration / 1000,
|
|
540
|
+
request_setup_ms: requestSetupMs,
|
|
541
|
+
// Derived metrics
|
|
542
|
+
itps,
|
|
543
|
+
otps,
|
|
544
|
+
cache_hit_rate_pct: cacheHitRate,
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Emit Request Setup sub-span when there was measurable setup time
|
|
548
|
+
// (client creation, param building, retries before the successful attempt)
|
|
549
|
+
const setupUs =
|
|
550
|
+
requestSetupMs !== undefined && requestSetupMs > 0
|
|
551
|
+
? requestSetupMs * 1000
|
|
552
|
+
: 0
|
|
553
|
+
if (setupUs > 0) {
|
|
554
|
+
const setupEndTs = pending.startTime + setupUs
|
|
555
|
+
|
|
556
|
+
events.push({
|
|
557
|
+
name: 'Request Setup',
|
|
558
|
+
cat: 'api,setup',
|
|
559
|
+
ph: 'B',
|
|
560
|
+
ts: pending.startTime,
|
|
561
|
+
pid: pending.agentInfo.processId,
|
|
562
|
+
tid: pending.agentInfo.threadId,
|
|
563
|
+
args: {
|
|
564
|
+
request_setup_ms: requestSetupMs,
|
|
565
|
+
attempt_count: attemptStartTimes?.length ?? 1,
|
|
566
|
+
},
|
|
567
|
+
})
|
|
568
|
+
|
|
569
|
+
// Emit retry attempt sub-spans within Request Setup.
|
|
570
|
+
// Each failed attempt runs from its start to the next attempt's start.
|
|
571
|
+
if (attemptStartTimes && attemptStartTimes.length > 1) {
|
|
572
|
+
// attemptStartTimes[0] is the reference point (first attempt).
|
|
573
|
+
// Convert wall-clock deltas into Perfetto-relative microseconds.
|
|
574
|
+
const baseWallMs = attemptStartTimes[0]!
|
|
575
|
+
for (let i = 0; i < attemptStartTimes.length - 1; i++) {
|
|
576
|
+
const attemptStartUs =
|
|
577
|
+
pending.startTime + (attemptStartTimes[i]! - baseWallMs) * 1000
|
|
578
|
+
const attemptEndUs =
|
|
579
|
+
pending.startTime + (attemptStartTimes[i + 1]! - baseWallMs) * 1000
|
|
580
|
+
|
|
581
|
+
events.push({
|
|
582
|
+
name: `Attempt ${i + 1} (retry)`,
|
|
583
|
+
cat: 'api,retry',
|
|
584
|
+
ph: 'B',
|
|
585
|
+
ts: attemptStartUs,
|
|
586
|
+
pid: pending.agentInfo.processId,
|
|
587
|
+
tid: pending.agentInfo.threadId,
|
|
588
|
+
args: { attempt: i + 1 },
|
|
589
|
+
})
|
|
590
|
+
events.push({
|
|
591
|
+
name: `Attempt ${i + 1} (retry)`,
|
|
592
|
+
cat: 'api,retry',
|
|
593
|
+
ph: 'E',
|
|
594
|
+
ts: attemptEndUs,
|
|
595
|
+
pid: pending.agentInfo.processId,
|
|
596
|
+
tid: pending.agentInfo.threadId,
|
|
597
|
+
})
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
events.push({
|
|
602
|
+
name: 'Request Setup',
|
|
603
|
+
cat: 'api,setup',
|
|
604
|
+
ph: 'E',
|
|
605
|
+
ts: setupEndTs,
|
|
606
|
+
pid: pending.agentInfo.processId,
|
|
607
|
+
tid: pending.agentInfo.threadId,
|
|
608
|
+
})
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Emit sub-spans for First Token and Sampling phases (before API Call end)
|
|
612
|
+
// Using B/E pairs in proper nesting order for correct Perfetto visualization
|
|
613
|
+
if (ttftMs !== undefined) {
|
|
614
|
+
// First Token starts after request setup (if any)
|
|
615
|
+
const firstTokenStartTs = pending.startTime + setupUs
|
|
616
|
+
const firstTokenEndTs = firstTokenStartTs + ttftMs * 1000
|
|
617
|
+
|
|
618
|
+
// First Token phase: from successful attempt start to first token
|
|
619
|
+
events.push({
|
|
620
|
+
name: 'First Token',
|
|
621
|
+
cat: 'api,ttft',
|
|
622
|
+
ph: 'B',
|
|
623
|
+
ts: firstTokenStartTs,
|
|
624
|
+
pid: pending.agentInfo.processId,
|
|
625
|
+
tid: pending.agentInfo.threadId,
|
|
626
|
+
args: {
|
|
627
|
+
ttft_ms: ttftMs,
|
|
628
|
+
prompt_tokens: promptTokens,
|
|
629
|
+
itps,
|
|
630
|
+
cache_hit_rate_pct: cacheHitRate,
|
|
631
|
+
},
|
|
632
|
+
})
|
|
633
|
+
events.push({
|
|
634
|
+
name: 'First Token',
|
|
635
|
+
cat: 'api,ttft',
|
|
636
|
+
ph: 'E',
|
|
637
|
+
ts: firstTokenEndTs,
|
|
638
|
+
pid: pending.agentInfo.processId,
|
|
639
|
+
tid: pending.agentInfo.threadId,
|
|
640
|
+
})
|
|
641
|
+
|
|
642
|
+
// Sampling phase: from first token to last token
|
|
643
|
+
// Note: samplingMs = ttltMs - ttftMs still includes setup time in ttltMs,
|
|
644
|
+
// so we compute the actual sampling duration for the span as the time from
|
|
645
|
+
// first token to API call end (endTime), not samplingMs directly.
|
|
646
|
+
const actualSamplingMs =
|
|
647
|
+
ttltMs !== undefined ? ttltMs - ttftMs - setupUs / 1000 : undefined
|
|
648
|
+
if (actualSamplingMs !== undefined && actualSamplingMs > 0) {
|
|
649
|
+
events.push({
|
|
650
|
+
name: 'Sampling',
|
|
651
|
+
cat: 'api,sampling',
|
|
652
|
+
ph: 'B',
|
|
653
|
+
ts: firstTokenEndTs,
|
|
654
|
+
pid: pending.agentInfo.processId,
|
|
655
|
+
tid: pending.agentInfo.threadId,
|
|
656
|
+
args: {
|
|
657
|
+
sampling_ms: actualSamplingMs,
|
|
658
|
+
output_tokens: outputTokens,
|
|
659
|
+
otps,
|
|
660
|
+
},
|
|
661
|
+
})
|
|
662
|
+
events.push({
|
|
663
|
+
name: 'Sampling',
|
|
664
|
+
cat: 'api,sampling',
|
|
665
|
+
ph: 'E',
|
|
666
|
+
ts: firstTokenEndTs + actualSamplingMs * 1000,
|
|
667
|
+
pid: pending.agentInfo.processId,
|
|
668
|
+
tid: pending.agentInfo.threadId,
|
|
669
|
+
})
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// Emit API Call end event (after sub-spans)
|
|
674
|
+
events.push({
|
|
675
|
+
name: pending.name,
|
|
676
|
+
cat: pending.category,
|
|
677
|
+
ph: 'E',
|
|
678
|
+
ts: endTime,
|
|
679
|
+
pid: pending.agentInfo.processId,
|
|
680
|
+
tid: pending.agentInfo.threadId,
|
|
681
|
+
args,
|
|
682
|
+
})
|
|
683
|
+
|
|
684
|
+
pendingSpans.delete(spanId)
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Start a tool execution span
|
|
689
|
+
*/
|
|
690
|
+
export function startToolPerfettoSpan(
|
|
691
|
+
toolName: string,
|
|
692
|
+
args?: Record<string, unknown>,
|
|
693
|
+
): string {
|
|
694
|
+
if (!isEnabled) return ''
|
|
695
|
+
|
|
696
|
+
const spanId = generateSpanId()
|
|
697
|
+
const agentInfo = getCurrentAgentInfo()
|
|
698
|
+
|
|
699
|
+
pendingSpans.set(spanId, {
|
|
700
|
+
name: `Tool: ${toolName}`,
|
|
701
|
+
category: 'tool',
|
|
702
|
+
startTime: getTimestamp(),
|
|
703
|
+
agentInfo,
|
|
704
|
+
args: {
|
|
705
|
+
tool_name: toolName,
|
|
706
|
+
...args,
|
|
707
|
+
},
|
|
708
|
+
})
|
|
709
|
+
|
|
710
|
+
// Emit begin event
|
|
711
|
+
events.push({
|
|
712
|
+
name: `Tool: ${toolName}`,
|
|
713
|
+
cat: 'tool',
|
|
714
|
+
ph: 'B',
|
|
715
|
+
ts: pendingSpans.get(spanId)!.startTime,
|
|
716
|
+
pid: agentInfo.processId,
|
|
717
|
+
tid: agentInfo.threadId,
|
|
718
|
+
args: pendingSpans.get(spanId)!.args,
|
|
719
|
+
})
|
|
720
|
+
|
|
721
|
+
return spanId
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* End a tool execution span
|
|
726
|
+
*/
|
|
727
|
+
export function endToolPerfettoSpan(
|
|
728
|
+
spanId: string,
|
|
729
|
+
metadata?: {
|
|
730
|
+
success?: boolean
|
|
731
|
+
error?: string
|
|
732
|
+
resultTokens?: number
|
|
733
|
+
},
|
|
734
|
+
): void {
|
|
735
|
+
if (!isEnabled || !spanId) return
|
|
736
|
+
|
|
737
|
+
const pending = pendingSpans.get(spanId)
|
|
738
|
+
if (!pending) return
|
|
739
|
+
|
|
740
|
+
const endTime = getTimestamp()
|
|
741
|
+
const duration = endTime - pending.startTime
|
|
742
|
+
|
|
743
|
+
const args = {
|
|
744
|
+
...pending.args,
|
|
745
|
+
success: metadata?.success ?? true,
|
|
746
|
+
error: metadata?.error,
|
|
747
|
+
result_tokens: metadata?.resultTokens,
|
|
748
|
+
duration_ms: duration / 1000,
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// Emit end event
|
|
752
|
+
events.push({
|
|
753
|
+
name: pending.name,
|
|
754
|
+
cat: pending.category,
|
|
755
|
+
ph: 'E',
|
|
756
|
+
ts: endTime,
|
|
757
|
+
pid: pending.agentInfo.processId,
|
|
758
|
+
tid: pending.agentInfo.threadId,
|
|
759
|
+
args,
|
|
760
|
+
})
|
|
761
|
+
|
|
762
|
+
pendingSpans.delete(spanId)
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* Start a user input waiting span
|
|
767
|
+
*/
|
|
768
|
+
export function startUserInputPerfettoSpan(context?: string): string {
|
|
769
|
+
if (!isEnabled) return ''
|
|
770
|
+
|
|
771
|
+
const spanId = generateSpanId()
|
|
772
|
+
const agentInfo = getCurrentAgentInfo()
|
|
773
|
+
|
|
774
|
+
pendingSpans.set(spanId, {
|
|
775
|
+
name: 'Waiting for User Input',
|
|
776
|
+
category: 'user_input',
|
|
777
|
+
startTime: getTimestamp(),
|
|
778
|
+
agentInfo,
|
|
779
|
+
args: {
|
|
780
|
+
context,
|
|
781
|
+
},
|
|
782
|
+
})
|
|
783
|
+
|
|
784
|
+
// Emit begin event
|
|
785
|
+
events.push({
|
|
786
|
+
name: 'Waiting for User Input',
|
|
787
|
+
cat: 'user_input',
|
|
788
|
+
ph: 'B',
|
|
789
|
+
ts: pendingSpans.get(spanId)!.startTime,
|
|
790
|
+
pid: agentInfo.processId,
|
|
791
|
+
tid: agentInfo.threadId,
|
|
792
|
+
args: pendingSpans.get(spanId)!.args,
|
|
793
|
+
})
|
|
794
|
+
|
|
795
|
+
return spanId
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* End a user input waiting span
|
|
800
|
+
*/
|
|
801
|
+
export function endUserInputPerfettoSpan(
|
|
802
|
+
spanId: string,
|
|
803
|
+
metadata?: {
|
|
804
|
+
decision?: string
|
|
805
|
+
source?: string
|
|
806
|
+
},
|
|
807
|
+
): void {
|
|
808
|
+
if (!isEnabled || !spanId) return
|
|
809
|
+
|
|
810
|
+
const pending = pendingSpans.get(spanId)
|
|
811
|
+
if (!pending) return
|
|
812
|
+
|
|
813
|
+
const endTime = getTimestamp()
|
|
814
|
+
const duration = endTime - pending.startTime
|
|
815
|
+
|
|
816
|
+
const args = {
|
|
817
|
+
...pending.args,
|
|
818
|
+
decision: metadata?.decision,
|
|
819
|
+
source: metadata?.source,
|
|
820
|
+
duration_ms: duration / 1000,
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// Emit end event
|
|
824
|
+
events.push({
|
|
825
|
+
name: pending.name,
|
|
826
|
+
cat: pending.category,
|
|
827
|
+
ph: 'E',
|
|
828
|
+
ts: endTime,
|
|
829
|
+
pid: pending.agentInfo.processId,
|
|
830
|
+
tid: pending.agentInfo.threadId,
|
|
831
|
+
args,
|
|
832
|
+
})
|
|
833
|
+
|
|
834
|
+
pendingSpans.delete(spanId)
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Emit an instant event (marker)
|
|
839
|
+
*/
|
|
840
|
+
export function emitPerfettoInstant(
|
|
841
|
+
name: string,
|
|
842
|
+
category: string,
|
|
843
|
+
args?: Record<string, unknown>,
|
|
844
|
+
): void {
|
|
845
|
+
if (!isEnabled) return
|
|
846
|
+
|
|
847
|
+
const agentInfo = getCurrentAgentInfo()
|
|
848
|
+
|
|
849
|
+
events.push({
|
|
850
|
+
name,
|
|
851
|
+
cat: category,
|
|
852
|
+
ph: 'i',
|
|
853
|
+
ts: getTimestamp(),
|
|
854
|
+
pid: agentInfo.processId,
|
|
855
|
+
tid: agentInfo.threadId,
|
|
856
|
+
args,
|
|
857
|
+
})
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* Emit a counter event for tracking metrics over time
|
|
862
|
+
*/
|
|
863
|
+
export function emitPerfettoCounter(
|
|
864
|
+
name: string,
|
|
865
|
+
values: Record<string, number>,
|
|
866
|
+
): void {
|
|
867
|
+
if (!isEnabled) return
|
|
868
|
+
|
|
869
|
+
const agentInfo = getCurrentAgentInfo()
|
|
870
|
+
|
|
871
|
+
events.push({
|
|
872
|
+
name,
|
|
873
|
+
cat: 'counter',
|
|
874
|
+
ph: 'C',
|
|
875
|
+
ts: getTimestamp(),
|
|
876
|
+
pid: agentInfo.processId,
|
|
877
|
+
tid: agentInfo.threadId,
|
|
878
|
+
args: values,
|
|
879
|
+
})
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* Start an interaction span (wraps a full user request cycle)
|
|
884
|
+
*/
|
|
885
|
+
export function startInteractionPerfettoSpan(userPrompt?: string): string {
|
|
886
|
+
if (!isEnabled) return ''
|
|
887
|
+
|
|
888
|
+
const spanId = generateSpanId()
|
|
889
|
+
const agentInfo = getCurrentAgentInfo()
|
|
890
|
+
|
|
891
|
+
pendingSpans.set(spanId, {
|
|
892
|
+
name: 'Interaction',
|
|
893
|
+
category: 'interaction',
|
|
894
|
+
startTime: getTimestamp(),
|
|
895
|
+
agentInfo,
|
|
896
|
+
args: {
|
|
897
|
+
user_prompt_length: userPrompt?.length,
|
|
898
|
+
},
|
|
899
|
+
})
|
|
900
|
+
|
|
901
|
+
// Emit begin event
|
|
902
|
+
events.push({
|
|
903
|
+
name: 'Interaction',
|
|
904
|
+
cat: 'interaction',
|
|
905
|
+
ph: 'B',
|
|
906
|
+
ts: pendingSpans.get(spanId)!.startTime,
|
|
907
|
+
pid: agentInfo.processId,
|
|
908
|
+
tid: agentInfo.threadId,
|
|
909
|
+
args: pendingSpans.get(spanId)!.args,
|
|
910
|
+
})
|
|
911
|
+
|
|
912
|
+
return spanId
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* End an interaction span
|
|
917
|
+
*/
|
|
918
|
+
export function endInteractionPerfettoSpan(spanId: string): void {
|
|
919
|
+
if (!isEnabled || !spanId) return
|
|
920
|
+
|
|
921
|
+
const pending = pendingSpans.get(spanId)
|
|
922
|
+
if (!pending) return
|
|
923
|
+
|
|
924
|
+
const endTime = getTimestamp()
|
|
925
|
+
const duration = endTime - pending.startTime
|
|
926
|
+
|
|
927
|
+
// Emit end event
|
|
928
|
+
events.push({
|
|
929
|
+
name: pending.name,
|
|
930
|
+
cat: pending.category,
|
|
931
|
+
ph: 'E',
|
|
932
|
+
ts: endTime,
|
|
933
|
+
pid: pending.agentInfo.processId,
|
|
934
|
+
tid: pending.agentInfo.threadId,
|
|
935
|
+
args: {
|
|
936
|
+
...pending.args,
|
|
937
|
+
duration_ms: duration / 1000,
|
|
938
|
+
},
|
|
939
|
+
})
|
|
940
|
+
|
|
941
|
+
pendingSpans.delete(spanId)
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// ---------------------------------------------------------------------------
|
|
945
|
+
// Periodic write helpers
|
|
946
|
+
// ---------------------------------------------------------------------------
|
|
947
|
+
|
|
948
|
+
/**
|
|
949
|
+
* Stop the periodic write timer.
|
|
950
|
+
*/
|
|
951
|
+
function stopWriteInterval(): void {
|
|
952
|
+
if (staleSpanCleanupId) {
|
|
953
|
+
clearInterval(staleSpanCleanupId)
|
|
954
|
+
staleSpanCleanupId = null
|
|
955
|
+
}
|
|
956
|
+
if (writeIntervalId) {
|
|
957
|
+
clearInterval(writeIntervalId)
|
|
958
|
+
writeIntervalId = null
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* Force-close any remaining open spans at session end.
|
|
964
|
+
*/
|
|
965
|
+
function closeOpenSpans(): void {
|
|
966
|
+
for (const [spanId, pending] of pendingSpans) {
|
|
967
|
+
const endTime = getTimestamp()
|
|
968
|
+
events.push({
|
|
969
|
+
name: pending.name,
|
|
970
|
+
cat: pending.category,
|
|
971
|
+
ph: 'E',
|
|
972
|
+
ts: endTime,
|
|
973
|
+
pid: pending.agentInfo.processId,
|
|
974
|
+
tid: pending.agentInfo.threadId,
|
|
975
|
+
args: {
|
|
976
|
+
...pending.args,
|
|
977
|
+
incomplete: true,
|
|
978
|
+
duration_ms: (endTime - pending.startTime) / 1000,
|
|
979
|
+
},
|
|
980
|
+
})
|
|
981
|
+
pendingSpans.delete(spanId)
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* Write the full trace to disk. Errors are logged but swallowed so that a
|
|
987
|
+
* transient I/O problem does not crash the session — the next periodic tick
|
|
988
|
+
* (or the final exit write) will retry with a complete snapshot.
|
|
989
|
+
*/
|
|
990
|
+
async function periodicWrite(): Promise<void> {
|
|
991
|
+
if (!isEnabled || !tracePath || traceWritten) return
|
|
992
|
+
|
|
993
|
+
try {
|
|
994
|
+
await mkdir(dirname(tracePath), { recursive: true })
|
|
995
|
+
await writeFile(tracePath, buildTraceDocument())
|
|
996
|
+
logForDebugging(
|
|
997
|
+
`[Perfetto] Periodic write: ${events.length} events to ${tracePath}`,
|
|
998
|
+
)
|
|
999
|
+
} catch (error) {
|
|
1000
|
+
logForDebugging(
|
|
1001
|
+
`[Perfetto] Periodic write failed: ${errorMessage(error)}`,
|
|
1002
|
+
{ level: 'error' },
|
|
1003
|
+
)
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
/**
|
|
1008
|
+
* Final async write: close open spans and write the complete trace.
|
|
1009
|
+
* Idempotent — sets `traceWritten` on success so subsequent calls are no-ops.
|
|
1010
|
+
*/
|
|
1011
|
+
async function writePerfettoTrace(): Promise<void> {
|
|
1012
|
+
if (!isEnabled || !tracePath || traceWritten) {
|
|
1013
|
+
logForDebugging(
|
|
1014
|
+
`[Perfetto] Skipping final write: isEnabled=${isEnabled}, tracePath=${tracePath}, traceWritten=${traceWritten}`,
|
|
1015
|
+
)
|
|
1016
|
+
return
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
stopWriteInterval()
|
|
1020
|
+
closeOpenSpans()
|
|
1021
|
+
|
|
1022
|
+
logForDebugging(
|
|
1023
|
+
`[Perfetto] writePerfettoTrace called: events=${events.length}`,
|
|
1024
|
+
)
|
|
1025
|
+
|
|
1026
|
+
try {
|
|
1027
|
+
await mkdir(dirname(tracePath), { recursive: true })
|
|
1028
|
+
await writeFile(tracePath, buildTraceDocument())
|
|
1029
|
+
traceWritten = true
|
|
1030
|
+
logForDebugging(`[Perfetto] Trace finalized at: ${tracePath}`)
|
|
1031
|
+
} catch (error) {
|
|
1032
|
+
logForDebugging(
|
|
1033
|
+
`[Perfetto] Failed to write final trace: ${errorMessage(error)}`,
|
|
1034
|
+
{ level: 'error' },
|
|
1035
|
+
)
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
/**
|
|
1040
|
+
* Final synchronous write (fallback for process 'exit' handler where async is forbidden).
|
|
1041
|
+
*/
|
|
1042
|
+
function writePerfettoTraceSync(): void {
|
|
1043
|
+
if (!isEnabled || !tracePath || traceWritten) {
|
|
1044
|
+
logForDebugging(
|
|
1045
|
+
`[Perfetto] Skipping final sync write: isEnabled=${isEnabled}, tracePath=${tracePath}, traceWritten=${traceWritten}`,
|
|
1046
|
+
)
|
|
1047
|
+
return
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
stopWriteInterval()
|
|
1051
|
+
closeOpenSpans()
|
|
1052
|
+
|
|
1053
|
+
logForDebugging(
|
|
1054
|
+
`[Perfetto] writePerfettoTraceSync called: events=${events.length}`,
|
|
1055
|
+
)
|
|
1056
|
+
|
|
1057
|
+
try {
|
|
1058
|
+
const dir = dirname(tracePath)
|
|
1059
|
+
// eslint-disable-next-line custom-rules/no-sync-fs -- Only called from process.on('exit') handler
|
|
1060
|
+
mkdirSync(dir, { recursive: true })
|
|
1061
|
+
// eslint-disable-next-line custom-rules/no-sync-fs, eslint-plugin-n/no-sync -- Required for process 'exit' handler which doesn't support async
|
|
1062
|
+
writeFileSync(tracePath, buildTraceDocument())
|
|
1063
|
+
traceWritten = true
|
|
1064
|
+
logForDebugging(`[Perfetto] Trace finalized synchronously at: ${tracePath}`)
|
|
1065
|
+
} catch (error) {
|
|
1066
|
+
logForDebugging(
|
|
1067
|
+
`[Perfetto] Failed to write final trace synchronously: ${errorMessage(error)}`,
|
|
1068
|
+
{ level: 'error' },
|
|
1069
|
+
)
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
/**
|
|
1074
|
+
* Get all recorded events (for testing)
|
|
1075
|
+
*/
|
|
1076
|
+
export function getPerfettoEvents(): TraceEvent[] {
|
|
1077
|
+
return [...metadataEvents, ...events]
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
/**
|
|
1081
|
+
* Reset the tracer state (for testing)
|
|
1082
|
+
*/
|
|
1083
|
+
export function resetPerfettoTracer(): void {
|
|
1084
|
+
if (staleSpanCleanupId) {
|
|
1085
|
+
clearInterval(staleSpanCleanupId)
|
|
1086
|
+
staleSpanCleanupId = null
|
|
1087
|
+
}
|
|
1088
|
+
stopWriteInterval()
|
|
1089
|
+
metadataEvents.length = 0
|
|
1090
|
+
events.length = 0
|
|
1091
|
+
pendingSpans.clear()
|
|
1092
|
+
agentRegistry.clear()
|
|
1093
|
+
agentIdToProcessId.clear()
|
|
1094
|
+
totalAgentCount = 0
|
|
1095
|
+
processIdCounter = 1
|
|
1096
|
+
spanIdCounter = 0
|
|
1097
|
+
isEnabled = false
|
|
1098
|
+
tracePath = null
|
|
1099
|
+
startTimeMs = 0
|
|
1100
|
+
traceWritten = false
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
/**
|
|
1104
|
+
* Trigger a periodic write immediately (for testing)
|
|
1105
|
+
*/
|
|
1106
|
+
export async function triggerPeriodicWriteForTesting(): Promise<void> {
|
|
1107
|
+
await periodicWrite()
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* Evict stale spans immediately (for testing)
|
|
1112
|
+
*/
|
|
1113
|
+
export function evictStaleSpansForTesting(): void {
|
|
1114
|
+
evictStaleSpans()
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
export const MAX_EVENTS_FOR_TESTING = MAX_EVENTS
|
|
1118
|
+
export function evictOldestEventsForTesting(): void {
|
|
1119
|
+
evictOldestEvents()
|
|
1120
|
+
}
|