@codingame/monaco-vscode-chat-service-override 36.2.7 → 37.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/index.d.ts +1 -0
- package/index.js +92 -10
- package/package.json +5 -5
- package/vscode/src/vs/platform/agentHost/browser/agentHostConnectionsService.d.ts +10 -3
- package/vscode/src/vs/platform/agentHost/browser/agentHostConnectionsService.js +54 -17
- package/vscode/src/vs/platform/agentHost/browser/agentHostEnablementService.d.ts +14 -0
- package/vscode/src/vs/platform/agentHost/browser/agentHostEnablementService.js +46 -0
- package/vscode/src/vs/platform/agentHost/browser/agentHostIpcChannelTransport.d.ts +7 -2
- package/vscode/src/vs/platform/agentHost/browser/agentHostIpcChannelTransport.js +34 -2
- package/vscode/src/vs/platform/agentHost/browser/{remoteAgentHostProtocolClient.d.ts → agentHostProtocolClient.d.ts} +240 -60
- package/vscode/src/vs/platform/agentHost/browser/agentHostProtocolClient.js +1911 -0
- package/vscode/src/vs/platform/agentHost/browser/remoteAgentHostServiceImpl.d.ts +30 -33
- package/vscode/src/vs/platform/agentHost/browser/remoteAgentHostServiceImpl.js +381 -315
- package/vscode/src/vs/platform/agentHost/browser/webSocketClientTransport.d.ts +3 -1
- package/vscode/src/vs/platform/agentHost/browser/webSocketClientTransport.js +2 -0
- package/vscode/src/vs/platform/agentHost/common/agentHostClientInfo.d.ts +9 -0
- package/vscode/src/vs/platform/agentHost/common/agentHostClientInfo.js +20 -0
- package/vscode/src/vs/platform/agentHost/common/agentHostExtensionProtocol.d.ts +144 -0
- package/vscode/src/vs/platform/agentHost/common/agentHostExtensionProtocol.js +20 -0
- package/vscode/src/vs/platform/agentHost/common/agentHostFileSystemProvider.d.ts +14 -6
- package/vscode/src/vs/platform/agentHost/common/agentHostFileSystemProvider.js +14 -10
- package/vscode/src/vs/platform/agentHost/common/agentHostFileSystemService.js +1 -1
- package/vscode/src/vs/platform/agentHost/common/agentHostManagedRules.d.ts +47 -0
- package/vscode/src/vs/platform/agentHost/common/agentHostManagedRules.js +75 -0
- package/vscode/src/vs/platform/agentHost/common/agentHostManagedSettings.d.ts +68 -0
- package/vscode/src/vs/platform/agentHost/common/agentHostManagedSettings.js +161 -0
- package/vscode/src/vs/platform/agentHost/common/agentHostStarter.config.contribution.js +288 -45
- package/vscode/src/vs/platform/agentHost/common/agentMerge.d.ts +261 -0
- package/vscode/src/vs/platform/agentHost/common/agentMerge.js +67 -0
- package/vscode/src/vs/platform/agentHost/common/agentSdkSetup.d.ts +53 -0
- package/vscode/src/vs/platform/agentHost/common/agentSdkSetup.js +45 -0
- package/vscode/src/vs/platform/agentHost/common/changesetUri.d.ts +130 -0
- package/vscode/src/vs/platform/agentHost/common/changesetUri.js +27 -0
- package/vscode/src/vs/platform/agentHost/common/customAgents.d.ts +8 -2
- package/vscode/src/vs/platform/agentHost/common/customAgents.js +7 -0
- package/vscode/src/vs/platform/agentHost/common/meta/agentChatSurfaceMeta.d.ts +39 -0
- package/vscode/src/vs/platform/agentHost/common/meta/agentChatSurfaceMeta.js +25 -0
- package/vscode/src/vs/platform/agentHost/common/meta/agentCompletionAttachmentMeta.d.ts +110 -0
- package/vscode/src/vs/platform/agentHost/common/meta/agentCompletionAttachmentMeta.js +38 -0
- package/vscode/src/vs/platform/agentHost/common/meta/agentHostArtifactRemovalMeta.d.ts +4 -0
- package/vscode/src/vs/platform/agentHost/common/meta/clientPluginCustomizationMeta.d.ts +7 -0
- package/vscode/src/vs/platform/agentHost/common/meta/clientPluginCustomizationMeta.js +14 -0
- package/vscode/src/vs/platform/agentHost/common/sandboxConfigSchema.d.ts +3 -3
- package/vscode/src/vs/platform/agentHost/common/sandboxConfigSchema.js +16 -24
- package/vscode/src/vs/platform/agentHost/common/semanticSearchConstants.d.ts +8 -0
- package/vscode/src/vs/platform/agentHost/common/semanticSearchConstants.js +8 -0
- package/vscode/src/vs/platform/agentHost/common/sessionArtifacts.d.ts +75 -0
- package/vscode/src/vs/platform/agentHost/common/sessionArtifacts.js +84 -0
- package/vscode/src/vs/platform/agentHost/common/shellInitScript.d.ts +24 -0
- package/vscode/src/vs/platform/agentHost/common/shellInitScript.js +63 -0
- package/vscode/src/vs/platform/agentHost/common/state/agentSubscription.d.ts +71 -20
- package/vscode/src/vs/platform/agentHost/common/state/agentSubscription.js +187 -26
- package/vscode/src/vs/platform/agentHost/common/state/legacyProtocolCompatibility.d.ts +30 -0
- package/vscode/src/vs/platform/agentHost/common/state/legacyProtocolCompatibility.js +87 -0
- package/vscode/src/vs/platform/agentHost/common/state/protocol/channels-annotations/reducer.js +2 -2
- package/vscode/src/vs/platform/agentHost/common/state/protocol/channels-automation/reducer.d.ts +4 -0
- package/vscode/src/vs/platform/agentHost/common/state/protocol/channels-automation/reducer.js +37 -0
- package/vscode/src/vs/platform/agentHost/common/state/protocol/channels-automation-run/reducer.d.ts +4 -0
- package/vscode/src/vs/platform/agentHost/common/state/protocol/channels-automation-run/reducer.js +45 -0
- package/vscode/src/vs/platform/agentHost/common/state/protocol/channels-changeset/reducer.d.ts +5 -4
- package/vscode/src/vs/platform/agentHost/common/state/protocol/channels-changeset/reducer.js +100 -35
- package/vscode/src/vs/platform/agentHost/common/state/protocol/channels-chat/reducer.js +193 -49
- package/vscode/src/vs/platform/agentHost/common/state/protocol/channels-session/reducer.js +161 -40
- package/vscode/src/vs/platform/agentHost/common/state/protocol/channels-terminal/reducer.d.ts +1 -1
- package/vscode/src/vs/platform/agentHost/common/state/protocol/channels-terminal/reducer.js +5 -1
- package/vscode/src/vs/platform/agentHost/common/state/protocol/common/reducer-helpers.d.ts +2 -2
- package/vscode/src/vs/platform/agentHost/common/state/protocol/common/timestamps.d.ts +1 -0
- package/vscode/src/vs/platform/agentHost/common/state/protocol/common/timestamps.js +7 -0
- package/vscode/src/vs/platform/agentHost/common/state/protocol/version/registry.d.ts +1 -1
- package/vscode/src/vs/platform/agentHost/common/state/protocol/version/registry.js +114 -3
- package/vscode/src/vs/platform/agentHost/common/state/sessionActions.d.ts +28 -5
- package/vscode/src/vs/platform/agentHost/common/state/sessionActions.js +4 -2
- package/vscode/src/vs/platform/agentHost/common/state/sessionWorkingDirectories.d.ts +34 -0
- package/vscode/src/vs/platform/agentHost/common/state/sessionWorkingDirectories.js +28 -0
- package/vscode/src/vs/platform/agentHost/common/worktreePaths.d.ts +24 -0
- package/vscode/src/vs/platform/agentHost/common/worktreePaths.js +15 -0
- package/vscode/src/vs/platform/browserView/common/browserChatToolReferenceNames.d.ts +1 -1
- package/vscode/src/vs/platform/chat/common/aiAgentEnv.d.ts +18 -0
- package/vscode/src/vs/platform/chat/common/aiAgentEnv.js +6 -0
- package/vscode/src/vs/platform/networkFilter/common/domainMatcher.d.ts +5 -1
- package/vscode/src/vs/platform/networkFilter/common/domainMatcher.js +77 -5
- package/vscode/src/vs/platform/networkFilter/common/networkFilterService.d.ts +1 -1
- package/vscode/src/vs/platform/networkFilter/common/networkFilterService.js +9 -5
- package/vscode/src/vs/platform/networkFilter/common/settings.d.ts +1 -5
- package/vscode/src/vs/platform/networkFilter/common/settings.js +0 -4
- package/vscode/src/vs/platform/sandbox/common/terminalSandboxEngine.d.ts +19 -7
- package/vscode/src/vs/platform/sandbox/common/terminalSandboxEngine.js +49 -37
- package/vscode/src/vs/platform/sandbox/common/terminalSandboxReadAllowList.d.ts +2 -1
- package/vscode/src/vs/platform/sandbox/common/terminalSandboxReadAllowList.js +12 -0
- package/vscode/src/vs/platform/sandbox/common/terminalSandboxRuntimeConfigurationPerOperation.js +1 -2
- package/vscode/src/vs/platform/sandbox/common/terminalSandboxService.d.ts +1 -0
- package/vscode/src/vs/platform/terminal/common/autoApprove/autoApproveParseSafety.d.ts +5 -0
- package/vscode/src/vs/platform/terminal/common/autoApprove/autoApproveParseSafety.js +7 -0
- package/vscode/src/vs/platform/terminal/common/autoApprove/cmdDelayedExpansion.d.ts +5 -0
- package/vscode/src/vs/platform/terminal/common/autoApprove/cmdDelayedExpansion.js +8 -0
- package/vscode/src/vs/{workbench/contrib/terminalContrib/chatAgentTools/browser/commandParsers → platform/terminal/common/autoApprove}/sedFileWriteParser.d.ts +1 -2
- package/vscode/src/vs/workbench/browser/chatChangesPill.d.ts +29 -0
- package/vscode/src/vs/workbench/browser/chatChangesPill.js +84 -0
- package/vscode/src/vs/workbench/common/chatPullRequest.d.ts +19 -0
- package/vscode/src/vs/workbench/common/chatPullRequest.js +53 -0
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/agentsVoice.contribution.js +342 -155
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/agentsVoiceSessionsPicker.js +2 -2
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/agentsVoiceWidget.d.ts +25 -2
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/agentsVoiceWidget.js +150 -67
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/agentsVoiceWidgetBinding.js +5 -3
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/agentsVoiceWindowService.d.ts +5 -1
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/agentsVoiceWindowService.js +39 -9
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/confirmationComponent.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/confirmationComponent.js +3 -3
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/feedbackDialog.js +6 -6
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/headerComponent.d.ts +4 -2
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/headerComponent.js +54 -17
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/onboardingComponent.js +11 -11
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/sessionListComponent.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/sessionListComponent.js +9 -9
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/statusRowsComponent.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/statusRowsComponent.js +5 -5
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/tokens.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/tokens.js +5 -1
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/transcriptComponent.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/voiceBarComponent.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/components/voiceBarComponent.js +2 -2
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/media/voiceModeOnboarding.css +252 -0
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/transcriptsView/voiceTranscripts.contribution.js +13 -13
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/transcriptsView/voiceTranscriptsView.js +7 -7
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/voiceModeOnboarding.d.ts +146 -0
- package/vscode/src/vs/workbench/contrib/agentsVoice/browser/voiceModeOnboarding.js +889 -0
- package/vscode/src/vs/workbench/contrib/agentsVoice/common/voiceTranscriptStore.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/accessibility/chatAccessibilityService.d.ts +2 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/accessibility/chatAccessibilityService.js +3 -54
- package/vscode/src/vs/workbench/contrib/chat/browser/accessibility/chatResponseAccessibleView.d.ts +32 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/accessibility/chatResponseAccessibleView.js +214 -161
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityActions.js +10 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.d.ts +2 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.js +256 -72
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatAgentRecommendationActions.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatClear.d.ts +2 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatClear.js +11 -12
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.js +19 -15
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContextActions.js +30 -14
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatCopyActions.js +19 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatDeveloperActions.js +9 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatFileTreeActions.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatFindActions.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatFindActions.js +237 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatImportExport.js +7 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatLanguageModelActions.js +13 -13
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatMoveActions.js +10 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatNewActions.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatNewActions.js +68 -61
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatOpenAgentDebugPanelAction.js +17 -21
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatPluginActions.js +17 -21
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatPromptNavigationActions.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatQueueActions.d.ts +5 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatQueueActions.js +68 -14
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.js +9 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/codeBlockOperations.js +21 -19
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/createPluginAction.d.ts +7 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/createPluginAction.js +222 -72
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/exportAgentHostDebugLogsAction.d.ts +64 -17
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/exportAgentHostDebugLogsAction.js +530 -305
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/openAgentHostStateFileAction.d.ts +25 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/openAgentHostStateFileAction.js +63 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentHostCompletionAction.d.ts +30 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentHostCompletionAction.js +37 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginCommands.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginCommands.js +95 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginEditor/agentPluginEditor.js +10 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginEditor/agentPluginEditorInput.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginEditor/agentPluginItems.d.ts +2 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginRepositoryService.d.ts +18 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginRepositoryService.js +86 -47
- package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginsView.js +61 -47
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostActiveClientService.d.ts +43 -24
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostActiveClientService.js +326 -76
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostCustomizationService.d.ts +112 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostCustomizationService.js +33 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostImportConversationStore.d.ts +20 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostImportConversationStore.js +26 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostLocalCustomizations.d.ts +28 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostLocalCustomizations.js +110 -126
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostMcpServerSupport.d.ts +131 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostMcpServerSupport.js +638 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostMcpServerSupportScope.d.ts +41 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostMcpServerSupportScope.js +202 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostModeSynchronizer.d.ts +24 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostModeSynchronizer.js +26 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostPermissionUiContribution.js +10 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostProtectedResourcesService.d.ts +20 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostProtectedResourcesService.js +55 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostResponseFileChanges.d.ts +62 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostResponseFileChanges.js +40 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionInputPills.d.ts +59 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionInputPills.js +624 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionWorkingDirectorySynchronizer.d.ts +90 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionWorkingDirectorySynchronizer.js +207 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostShellInitSynchronizer.d.ts +31 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostShellInitSynchronizer.js +140 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostToolSetEnablementService.d.ts +4 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostToolSetEnablementService.js +5 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostToolUtils.js +5 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostUntitledProvisionalSessionService.d.ts +74 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostUntitledProvisionalSessionService.js +511 -171
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/applyAgentHostSessionConfig.d.ts +32 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/applyAgentHostSessionConfig.js +48 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/syncedCustomizationBundler.d.ts +55 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/syncedCustomizationBundler.js +210 -20
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessions.contribution.js +43 -24
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsActions.d.ts +46 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsActions.js +216 -110
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsPicker.d.ts +9 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsPicker.js +26 -17
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionProjection.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionProjectionActions.js +4 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionProjectionService.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentSessionsExperiments.contribution.js +4 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentTitleBarStatusWidget.js +30 -26
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/media/agenttitlebarstatuswidget.css +5 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/media/unifiedQuickAccess.css +6 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/unifiedQuickAccess.js +17 -17
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/unifiedQuickAccessActions.js +4 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/externalSessionsFilterMenu.d.ts +3 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/externalSessionsFilterMenu.js +62 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/media/sessionSummaryHover.css +104 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/sessionSummaryHover.d.ts +115 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/sessionSummaryHover.js +168 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/sessionSummaryHoverService.d.ts +24 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/sessionSummaryHoverService.js +32 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessionsConfiguration.js +56 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationIcons.d.ts +0 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationIcons.js +16 -17
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationItemSource.d.ts +7 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationItemSource.js +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationItemsModel.d.ts +2 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationItemsModel.js +10 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidget.d.ts +48 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidget.js +913 -220
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagement.contribution.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagement.contribution.js +148 -84
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagementEditor.d.ts +161 -17
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagementEditor.js +2367 -247
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagementEditorInput.d.ts +5 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagementEditorInput.js +21 -13
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagementSectionRegistry.d.ts +26 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagementSectionRegistry.js +34 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationPresentation.d.ts +2 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationPresentation.js +23 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationWelcomePage.d.ts +15 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationWelcomePage.js +3 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationWelcomePagePromptLaunchers.d.ts +10 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationWelcomePagePromptLaunchers.js +143 -68
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationWorkspaceService.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationWorkspaceService.js +10 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationCardList.d.ts +40 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationCardList.js +302 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationCreatorService.d.ts +1 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationCreatorService.js +49 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationGroupHeaderRenderer.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationMigration.d.ts +38 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationMigration.js +240 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationMigrationAccessibility.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationMigrationAccessibility.js +53 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationMigrationCategories.d.ts +82 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationMigrationCategories.js +762 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationMigrationDashboard.d.ts +80 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationMigrationDashboard.js +279 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationMigrationServiceImpl.d.ts +44 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/customizationMigrationServiceImpl.js +437 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/embeddedAgentPluginDetail.d.ts +85 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/embeddedAgentPluginDetail.js +697 -15
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/embeddedExtensionToolsDetail.js +7 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/embeddedMcpServerDetail.d.ts +40 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/embeddedMcpServerDetail.js +164 -42
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/galleryItemRenderer.js +6 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/mcpListWidget.d.ts +260 -31
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/mcpListWidget.js +2097 -589
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/mcpServerCustomizationMigration.d.ts +32 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/mcpServerCustomizationMigration.js +860 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/media/aiCustomizationManagement.css +2229 -1338
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/media/aiCustomizationWelcomePromptLaunchers.css +79 -26
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/media/customizationMigrationDashboard.css +354 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/pluginListWidget.d.ts +85 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/pluginListWidget.js +1550 -357
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/promptsServiceCustomizationItemProvider.d.ts +2 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/promptsServiceCustomizationItemProvider.js +13 -27
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/toolsListWidget.d.ts +38 -26
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/toolsListWidget.js +637 -319
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentResolveService.js +28 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatPasteTargetService.d.ts +10 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatPasteTargetService.js +22 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatReferenceAttachmentWidget.contribution.d.ts +15 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatReferenceAttachmentWidget.contribution.js +38 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/transcriptContextAttachmentWidget.contribution.d.ts +8 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/transcriptContextAttachmentWidget.contribution.js +38 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chat.contribution.js +4 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/chat.shared.contribution.js +1675 -633
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/agentHostChatDebugProvider.d.ts +93 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/agentHostChatDebugProvider.js +823 -52
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/agentHostLogSources.d.ts +132 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/agentHostLogSources.js +446 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/agentHostUsageSidecar.d.ts +183 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/agentHostUsageSidecar.js +218 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatCustomizationDiscoveryRenderer.js +45 -42
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugCacheExplorerView.d.ts +11 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugCacheExplorerView.js +163 -136
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugCacheInsights.js +72 -72
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugDetailPanel.js +7 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugEditor.d.ts +22 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugEditor.js +105 -14
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugEditorInput.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugEnablement.d.ts +32 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugEnablement.js +49 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugEventDetailRenderer.js +20 -20
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugEventList.js +7 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugFilters.js +4 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugFlowChartView.js +7 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugFlowGraph.js +27 -22
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugHomeView.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugHomeView.js +22 -23
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugHookContentRenderer.js +17 -17
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugLogsView.js +25 -25
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugMessageContentRenderer.js +8 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugModelTurnContentRenderer.js +23 -23
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugOverviewView.d.ts +7 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugOverviewView.js +76 -43
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugToolCallContentRenderer.js +11 -11
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugTypes.d.ts +3 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugTypes.js +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugWireLogView.d.ts +145 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/chatDebugWireLogView.js +839 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatDebug/media/chatDebug.css +277 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingCodeEditorIntegration.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorActions.d.ts +6 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorActions.js +14 -14
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorOverlay.js +8 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingExplanationModelManager.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingExplanationWidget.js +16 -16
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedDocumentEntry.d.ts +4 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedDocumentEntry.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedFileEntry.js +8 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedNotebookEntry.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingServiceImpl.d.ts +6 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingServiceImpl.js +35 -19
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.js +16 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSessionStorage.js +4 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingTextModelChangeService.d.ts +4 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/media/chatEditingEditorOverlay.css +4 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/media/chatEditingExplanationWidget.css +7 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/notebook/chatEditingNotebookEditorIntegration.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/notebook/notebookCellChanges.d.ts +5 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/chatImageCarouselService.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/chatInputPills.d.ts +86 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatInputPills.js +282 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatManagement/chatManagement.contribution.js +14 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/chatManagement/chatManagementEditorInput.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatManagement/chatModelsViewModel.d.ts +5 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatManagement/chatModelsViewModel.js +37 -25
- package/vscode/src/vs/workbench/contrib/chat/browser/chatManagement/chatModelsWidget.d.ts +7 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/chatManagement/chatModelsWidget.js +135 -82
- package/vscode/src/vs/workbench/contrib/chat/browser/chatManagement/media/chatModelsWidget.css +22 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/chatOutlineCreator.d.ts +17 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatOutlineCreator.js +28 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatOutputItemRenderer.js +5 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/chatParticipant.contribution.js +32 -32
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPetAchievementPreview.d.ts +7 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPetAchievementPreview.js +114 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPetAchievements.contribution.d.ts +45 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPetAchievements.contribution.js +326 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPetAchievementsEditor.d.ts +33 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPetAchievementsEditor.js +99 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPetAchievementsEditorInput.d.ts +17 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPetAchievementsEditorInput.js +46 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPetAchievementsWidget.d.ts +27 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPetAchievementsWidget.js +301 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPromoNotification.d.ts +22 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPromoNotification.js +103 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatQuotaNotification.d.ts +9 -36
- package/vscode/src/vs/workbench/contrib/chat/browser/chatQuotaNotification.js +103 -196
- package/vscode/src/vs/workbench/contrib/chat/browser/chatRepoInfo.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupContributions.js +36 -30
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupController.d.ts +2 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupController.js +51 -12
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupGrowthSession.js +6 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupProviders.js +31 -27
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupRunner.d.ts +65 -20
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupRunner.js +291 -138
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/media/chatSetup.css +9 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/media/microsoft-dark.svg +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup/media/microsoft-light.svg +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSideChat.d.ts +9 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSideChat.js +24 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSlashCommands.d.ts +2 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSlashCommands.js +59 -35
- package/vscode/src/vs/workbench/contrib/chat/browser/chatStatus/chatStatusDashboard.d.ts +7 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatStatus/chatStatusDashboard.js +221 -145
- package/vscode/src/vs/workbench/contrib/chat/browser/chatStatus/chatStatusEntry.js +15 -29
- package/vscode/src/vs/workbench/contrib/chat/browser/chatStatus/media/chatStatus.css +21 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSubmitRequestHandlerService.d.ts +22 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSubmitRequestHandlerService.js +27 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatTipCatalog.d.ts +9 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/chatTipCatalog.js +23 -21
- package/vscode/src/vs/workbench/contrib/chat/browser/chatTipService.d.ts +6 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/chatTipService.js +62 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/chatWindowNotifier.d.ts +15 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/chatWindowNotifier.js +97 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/claudePluginRecommendations.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/contextContrib/chatContext.contribution.js +6 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/contextContrib/chatContextService.d.ts +11 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/contextContrib/chatContextService.js +24 -16
- package/vscode/src/vs/workbench/contrib/chat/browser/defaultModelContribution.js +5 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/enablementStatusWidget.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/expNotification/chatExpNotificationConfig.d.ts +44 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/expNotification/chatExpNotificationConfig.js +232 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/expNotification/chatExpNotificationContribution.d.ts +36 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/expNotification/chatExpNotificationContribution.js +127 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/exploreAgentDefaultModel.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/feedbackSurvey/chatModelFeedbackSurveyPromptContribution.d.ts +18 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/feedbackSurvey/chatModelFeedbackSurveyPromptContribution.js +55 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/hasByokModelsContribution.js +4 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/languageModelsConfigurationService.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/media/chatPetAchievements.css +236 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/planAgentDefaultModel.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/planReviewFeedback/planReviewFeedbackEditorOverlay.d.ts +9 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/planReviewFeedback/planReviewFeedbackEditorOverlay.js +260 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/planReviewFeedback/planReviewFeedbackService.d.ts +39 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/planReviewFeedback/planReviewFeedbackService.js +155 -56
- package/vscode/src/vs/workbench/contrib/chat/browser/pluginAutoUpdate.d.ts +10 -14
- package/vscode/src/vs/workbench/contrib/chat/browser/pluginAutoUpdate.js +29 -14
- package/vscode/src/vs/workbench/contrib/chat/browser/pluginGitCommandService.d.ts +2 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/pluginGitCommandService.js +76 -24
- package/vscode/src/vs/workbench/contrib/chat/browser/pluginInstallService.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/pluginInstallService.js +53 -32
- package/vscode/src/vs/workbench/contrib/chat/browser/pluginSources.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/pluginSources.js +17 -17
- package/vscode/src/vs/workbench/contrib/chat/browser/pluginUrlHandler.js +8 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/chatModeActions.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/chatModeActions.js +29 -71
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/hookActions.d.ts +3 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/hookActions.js +36 -40
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/hookUtils.d.ts +3 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/hookUtils.js +5 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/promptCodingAgentActionOverlay.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/promptToolSetsCodeLensProvider.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/promptToolsCodeLensProvider.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/promptUrlHandler.js +8 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/runPromptAction.js +9 -16
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/saveAsPromptFileActions.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/skillActions.js +5 -13
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/media/promptTimeline.css +820 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptBucketing.d.ts +38 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptBucketing.js +100 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimeline.contribution.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimeline.contribution.js +51 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineCard.d.ts +30 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineCard.js +113 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineGutterRail.d.ts +146 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineGutterRail.js +440 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineLayout.d.ts +16 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineLayout.js +5 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineModel.d.ts +194 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineModel.js +525 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineRail.d.ts +33 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineRulerRail.d.ts +128 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineRulerRail.js +460 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineStickyHeader.d.ts +38 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineStickyHeader.js +120 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineWidgetContrib.d.ts +53 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptTimeline/promptTimelineWidgetContrib.js +160 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/promptsDebugContribution.js +25 -22
- package/vscode/src/vs/workbench/contrib/chat/browser/sessionChatPillOptions.d.ts +13 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/sessionChatPillOptions.js +52 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/sessionPullRequestPill.d.ts +22 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/sessionPullRequestPill.js +58 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/speechToText/voiceCodeTranscriptionClient.d.ts +63 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/speechToText/voiceCodeTranscriptionClient.js +361 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/telemetry/chatEditorTopologyTelemetry.d.ts +35 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/telemetry/chatEditorTopologyTelemetry.js +90 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/clientToolSetsContribution.js +25 -18
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/languageModelToolsConfirmationService.d.ts +3 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/languageModelToolsConfirmationService.js +77 -41
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/languageModelToolsService.js +60 -43
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/renameTool.d.ts +4 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/renameTool.js +60 -16
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/toolHelpers.d.ts +10 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/toolHelpers.js +13 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/usagesTool.d.ts +3 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/usagesTool.js +44 -24
- package/vscode/src/vs/workbench/contrib/chat/browser/utilityModelContribution.js +4 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcomeHandler.js +5 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/voiceClient/voiceClientService.d.ts +52 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/voiceClient/voiceClientService.js +446 -79
- package/vscode/src/vs/workbench/contrib/chat/browser/voiceClient/voiceInputUtils.d.ts +11 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/voiceClient/voiceInputUtils.js +13 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/voiceInputMode/voiceInputMode.d.ts +66 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/voiceInputMode/voiceInputMode.js +297 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSubagentOpenChat.d.ts +137 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSubagentOpenChat.js +714 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatSubagentOpenChat.css +379 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatFind/chatFindAccessibilityHelp.d.ts +10 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatFind/chatFindAccessibilityHelp.js +78 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatPetWidgetService.d.ts +36 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatPetWidgetService.js +172 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatWidgetService.d.ts +5 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatWidgetService.js +8 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNoticeHub.d.ts +15 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNoticeHub.js +30 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatQueuePickerActionItem.d.ts +11 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatQueuePickerActionItem.js +41 -13
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/agentHostInputCompletions.d.ts +5 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/agentHostInputCompletions.js +133 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/agentHostInputCompletionsBase.d.ts +3 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/agentHostInputCompletionsBase.js +11 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatEditorInputContentProvider.js +4 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputCommandArgumentHint.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputCommandArgumentHint.js +96 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputCompletionUtils.d.ts +12 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputCompletionUtils.js +36 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputCompletions.js +67 -17
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputEditorContrib.js +23 -37
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputEditorHover.d.ts +18 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputEditorHover.js +72 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputPlaceholderDecoration.d.ts +11 -0
- package/vscode/src/vs/workbench/contrib/{agentsVoice/common/agentsVoiceColors.js → chat/browser/widget/input/editor/chatInputPlaceholderDecoration.js} +17 -15
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputReferenceDecorations.d.ts +3 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/editor/chatInputReferenceDecorations.js +16 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/chatQuick.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/editor/chatEditor.d.ts +6 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/editor/chatEditor.js +21 -13
- package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatViewPane.d.ts +48 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatViewPane.js +457 -142
- package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatViewTitleControl.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatViewTitleControl.js +22 -14
- package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/media/chatViewPane.css +6 -22
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automationBlueprint.d.ts +22 -0
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automationBlueprint.js +163 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatDebugServiceImpl.d.ts +27 -5
- package/vscode/src/vs/workbench/contrib/chat/common/chatDebugServiceImpl.js +79 -32
- package/vscode/src/vs/workbench/contrib/chat/common/chatNotification.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatNotification.js +12 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatService/chatServiceImpl.d.ts +44 -11
- package/vscode/src/vs/workbench/contrib/chat/common/chatService/chatServiceImpl.js +404 -51
- package/vscode/src/vs/workbench/contrib/chat/common/chatService/chatServiceTelemetry.d.ts +64 -4
- package/vscode/src/vs/workbench/contrib/chat/common/chatService/chatServiceTelemetry.js +33 -2
- package/vscode/src/vs/workbench/contrib/chat/common/chatSideChatService.d.ts +68 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatSideChatService.js +70 -0
- package/vscode/src/vs/workbench/contrib/chat/common/model/chatModelStore.d.ts +5 -2
- package/vscode/src/vs/workbench/contrib/chat/common/model/chatSessionOperationLog.js +18 -5
- package/vscode/src/vs/workbench/contrib/chat/common/model/chatSessionStore.js +43 -14
- package/vscode/src/vs/workbench/contrib/chat/common/participants/chatSlashCommands.d.ts +4 -0
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/agentPluginServiceImpl.d.ts +4 -9
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/agentPluginServiceImpl.js +164 -71
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/workspacePluginSettingsService.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/workspacePluginSettingsService.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/chatPromptFilesContribution.js +18 -18
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptCodeActions.js +12 -12
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptHeaderAutocompletion.js +5 -5
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptHovers.js +12 -12
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptLinkProvider.d.ts +3 -1
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptLinkProvider.js +19 -10
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptValidator.d.ts +3 -1
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptValidator.js +172 -159
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/service/customizationMigrationService.d.ts +115 -0
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/service/customizationMigrationService.js +69 -0
- package/vscode/src/vs/workbench/contrib/chat/common/sessionChatPills.d.ts +60 -0
- package/vscode/src/vs/workbench/contrib/chat/common/sessionChatPills.js +139 -0
- package/vscode/src/vs/workbench/contrib/chat/common/voiceChatService.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/common/voicePlaybackService.d.ts +5 -0
- package/vscode/src/vs/workbench/contrib/chat/common/voicePlaybackService.js +21 -1
- package/vscode/src/vs/workbench/contrib/chat/common/widget/chatResponseResourceFileSystemProvider.d.ts +25 -2
- package/vscode/src/vs/workbench/contrib/chat/common/widget/chatResponseResourceFileSystemProvider.js +55 -18
- package/vscode/src/vs/workbench/contrib/imageCarousel/browser/imageCarousel.contribution.js +10 -10
- package/vscode/src/vs/workbench/contrib/imageCarousel/browser/imageCarouselEditor.js +10 -10
- package/vscode/src/vs/workbench/contrib/imageCarousel/browser/imageCarouselEditorInput.js +1 -1
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.js +1 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.js +15 -15
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatDefaultModel.js +2 -2
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatEditReviewSession.d.ts +59 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatEditReviewSession.js +323 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionResolver.d.ts +30 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionResolver.js +79 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.d.ts +6 -2
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.js +118 -13
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpPromptArgumentPick.js +14 -14
- package/vscode/src/vs/workbench/contrib/notebook/browser/contrib/chat/notebookChatUtils.js +1 -1
- package/vscode/src/vs/workbench/contrib/notebook/browser/controller/chat/cellChatActions.js +10 -10
- package/vscode/src/vs/workbench/contrib/notebook/browser/controller/chat/notebook.chat.contribution.js +5 -5
- package/vscode/src/vs/workbench/contrib/notebook/browser/controller/chat/notebookChatContext.js +1 -1
- package/vscode/src/vs/workbench/contrib/remoteCodingAgents/browser/remoteCodingAgents.contribution.js +8 -8
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminal.chat.contribution.js +1 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChat.d.ts +81 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChat.js +85 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatAccessibilityHelp.js +17 -17
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatAccessibleView.js +1 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatActions.js +23 -23
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatEnabler.js +1 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatService.d.ts +17 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatService.js +81 -7
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatSessionResolver.d.ts +30 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatSessionResolver.js +86 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.d.ts +10 -2
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.js +97 -18
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/agentHostSandboxForwarder.d.ts +2 -22
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/agentHostSandboxForwarder.js +10 -8
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/largeOutputFileWriter.js +2 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalHelpers.d.ts +2 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalHelpers.js +42 -36
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalToolTelemetry.d.ts +8 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalToolTelemetry.js +10 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/terminal.chatAgentTools.contribution.js +4 -4
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/toolTerminalCreator.js +2 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/autoApprove/npmScriptAutoApprover.js +1 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineAutoApproveAnalyzer.js +25 -16
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineFileWriteAnalyzer.js +4 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/consoleCompactor/consoleCompactor.d.ts +70 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/consoleCompactor/consoleCompactor.js +4316 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/getTerminalLastCommandTool.js +3 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/getTerminalOutputTool.js +3 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/getTerminalSelectionTool.js +3 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/killTerminalTool.js +3 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/monitoring/outputMonitor.d.ts +4 -4
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/monitoring/outputMonitor.js +3 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalConfirmationTool.js +4 -4
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.d.ts +6 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.js +188 -148
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/sendToTerminalTool.js +10 -10
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/createAndRunTaskTool.js +14 -14
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/getTaskOutputTool.js +7 -7
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/runTaskTool.js +14 -14
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/task/taskHelpers.js +1 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/treeSitterCommandParser.d.ts +7 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/treeSitterCommandParser.js +82 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/sandboxSettingsReader.d.ts +5 -6
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/sandboxSettingsReader.js +5 -42
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalOutput.d.ts +2 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalOutput.js +8 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.js +27 -8
- package/vscode/src/vs/workbench/services/accounts/browser/defaultAccount.d.ts +205 -0
- package/vscode/src/vs/workbench/services/accounts/browser/defaultAccount.js +1580 -0
- package/vscode/src/vs/workbench/services/agentEditorComments/browser/agentEditorCommentsOverlayWidget.d.ts +30 -0
- package/vscode/src/vs/workbench/services/agentEditorComments/browser/agentEditorCommentsOverlayWidget.js +175 -0
- package/vscode/src/vs/workbench/services/agentEditorComments/browser/media/agentEditorCommentsOverlayWidget.css +65 -0
- package/vscode/src/vs/workbench/services/agentHost/browser/agentSdkSetupService.d.ts +47 -0
- package/vscode/src/vs/workbench/services/agentHost/browser/agentSdkSetupService.js +129 -0
- package/vscode/src/vs/workbench/services/agentHost/browser/editorRemoteAgentHostServiceClient.d.ts +26 -8
- package/vscode/src/vs/workbench/services/agentHost/browser/editorRemoteAgentHostServiceClient.js +89 -27
- package/vscode/src/vs/workbench/services/agentHost/browser/webAgentHostEnablementService.d.ts +8 -0
- package/vscode/src/vs/workbench/services/agentHost/browser/webAgentHostEnablementService.js +28 -0
- package/vscode/src/vs/workbench/services/agentHost/common/agentHostFileSystemService.js +5 -1
- package/vscode/src/vs/workbench/services/agentHost/common/agentHostResourceService.d.ts +18 -18
- package/vscode/src/vs/workbench/services/agentHost/common/agentHostResourceService.js +159 -60
- package/vscode/src/vs/workbench/services/agentHost/common/editorRemoteAgentHostTransport.d.ts +47 -0
- package/vscode/src/vs/workbench/services/agentHost/common/editorRemoteAgentHostTransport.js +362 -0
- package/vscode/src/vs/platform/agentHost/browser/agentHost.config.contribution.d.ts +0 -1
- package/vscode/src/vs/platform/agentHost/browser/agentHost.config.contribution.js +0 -40
- package/vscode/src/vs/platform/agentHost/browser/remoteAgentHostProtocolClient.js +0 -1110
- package/vscode/src/vs/platform/agentHost/common/agentHost.config.contribution.js +0 -76
- package/vscode/src/vs/platform/agentHost/common/agentHostResourceService.d.ts +0 -63
- package/vscode/src/vs/platform/agentHost/common/agentHostResourceService.js +0 -25
- package/vscode/src/vs/platform/agentHost/common/agentHostSchema.d.ts +0 -254
- package/vscode/src/vs/platform/agentHost/common/agentHostSchema.js +0 -451
- package/vscode/src/vs/platform/agentHost/common/agentService.d.ts +0 -1294
- package/vscode/src/vs/platform/agentHost/common/agentService.js +0 -92
- package/vscode/src/vs/platform/agentHost/common/state/protocol/common/errors.d.ts +0 -186
- package/vscode/src/vs/platform/agentHost/common/state/protocol/common/errors.js +0 -10
- package/vscode/src/vs/platform/agentHost/common/state/sessionTransport.d.ts +0 -42
- package/vscode/src/vs/platform/agentHost/common/state/sessionTransport.js +0 -7
- package/vscode/src/vs/workbench/contrib/agentsVoice/common/agentsVoice.d.ts +0 -15
- package/vscode/src/vs/workbench/contrib/agentsVoice/common/agentsVoice.js +0 -15
- package/vscode/src/vs/workbench/contrib/agentsVoice/common/agentsVoiceColors.d.ts +0 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatForkActions.d.ts +0 -19
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatForkActions.js +0 -243
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/openCopilotCliStateFileAction.d.ts +0 -24
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/openCopilotCliStateFileAction.js +0 -77
- package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginActions.d.ts +0 -92
- package/vscode/src/vs/workbench/contrib/chat/browser/agentPluginActions.js +0 -224
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostNewSessionFolderService.d.ts +0 -23
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostNewSessionFolderService.js +0 -52
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsQuickAccess.d.ts +0 -16
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsQuickAccess.js +0 -96
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/localAgentDisabledInputTipContribution.d.ts +0 -27
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/localAgentDisabledInputTipContribution.js +0 -152
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/automationsListWidget.d.ts +0 -87
- package/vscode/src/vs/workbench/contrib/chat/browser/aiCustomization/automationsListWidget.js +0 -772
- package/vscode/src/vs/workbench/contrib/chat/browser/chatResponseFileChangesService.d.ts +0 -30
- package/vscode/src/vs/workbench/contrib/chat/browser/chatResponseFileChangesService.js +0 -29
- package/vscode/src/vs/workbench/contrib/chat/browser/enablementActions.d.ts +0 -20
- package/vscode/src/vs/workbench/contrib/chat/browser/enablementActions.js +0 -40
- package/vscode/src/vs/workbench/contrib/chat/browser/planReviewFeedback/media/planReviewFeedback.css +0 -160
- package/vscode/src/vs/workbench/contrib/chat/browser/planReviewFeedback/planReviewFeedbackEditorActions.d.ts +0 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/planReviewFeedback/planReviewFeedbackEditorActions.js +0 -123
- package/vscode/src/vs/workbench/contrib/chat/browser/planReviewFeedback/planReviewFeedbackEditorContribution.d.ts +0 -37
- package/vscode/src/vs/workbench/contrib/chat/browser/planReviewFeedback/planReviewFeedbackEditorContribution.js +0 -572
- package/vscode/src/vs/workbench/contrib/chat/browser/voiceClient/micCaptureService.d.ts +0 -125
- package/vscode/src/vs/workbench/contrib/chat/browser/voiceClient/micCaptureService.js +0 -399
- package/vscode/src/vs/workbench/contrib/chat/browser/voiceClient/voiceSessionController.d.ts +0 -321
- package/vscode/src/vs/workbench/contrib/chat/browser/voiceClient/voiceSessionController.js +0 -2117
- package/vscode/src/vs/workbench/contrib/chat/browser/voiceClient/voiceToolDispatchService.d.ts +0 -57
- package/vscode/src/vs/workbench/contrib/chat/browser/voiceClient/voiceToolDispatchService.js +0 -367
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automation.d.ts +0 -78
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automationDialogService.d.ts +0 -13
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automationDialogService.service.d.ts +0 -11
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automationDialogService.service.js +0 -6
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automationRunner.service.d.ts +0 -16
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automationRunner.service.js +0 -6
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automationService.d.ts +0 -46
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automationService.service.d.ts +0 -36
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automationService.service.js +0 -6
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automationsEnabled.d.ts +0 -12
- package/vscode/src/vs/workbench/contrib/chat/common/automations/automationsEnabled.js +0 -6
- package/vscode/src/vs/workbench/contrib/chat/common/automations/schedule.d.ts +0 -9
- package/vscode/src/vs/workbench/contrib/chat/common/automations/schedule.js +0 -6
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/agentPluginEnablement.d.ts +0 -15
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/agentPluginEnablement.js +0 -177
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/fileBackedInstalledPluginsStore.d.ts +0 -67
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/fileBackedInstalledPluginsStore.js +0 -195
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/marketplaceReference.d.ts +0 -65
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/marketplaceReference.js +0 -264
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/pluginMarketplaceService.d.ts +0 -190
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/pluginMarketplaceService.js +0 -865
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/strictKnownMarketplaces.d.ts +0 -31
- package/vscode/src/vs/workbench/contrib/chat/common/plugins/strictKnownMarketplaces.js +0 -122
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/commandParsers/commandFileWriteParser.d.ts +0 -24
- /package/vscode/src/vs/{workbench/contrib/terminalContrib/chatAgentTools/browser/commandParsers → platform/terminal/common/autoApprove}/sedFileWriteParser.js +0 -0
- /package/vscode/src/vs/{platform/agentHost/common/agentHost.config.contribution.d.ts → workbench/contrib/chat/browser/agentSessionsConfiguration.d.ts} +0 -0
|
@@ -0,0 +1,4316 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
const DEFAULT_LARGE_OUTPUT_THRESHOLD = 30_000;
|
|
4
|
+
const DEFAULT_SHELL_GREP_LARGE_OUTPUT_THRESHOLD = 30_000;
|
|
5
|
+
const DEFAULT_MIN_SAVED_CHARS = 0;
|
|
6
|
+
function compact(command, output, options) {
|
|
7
|
+
const opts = {};
|
|
8
|
+
const largeOutputThreshold = opts.largeOutputThreshold ?? DEFAULT_LARGE_OUTPUT_THRESHOLD;
|
|
9
|
+
const shellGrepLargeOutputThreshold = opts.shellGrepLargeOutputThreshold ?? DEFAULT_SHELL_GREP_LARGE_OUTPUT_THRESHOLD;
|
|
10
|
+
const minimumSavedChars = opts.minSavedChars ?? DEFAULT_MIN_SAVED_CHARS;
|
|
11
|
+
const classification = classifyCommandResult(command);
|
|
12
|
+
const preview = previewShellOutputCompaction(
|
|
13
|
+
command,
|
|
14
|
+
output,
|
|
15
|
+
largeOutputThreshold,
|
|
16
|
+
shellGrepLargeOutputThreshold,
|
|
17
|
+
minimumSavedChars
|
|
18
|
+
);
|
|
19
|
+
return buildReport(command, classification, output, preview);
|
|
20
|
+
}
|
|
21
|
+
const textEncoder = ( new TextEncoder());
|
|
22
|
+
function byteLength(value) {
|
|
23
|
+
return textEncoder.encode(value).length;
|
|
24
|
+
}
|
|
25
|
+
function countLines(text) {
|
|
26
|
+
if (text.length === 0) {
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
let count = text.split("\n").length;
|
|
30
|
+
if (text.endsWith("\n")) {
|
|
31
|
+
count -= 1;
|
|
32
|
+
}
|
|
33
|
+
return count;
|
|
34
|
+
}
|
|
35
|
+
function countsOf(text) {
|
|
36
|
+
return {
|
|
37
|
+
chars: text.length,
|
|
38
|
+
bytes: byteLength(text),
|
|
39
|
+
lines: countLines(text)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function minusCounts(self, other) {
|
|
43
|
+
return {
|
|
44
|
+
chars: saturatingSub(self.chars, other.chars),
|
|
45
|
+
bytes: saturatingSub(self.bytes, other.bytes),
|
|
46
|
+
lines: saturatingSub(self.lines, other.lines)
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function reductionOf(saved, original) {
|
|
50
|
+
return {
|
|
51
|
+
charsPct: pct(saved.chars, original.chars),
|
|
52
|
+
bytesPct: pct(saved.bytes, original.bytes),
|
|
53
|
+
linesPct: pct(saved.lines, original.lines)
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function pct(part, whole) {
|
|
57
|
+
if (whole === 0) {
|
|
58
|
+
return 0;
|
|
59
|
+
}
|
|
60
|
+
return (part / whole) * 100;
|
|
61
|
+
}
|
|
62
|
+
function buildReport(command, classification, original, preview) {
|
|
63
|
+
const compactedText = preview ? preview.output : original;
|
|
64
|
+
const originalCounts = countsOf(original);
|
|
65
|
+
const compactedCounts = countsOf(compactedText);
|
|
66
|
+
const saved = minusCounts(originalCounts, compactedCounts);
|
|
67
|
+
const reduction = reductionOf(saved, originalCounts);
|
|
68
|
+
return {
|
|
69
|
+
command,
|
|
70
|
+
applied: preview !== undefined,
|
|
71
|
+
lossless: preview === undefined ? true : preview.lossless,
|
|
72
|
+
commandKinds: classification.commandKinds.slice(),
|
|
73
|
+
isSourceReadCommand: classification.isSourceReadCommand,
|
|
74
|
+
runsGoTest: classification.runsGoTest,
|
|
75
|
+
mentionsSavedToolOutput: classification.mentionsSavedToolOutput,
|
|
76
|
+
original: originalCounts,
|
|
77
|
+
compacted: compactedCounts,
|
|
78
|
+
saved,
|
|
79
|
+
reduction,
|
|
80
|
+
compactedOutput: compactedText
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const COMPACTED_REFERENCE_OVERHEAD_BUDGET = 512;
|
|
84
|
+
const COMMON_PREFIX_DISPLAY_WIDTH = 120;
|
|
85
|
+
const EXTENSION_SUMMARY_INLINE_WIDTH = 160;
|
|
86
|
+
const GO_RUNTIME_PANIC_MIN_GOROUTINES = 8;
|
|
87
|
+
const CARGO_PROGRESS_PREFIXES = [
|
|
88
|
+
"Updating ",
|
|
89
|
+
"Downloading ",
|
|
90
|
+
"Downloaded ",
|
|
91
|
+
"Compiling ",
|
|
92
|
+
"Checking ",
|
|
93
|
+
"Fresh ",
|
|
94
|
+
"Locking ",
|
|
95
|
+
"Adding ",
|
|
96
|
+
"Building "
|
|
97
|
+
];
|
|
98
|
+
const COMMAND_COMPACTOR_ORDER = [
|
|
99
|
+
"apt",
|
|
100
|
+
"npm",
|
|
101
|
+
"npm-pack",
|
|
102
|
+
"yarn-berry",
|
|
103
|
+
"pnpm",
|
|
104
|
+
"composer",
|
|
105
|
+
"poetry",
|
|
106
|
+
"pip",
|
|
107
|
+
"uv",
|
|
108
|
+
"maven",
|
|
109
|
+
"dotnet",
|
|
110
|
+
"python-build",
|
|
111
|
+
"go",
|
|
112
|
+
"unittest",
|
|
113
|
+
"js-test",
|
|
114
|
+
"cargo",
|
|
115
|
+
"node",
|
|
116
|
+
"pytest",
|
|
117
|
+
"git",
|
|
118
|
+
"git-clean",
|
|
119
|
+
"nx",
|
|
120
|
+
"python-build-ext",
|
|
121
|
+
"django-test",
|
|
122
|
+
"golangci-lint",
|
|
123
|
+
"clang-format-linter",
|
|
124
|
+
"gradle",
|
|
125
|
+
"cmake",
|
|
126
|
+
"make",
|
|
127
|
+
"shell-grep",
|
|
128
|
+
"python-script"
|
|
129
|
+
];
|
|
130
|
+
const BENIGN_SEGMENT = {
|
|
131
|
+
benign: true
|
|
132
|
+
};
|
|
133
|
+
function compactSegment(kind) {
|
|
134
|
+
return {
|
|
135
|
+
benign: false,
|
|
136
|
+
kind
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function segmentsEqual(a, b) {
|
|
140
|
+
if (a.benign || b.benign) {
|
|
141
|
+
return a.benign === b.benign;
|
|
142
|
+
}
|
|
143
|
+
return a.kind === b.kind;
|
|
144
|
+
}
|
|
145
|
+
function jsStringLen(value) {
|
|
146
|
+
return value.length;
|
|
147
|
+
}
|
|
148
|
+
function sliceJsUnits(text, start, len) {
|
|
149
|
+
if (len === 0) {
|
|
150
|
+
return "";
|
|
151
|
+
}
|
|
152
|
+
return text.slice(start, start + len);
|
|
153
|
+
}
|
|
154
|
+
function splitWhitespace(value) {
|
|
155
|
+
const trimmed = value.trim();
|
|
156
|
+
return trimmed.length === 0 ? [] : trimmed.split(/\s+/);
|
|
157
|
+
}
|
|
158
|
+
function saturatingSub(a, b) {
|
|
159
|
+
return a > b ? a - b : 0;
|
|
160
|
+
}
|
|
161
|
+
function arraySliceEqual(arr, aStart, bStart, len) {
|
|
162
|
+
for (let k = 0; k < len; k++) {
|
|
163
|
+
if (arr[aStart + k] !== arr[bStart + k]) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
function isAsciiDigit(ch) {
|
|
170
|
+
return ch >= "0" && ch <= "9";
|
|
171
|
+
}
|
|
172
|
+
function isAsciiAlphabetic(ch) {
|
|
173
|
+
return (ch >= "A" && ch <= "Z") || (ch >= "a" && ch <= "z");
|
|
174
|
+
}
|
|
175
|
+
function trimStartMatchesChars(value, chars) {
|
|
176
|
+
let i = 0;
|
|
177
|
+
while (i < value.length && chars.includes(value[i])) {
|
|
178
|
+
i += 1;
|
|
179
|
+
}
|
|
180
|
+
return value.slice(i);
|
|
181
|
+
}
|
|
182
|
+
function regexReplaceAll(pattern, input, replacement) {
|
|
183
|
+
return input.replace(( new RegExp(pattern, "g")), replacement);
|
|
184
|
+
}
|
|
185
|
+
function regexTest(pattern, input) {
|
|
186
|
+
return regexTestWithFlags(pattern, input, "");
|
|
187
|
+
}
|
|
188
|
+
function regexTestWithFlags(pattern, input, flags) {
|
|
189
|
+
return ( new RegExp(pattern, flags)).test(input);
|
|
190
|
+
}
|
|
191
|
+
function regexFind(pattern, input) {
|
|
192
|
+
const match = ( new RegExp(pattern)).exec(input);
|
|
193
|
+
return match ? match.index : undefined;
|
|
194
|
+
}
|
|
195
|
+
function regexCaptureFirst(pattern, input) {
|
|
196
|
+
const match = ( new RegExp(pattern)).exec(input);
|
|
197
|
+
if (match && match[1] !== undefined) {
|
|
198
|
+
return match[1];
|
|
199
|
+
}
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
function regexFindAll(pattern, input) {
|
|
203
|
+
const regex = ( new RegExp(pattern, "g"));
|
|
204
|
+
const matches = [];
|
|
205
|
+
let match;
|
|
206
|
+
while ((match = regex.exec(input)) !== null) {
|
|
207
|
+
matches.push({
|
|
208
|
+
start: match.index,
|
|
209
|
+
end: match.index + match[0].length
|
|
210
|
+
});
|
|
211
|
+
if (match[0].length === 0) {
|
|
212
|
+
regex.lastIndex += 1;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return matches;
|
|
216
|
+
}
|
|
217
|
+
function unchanged(output) {
|
|
218
|
+
return {
|
|
219
|
+
output,
|
|
220
|
+
lossless: true
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
function lossy(output) {
|
|
224
|
+
return {
|
|
225
|
+
output,
|
|
226
|
+
lossless: false
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function indexAll(items) {
|
|
230
|
+
return ( items.map((item, index) => ({
|
|
231
|
+
index,
|
|
232
|
+
item
|
|
233
|
+
})));
|
|
234
|
+
}
|
|
235
|
+
function shouldSkipToolOutputCompaction(lines, output, minLines) {
|
|
236
|
+
return lines.length < minLines || lines.length > 200_000 || jsStringLen(output) < 1500 || ( lines.some(
|
|
237
|
+
line => line.startsWith("Error:") || line.startsWith("rg: ") || line.startsWith("grep: ")
|
|
238
|
+
));
|
|
239
|
+
}
|
|
240
|
+
function fitsLargeOutputThreshold(output, largeOutputThreshold) {
|
|
241
|
+
return byteLength(output) <= largeOutputThreshold;
|
|
242
|
+
}
|
|
243
|
+
function compactedBodyBudget(largeOutputThreshold) {
|
|
244
|
+
return Math.max(
|
|
245
|
+
256,
|
|
246
|
+
saturatingSub(largeOutputThreshold, COMPACTED_REFERENCE_OVERHEAD_BUDGET)
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
function totalGroupItems(groups) {
|
|
250
|
+
let total = 0;
|
|
251
|
+
for (const [, items] of groups) {
|
|
252
|
+
total += items.length;
|
|
253
|
+
}
|
|
254
|
+
return total;
|
|
255
|
+
}
|
|
256
|
+
function truncateInlineText(text, maxLength) {
|
|
257
|
+
const normalized = normalizeInlineWhitespace(text);
|
|
258
|
+
const normalizedLen = jsStringLen(normalized);
|
|
259
|
+
if (normalizedLen <= maxLength) {
|
|
260
|
+
return normalized;
|
|
261
|
+
}
|
|
262
|
+
const suffix = `... [+${normalizedLen - maxLength} chars]`;
|
|
263
|
+
return `${sliceJsUnits(normalized, 0, saturatingSub(maxLength, suffix.length))}${suffix}`;
|
|
264
|
+
}
|
|
265
|
+
function excerptInlineText(text, maxLength) {
|
|
266
|
+
const normalized = normalizeInlineWhitespace(text);
|
|
267
|
+
const normalizedLen = jsStringLen(normalized);
|
|
268
|
+
if (normalizedLen <= maxLength) {
|
|
269
|
+
return normalized;
|
|
270
|
+
}
|
|
271
|
+
const markerIndex = highSignalTextIndex(normalized);
|
|
272
|
+
if (markerIndex !== undefined) {
|
|
273
|
+
return excerptAroundIndex(normalized, maxLength, markerIndex);
|
|
274
|
+
}
|
|
275
|
+
const separator = ` ... [+${normalizedLen - maxLength} chars] ... `;
|
|
276
|
+
const available = saturatingSub(maxLength, separator.length);
|
|
277
|
+
const headLength = Math.ceil(available / 2);
|
|
278
|
+
const tailLength = Math.floor(available / 2);
|
|
279
|
+
return `${sliceJsUnits(normalized, 0, headLength)}${separator}${sliceJsUnits(normalized, saturatingSub(normalizedLen, tailLength), tailLength)}`;
|
|
280
|
+
}
|
|
281
|
+
function normalizeInlineWhitespace(text) {
|
|
282
|
+
return splitWhitespace(text).join(" ");
|
|
283
|
+
}
|
|
284
|
+
function highSignalTextIndex(text) {
|
|
285
|
+
return regexFind(
|
|
286
|
+
String.raw`\b(?:HF_TOKEN|AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|SECRET|TOKEN|FINAL_EXIT|RESULT|BEST|Accuracy|Model size|AssertionError|FAIL|ERROR|Rank)\b|hf_[A-Za-z0-9_]+|u=a1[A-Za-z0-9_-]+|https?://`,
|
|
287
|
+
text
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
function excerptAroundIndex(text, maxLength, index) {
|
|
291
|
+
const prefix = index > 0 ? "... " : "";
|
|
292
|
+
const textLen = jsStringLen(text);
|
|
293
|
+
const indexUnits = index;
|
|
294
|
+
const suffix = indexUnits + maxLength < textLen ? " ..." : "";
|
|
295
|
+
const available = saturatingSub(maxLength, prefix.length + suffix.length);
|
|
296
|
+
const start = Math.min(
|
|
297
|
+
saturatingSub(indexUnits, Math.floor(available / 2)),
|
|
298
|
+
saturatingSub(textLen, available)
|
|
299
|
+
);
|
|
300
|
+
return `${prefix}${sliceJsUnits(text, start, available)}${suffix}`;
|
|
301
|
+
}
|
|
302
|
+
function truncatePathMiddle(inputPath, maxLength) {
|
|
303
|
+
if (jsStringLen(inputPath) <= maxLength) {
|
|
304
|
+
return inputPath;
|
|
305
|
+
}
|
|
306
|
+
const ellipsis = "...";
|
|
307
|
+
const minTruncateWithEllipsisLength = ellipsis.length + 2;
|
|
308
|
+
const minMiddleTruncateLength = minTruncateWithEllipsisLength * 2;
|
|
309
|
+
if (maxLength <= minTruncateWithEllipsisLength) {
|
|
310
|
+
return sliceJsUnits(inputPath, 0, maxLength);
|
|
311
|
+
}
|
|
312
|
+
if (maxLength < minMiddleTruncateLength) {
|
|
313
|
+
return `${sliceJsUnits(inputPath, 0, maxLength - ellipsis.length)}${ellipsis}`;
|
|
314
|
+
}
|
|
315
|
+
const separator = inputPath.includes("\\") && !inputPath.includes("/") ? "\\" : "/";
|
|
316
|
+
const [root, segments] = getPathPartsForMiddleTruncation(inputPath, separator);
|
|
317
|
+
const minSegmentsForMiddleTruncation = root.length === 0 ? 3 : 2;
|
|
318
|
+
if (segments.length < minSegmentsForMiddleTruncation) {
|
|
319
|
+
return `${sliceJsUnits(inputPath, 0, maxLength - ellipsis.length)}${ellipsis}`;
|
|
320
|
+
}
|
|
321
|
+
const lastSegment = segments.length > 0 ? segments[segments.length - 1] : "";
|
|
322
|
+
const preservedSegmentCount = root.length === 0 ? 1 : 0;
|
|
323
|
+
const minResult = root.length === 0 ? `${segments[0]}${separator}${ellipsis}${separator}${lastSegment}` : `${root}${ellipsis}${separator}${lastSegment}`;
|
|
324
|
+
if (jsStringLen(minResult) > maxLength) {
|
|
325
|
+
return `${sliceJsUnits(inputPath, 0, maxLength - ellipsis.length)}${ellipsis}`;
|
|
326
|
+
}
|
|
327
|
+
let result = minResult;
|
|
328
|
+
const middleSegments = segments.slice(preservedSegmentCount, segments.length - 1);
|
|
329
|
+
for (let i = 0; i < middleSegments.length; i++) {
|
|
330
|
+
const preservedSegments = segments.slice(0, preservedSegmentCount + i + 1);
|
|
331
|
+
const prefix = root.length === 0 ? preservedSegments.join(separator) : `${root}${preservedSegments.join(separator)}`;
|
|
332
|
+
const candidate = `${prefix}${separator}${ellipsis}${separator}${lastSegment}`;
|
|
333
|
+
if (jsStringLen(candidate) <= maxLength) {
|
|
334
|
+
result = candidate;
|
|
335
|
+
} else {
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return result;
|
|
340
|
+
}
|
|
341
|
+
function getPathPartsForMiddleTruncation(inputPath, separator) {
|
|
342
|
+
if (inputPath.length >= 2 && isAsciiAlphabetic(inputPath[0]) && inputPath[1] === ":") {
|
|
343
|
+
let end = 2;
|
|
344
|
+
while (end < inputPath.length && (inputPath[end] === "/" || inputPath[end] === "\\")) {
|
|
345
|
+
end += 1;
|
|
346
|
+
}
|
|
347
|
+
const root = end > 2 ? `${inputPath.slice(0, 2)}${separator}` : inputPath.slice(0, 2);
|
|
348
|
+
return [root, splitPathSegments(inputPath.slice(end))];
|
|
349
|
+
}
|
|
350
|
+
if (inputPath.startsWith("\\\\") || inputPath.startsWith("//")) {
|
|
351
|
+
const uncSegments = splitPathSegments(trimStartMatchesChars(inputPath, ["\\", "/"]));
|
|
352
|
+
if (uncSegments.length >= 2) {
|
|
353
|
+
return [
|
|
354
|
+
`${separator}${separator}${uncSegments[0]}${separator}${uncSegments[1]}${separator}`,
|
|
355
|
+
uncSegments.slice(2)
|
|
356
|
+
];
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
if (inputPath.startsWith("\\") || inputPath.startsWith("/")) {
|
|
360
|
+
return [
|
|
361
|
+
separator,
|
|
362
|
+
splitPathSegments(trimStartMatchesChars(inputPath, ["\\", "/"]))
|
|
363
|
+
];
|
|
364
|
+
}
|
|
365
|
+
return ["", splitPathSegments(inputPath)];
|
|
366
|
+
}
|
|
367
|
+
function splitPathSegments(inputPath) {
|
|
368
|
+
return inputPath.split(/[\\/]/).filter(part => part.length > 0);
|
|
369
|
+
}
|
|
370
|
+
function classifyCommandResult(command) {
|
|
371
|
+
return {
|
|
372
|
+
commandKinds: classifyCommandKinds(command),
|
|
373
|
+
isSourceReadCommand: isShellSourceReadCommand(command),
|
|
374
|
+
runsGoTest: commandRunsGoTest(command),
|
|
375
|
+
mentionsSavedToolOutput: commandMentionsSavedToolOutput(command)
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
function previewShellOutputCompaction(
|
|
379
|
+
command,
|
|
380
|
+
original,
|
|
381
|
+
largeOutputThreshold,
|
|
382
|
+
shellGrepLargeOutputThreshold,
|
|
383
|
+
minimumSavedChars
|
|
384
|
+
) {
|
|
385
|
+
const classification = classifyCommandResult(command);
|
|
386
|
+
const hasGoRuntimePanic = looksLikeGoRuntimePanic(original);
|
|
387
|
+
const hasNpmPackOutput = looksLikeNpmPackOutput(original);
|
|
388
|
+
const hasJestRunsOutput = hasJestRunsProgress(original);
|
|
389
|
+
const hasDocusaurusOutput = hasDocusaurusProgress(original);
|
|
390
|
+
const hasSphinxProgressOutput = hasSphinxProgress(original);
|
|
391
|
+
const hasGoPassingTestOutput = classification.runsGoTest && hasPassingGoTestOutput(original);
|
|
392
|
+
const hasNeedrestartNoopOutput = hasNeedrestartNoopSummary(original);
|
|
393
|
+
const canCompactSourceReadProgress = hasGoPassingTestOutput && !classification.mentionsSavedToolOutput;
|
|
394
|
+
if (classification.commandKinds.length === 0 && !hasGoRuntimePanic && !hasNpmPackOutput && !hasJestRunsOutput && !hasGoPassingTestOutput && !hasNeedrestartNoopOutput && !hasDocusaurusOutput && !hasSphinxProgressOutput) {
|
|
395
|
+
return undefined;
|
|
396
|
+
}
|
|
397
|
+
if (classification.commandKinds.length === 0 && classification.isSourceReadCommand && !canCompactSourceReadProgress) {
|
|
398
|
+
return undefined;
|
|
399
|
+
}
|
|
400
|
+
const result = compactShellOutput(
|
|
401
|
+
classification.commandKinds,
|
|
402
|
+
original,
|
|
403
|
+
hasGoPassingTestOutput,
|
|
404
|
+
shellGrepLargeOutputThreshold
|
|
405
|
+
) ?? {
|
|
406
|
+
output: original,
|
|
407
|
+
lossless: true
|
|
408
|
+
};
|
|
409
|
+
const savedChars = saturatingSub(jsStringLen(original), jsStringLen(result.output));
|
|
410
|
+
const originalWouldSpill = !fitsLargeOutputThreshold(original, largeOutputThreshold);
|
|
411
|
+
const savedBytes = saturatingSub(byteLength(original), byteLength(result.output));
|
|
412
|
+
if (savedChars < minimumSavedChars && !(originalWouldSpill && savedBytes > 0)) {
|
|
413
|
+
return undefined;
|
|
414
|
+
}
|
|
415
|
+
return {
|
|
416
|
+
output: result.output,
|
|
417
|
+
savedChars,
|
|
418
|
+
lossless: result.lossless
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
function compactToolOutput(kind, output, largeOutputThreshold) {
|
|
422
|
+
const result = compactGrepContentOutput(output, largeOutputThreshold) ;
|
|
423
|
+
if (result.output === output) {
|
|
424
|
+
return undefined;
|
|
425
|
+
}
|
|
426
|
+
return result;
|
|
427
|
+
}
|
|
428
|
+
function classifyCommandKinds(command) {
|
|
429
|
+
const heredocStrippedCommand = stripHeredocBodies(command);
|
|
430
|
+
if (heredocStrippedCommand === undefined) {
|
|
431
|
+
return [];
|
|
432
|
+
}
|
|
433
|
+
const lineContinuedCommand = regexReplaceAll(String.raw`\s*\\\r?\n\s*`, heredocStrippedCommand.command, " ");
|
|
434
|
+
const commandWithoutAllowedDescriptorRedirects = regexReplaceAll(String.raw`\s+[12]>&[12]\b`, lineContinuedCommand, "");
|
|
435
|
+
const commandWithSafeSubstitutions = replaceSafeCommandSubstitutions(commandWithoutAllowedDescriptorRedirects);
|
|
436
|
+
const safetyCommand = stripQuotedText(commandWithSafeSubstitutions);
|
|
437
|
+
const hasNewline = regexTest(String.raw`\r?\n`, safetyCommand);
|
|
438
|
+
if (regexTest("[;`<>]", safetyCommand) || regexTest(String.raw`(^|[^&])&($|[^&])`, safetyCommand) || safetyCommand.includes("$(")) {
|
|
439
|
+
return [];
|
|
440
|
+
}
|
|
441
|
+
const segments = splitCommandSegments(lineContinuedCommand);
|
|
442
|
+
const segmentKinds = ( segments.map(
|
|
443
|
+
(segment, index) => classifyCommandSegmentOrPipeline(segment, ( heredocStrippedCommand.heredocStdinSegmentIndexes.has(index)))
|
|
444
|
+
));
|
|
445
|
+
if (( segmentKinds.some(kind => kind === undefined))) {
|
|
446
|
+
return [];
|
|
447
|
+
}
|
|
448
|
+
const resolvedKinds = segmentKinds;
|
|
449
|
+
if (hasNewline && !hasErrexitBeforeFirstCommand(segments, resolvedKinds)) {
|
|
450
|
+
return [];
|
|
451
|
+
}
|
|
452
|
+
const result = [];
|
|
453
|
+
for (const kind of resolvedKinds) {
|
|
454
|
+
if (!kind.benign) {
|
|
455
|
+
result.push(kind.kind);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return result;
|
|
459
|
+
}
|
|
460
|
+
function isShellSourceReadCommand(command) {
|
|
461
|
+
const heredocStrippedCommand = stripHeredocBodies(command);
|
|
462
|
+
if (heredocStrippedCommand === undefined) {
|
|
463
|
+
return true;
|
|
464
|
+
}
|
|
465
|
+
const lineContinuedCommand = regexReplaceAll(String.raw`\s*\\\r?\n\s*`, heredocStrippedCommand.command, " ");
|
|
466
|
+
return ( splitCommandSegments(lineContinuedCommand).some(segment => ( splitUnquotedPipes(segment).some(part => isSourceReadSegment(part)))));
|
|
467
|
+
}
|
|
468
|
+
function isSourceReadSegment(segment) {
|
|
469
|
+
const normalized = normalizeSegment(segment);
|
|
470
|
+
const withoutEnv = stripSafeCommandWrappers(stripEnvironmentAssignmentPrefix(normalized));
|
|
471
|
+
return regexTest(
|
|
472
|
+
String.raw`^(?:cat|sed|head|tail|less|more|bat|nl|awk|grep|egrep|fgrep|rg)(?:\s|$)`,
|
|
473
|
+
withoutEnv
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
function classifyCommandSegmentOrPipeline(segment, isHeredocStdinSegment) {
|
|
477
|
+
const parts = splitUnquotedPipes(segment);
|
|
478
|
+
if (parts.length === 1) {
|
|
479
|
+
return classifyCommandSegment(parts[0], isHeredocStdinSegment);
|
|
480
|
+
}
|
|
481
|
+
if (parts.length < 2) {
|
|
482
|
+
return undefined;
|
|
483
|
+
}
|
|
484
|
+
const headKind = classifyCommandSegment(parts[0], isHeredocStdinSegment);
|
|
485
|
+
if (headKind === undefined) {
|
|
486
|
+
return undefined;
|
|
487
|
+
}
|
|
488
|
+
if (segmentsEqual(headKind, BENIGN_SEGMENT)) {
|
|
489
|
+
return undefined;
|
|
490
|
+
}
|
|
491
|
+
if (segmentsEqual(headKind, compactSegment("shell-grep"))) {
|
|
492
|
+
return undefined;
|
|
493
|
+
}
|
|
494
|
+
if (parts.slice(1).every(part => isBenignPipelineTail(part))) {
|
|
495
|
+
return headKind;
|
|
496
|
+
}
|
|
497
|
+
return undefined;
|
|
498
|
+
}
|
|
499
|
+
function classifyCommandSegment(segment, isHeredocStdinSegment) {
|
|
500
|
+
const normalized = normalizeSegment(segment);
|
|
501
|
+
if (normalized.length === 0 || normalized === "true" || normalized === ":" || isBenignGofmtWriteCommand(normalized) || isBenignTarballCleanupCommand(normalized) || isBenignPythonBuildCleanupCommand(normalized) || normalized.startsWith("#") || regexTest(String.raw`^cd(?:\s+(?:"[^"]*"|'[^']*'|[^\s]+))?$`, normalized) || isBenignSetupCommand(normalized) || regexTest(
|
|
502
|
+
String.raw`^set\s+(?:[-+A-Za-z]+|-o\s+[A-Za-z][A-Za-z0-9_-]*|[A-Za-z][A-Za-z0-9_-]*)(?:\s+(?:[-+A-Za-z]+|-o\s+[A-Za-z][A-Za-z0-9_-]*|[A-Za-z][A-Za-z0-9_-]*))*$`,
|
|
503
|
+
normalized
|
|
504
|
+
)) {
|
|
505
|
+
return BENIGN_SEGMENT;
|
|
506
|
+
}
|
|
507
|
+
if (isAssignmentList(normalized) || (normalized.startsWith("export ") && isAssignmentList(normalized.slice("export ".length)))) {
|
|
508
|
+
return BENIGN_SEGMENT;
|
|
509
|
+
}
|
|
510
|
+
const withoutEnv = stripSafeCommandWrappers(stripEnvironmentAssignmentPrefix(normalized));
|
|
511
|
+
let kind;
|
|
512
|
+
if (isAptCommand(withoutEnv)) {
|
|
513
|
+
kind = "apt";
|
|
514
|
+
} else if (isPnpmInstallCommand(withoutEnv)) {
|
|
515
|
+
kind = "pnpm";
|
|
516
|
+
} else if (regexTest(String.raw`^npm\s+pack\b`, withoutEnv)) {
|
|
517
|
+
kind = "npm-pack";
|
|
518
|
+
} else if (isYarnBerryCommand(withoutEnv)) {
|
|
519
|
+
kind = "yarn-berry";
|
|
520
|
+
} else if (regexTest(String.raw`^(?:npm\s+(?:ci|install)|yarn\s+install)\b`, withoutEnv)) {
|
|
521
|
+
kind = "npm";
|
|
522
|
+
} else if (isPipInstallCommand(withoutEnv)) {
|
|
523
|
+
kind = "pip";
|
|
524
|
+
} else if (regexTest(String.raw`^composer\s+(?:install|update|require|remove)\b`, withoutEnv)) {
|
|
525
|
+
kind = "composer";
|
|
526
|
+
} else if (regexTest(String.raw`^poetry\s+(?:install|update|add|remove)\b`, withoutEnv)) {
|
|
527
|
+
kind = "poetry";
|
|
528
|
+
} else if (isUvCommand(withoutEnv)) {
|
|
529
|
+
kind = "uv";
|
|
530
|
+
} else if (isBenignVersionCommand(withoutEnv)) {
|
|
531
|
+
return BENIGN_SEGMENT;
|
|
532
|
+
} else if (isGoCommand(withoutEnv)) {
|
|
533
|
+
kind = "go";
|
|
534
|
+
} else if (isJsTestCommand(withoutEnv)) {
|
|
535
|
+
kind = "js-test";
|
|
536
|
+
} else if (regexTest(String.raw`^cargo\s+(?:build|check|test|clippy|doc|fetch)\b`, withoutEnv)) {
|
|
537
|
+
kind = "cargo";
|
|
538
|
+
} else if (regexTest(String.raw`^(?:node|npx|npm\s+exec|pnpm\s+exec|yarn\s+node)\b`, withoutEnv)) {
|
|
539
|
+
kind = "node";
|
|
540
|
+
} else if (isNxCommand(withoutEnv)) {
|
|
541
|
+
kind = "nx";
|
|
542
|
+
} else if (isPytestCommand(withoutEnv)) {
|
|
543
|
+
kind = "pytest";
|
|
544
|
+
} else if (isPythonUnittestCommand(withoutEnv)) {
|
|
545
|
+
kind = "unittest";
|
|
546
|
+
} else if (isPythonBuildCommand(withoutEnv)) {
|
|
547
|
+
kind = "python-build";
|
|
548
|
+
} else if (isBenignGitCommand(withoutEnv)) {
|
|
549
|
+
return BENIGN_SEGMENT;
|
|
550
|
+
} else if (isGitProgressCommand(withoutEnv)) {
|
|
551
|
+
kind = "git";
|
|
552
|
+
} else if (isGitCleanOrResetCommand(withoutEnv)) {
|
|
553
|
+
kind = "git-clean";
|
|
554
|
+
} else if (regexTest(String.raw`^git\s+(?:checkout|switch)\b`, withoutEnv)) {
|
|
555
|
+
kind = "git";
|
|
556
|
+
} else if (isPythonBuildExtCommand(withoutEnv)) {
|
|
557
|
+
kind = "python-build-ext";
|
|
558
|
+
} else if (isDjangoTestCommand(withoutEnv)) {
|
|
559
|
+
kind = "django-test";
|
|
560
|
+
} else if (isGolangciLintCommand(withoutEnv)) {
|
|
561
|
+
kind = "golangci-lint";
|
|
562
|
+
} else if (isClangFormatLinterCommand(withoutEnv)) {
|
|
563
|
+
kind = "clang-format-linter";
|
|
564
|
+
} else if (isGradleCommand(withoutEnv)) {
|
|
565
|
+
kind = "gradle";
|
|
566
|
+
} else if (isCmakeConfigureCommand(withoutEnv)) {
|
|
567
|
+
kind = "cmake";
|
|
568
|
+
} else if (isMavenCommand(withoutEnv)) {
|
|
569
|
+
kind = "maven";
|
|
570
|
+
} else if (isDotnetCommand(withoutEnv)) {
|
|
571
|
+
kind = "dotnet";
|
|
572
|
+
} else if (isSafeShellGrepCommand(withoutEnv)) {
|
|
573
|
+
kind = "shell-grep";
|
|
574
|
+
} else if (regexTest(String.raw`^(?:g?make|ninja)\b`, withoutEnv) || regexTest(String.raw`^\./configure\b`, withoutEnv) || regexTest(String.raw`^cmake\s+--build\b`, withoutEnv)) {
|
|
575
|
+
kind = "make";
|
|
576
|
+
} else if (isPythonScriptCommand(withoutEnv, isHeredocStdinSegment)) {
|
|
577
|
+
kind = "python-script";
|
|
578
|
+
} else {
|
|
579
|
+
return undefined;
|
|
580
|
+
}
|
|
581
|
+
return compactSegment(kind);
|
|
582
|
+
}
|
|
583
|
+
function splitUnquotedPipes(segment) {
|
|
584
|
+
const parts = [];
|
|
585
|
+
let start = 0;
|
|
586
|
+
let inSingle = false;
|
|
587
|
+
let inDouble = false;
|
|
588
|
+
for (let i = 0; i < segment.length; i++) {
|
|
589
|
+
const ch = segment[i];
|
|
590
|
+
if (ch === "'" && !inDouble) {
|
|
591
|
+
inSingle = !inSingle;
|
|
592
|
+
} else if (ch === "\"" && !inSingle && !isEscapedByOddBackslashes(segment, i)) {
|
|
593
|
+
inDouble = !inDouble;
|
|
594
|
+
} else if (ch === "|" && !inSingle && !inDouble) {
|
|
595
|
+
pushTrimmedPart(parts, segment.slice(start, i));
|
|
596
|
+
start = i + 1;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
pushTrimmedPart(parts, segment.slice(start));
|
|
600
|
+
return parts;
|
|
601
|
+
}
|
|
602
|
+
function pushTrimmedPart(parts, part) {
|
|
603
|
+
const trimmed = part.trim();
|
|
604
|
+
if (trimmed.length !== 0) {
|
|
605
|
+
parts.push(trimmed);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
function isBenignPipelineTail(segment) {
|
|
609
|
+
const normalized = normalizeSegment(segment);
|
|
610
|
+
return normalized === "cat" || regexTest(String.raw`^tee(?:\s+-a)?\s+(?:"[^"]*"|'[^']*'|\S+)$`, normalized) || regexTest(
|
|
611
|
+
String.raw`^(?:head|tail)(?:\s+(?:-[nc]\s*)?[+-]?\d+|\s+-[nc]\s+[+-]?\d+)?$`,
|
|
612
|
+
normalized
|
|
613
|
+
) || regexTest(String.raw`^sed\s+-n\s+(?:"\d+(?:,\d+)?p"|'[\d]+(?:,\d+)?p')$`, normalized) || isSafeStreamingGrepTail(normalized) || isSafeStreamingFlagOnlyTail(normalized);
|
|
614
|
+
}
|
|
615
|
+
function stripPrefix(value, prefix) {
|
|
616
|
+
return value.startsWith(prefix) ? value.slice(prefix.length) : undefined;
|
|
617
|
+
}
|
|
618
|
+
function stripSuffix(value, suffix) {
|
|
619
|
+
return value.endsWith(suffix) ? value.slice(0, value.length - suffix.length) : undefined;
|
|
620
|
+
}
|
|
621
|
+
function splitOnce(value, separator) {
|
|
622
|
+
const index = value.indexOf(separator);
|
|
623
|
+
if (index === -1) {
|
|
624
|
+
return undefined;
|
|
625
|
+
}
|
|
626
|
+
return [value.slice(0, index), value.slice(index + separator.length)];
|
|
627
|
+
}
|
|
628
|
+
function rsplitOnce(value, separator) {
|
|
629
|
+
const index = value.lastIndexOf(separator);
|
|
630
|
+
if (index === -1) {
|
|
631
|
+
return undefined;
|
|
632
|
+
}
|
|
633
|
+
return [value.slice(0, index), value.slice(index + separator.length)];
|
|
634
|
+
}
|
|
635
|
+
function asciiLowercase(value) {
|
|
636
|
+
let result = "";
|
|
637
|
+
for (let i = 0; i < value.length; i++) {
|
|
638
|
+
const code = value.charCodeAt(i);
|
|
639
|
+
result += code >= 65 && code <= 90 ? String.fromCharCode(code + 32) : value[i];
|
|
640
|
+
}
|
|
641
|
+
return result;
|
|
642
|
+
}
|
|
643
|
+
function parseUsize(value) {
|
|
644
|
+
if (!/^\+?\d+$/.test(value)) {
|
|
645
|
+
return undefined;
|
|
646
|
+
}
|
|
647
|
+
return Number(value);
|
|
648
|
+
}
|
|
649
|
+
function isAptCommand(segment) {
|
|
650
|
+
const withoutSudo = stripPrefix(segment, "sudo ") ?? segment;
|
|
651
|
+
const args = stripPrefix(withoutSudo, "apt-get ") ?? stripPrefix(withoutSudo, "apt ");
|
|
652
|
+
if (args === undefined) {
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
const tokens = splitWhitespace(args);
|
|
656
|
+
let i = 0;
|
|
657
|
+
while (i < tokens.length) {
|
|
658
|
+
const token = tokens[i];
|
|
659
|
+
if (token === "-o" || token === "--option" || token === "-c" || token === "--config-file") {
|
|
660
|
+
i += 2;
|
|
661
|
+
continue;
|
|
662
|
+
}
|
|
663
|
+
if (token.startsWith("-")) {
|
|
664
|
+
i += 1;
|
|
665
|
+
continue;
|
|
666
|
+
}
|
|
667
|
+
return token === "update" || token === "install";
|
|
668
|
+
}
|
|
669
|
+
return false;
|
|
670
|
+
}
|
|
671
|
+
function isPnpmInstallCommand(segment) {
|
|
672
|
+
const tokens = splitWhitespace(segment);
|
|
673
|
+
if (tokens[0] !== "pnpm") {
|
|
674
|
+
return false;
|
|
675
|
+
}
|
|
676
|
+
let index = 1;
|
|
677
|
+
while (index < tokens.length) {
|
|
678
|
+
const token = tokens[index];
|
|
679
|
+
if ([
|
|
680
|
+
"--filter",
|
|
681
|
+
"-F",
|
|
682
|
+
"--prefix",
|
|
683
|
+
"-C",
|
|
684
|
+
"--dir",
|
|
685
|
+
"--loglevel",
|
|
686
|
+
"--reporter",
|
|
687
|
+
"--package-import-method",
|
|
688
|
+
"--workspace-concurrency"
|
|
689
|
+
].includes(token)) {
|
|
690
|
+
index += 2;
|
|
691
|
+
continue;
|
|
692
|
+
}
|
|
693
|
+
if ([
|
|
694
|
+
"--recursive",
|
|
695
|
+
"-r",
|
|
696
|
+
"--workspace-root",
|
|
697
|
+
"-w",
|
|
698
|
+
"--silent",
|
|
699
|
+
"-s",
|
|
700
|
+
"--use-stderr",
|
|
701
|
+
"--color",
|
|
702
|
+
"--no-color"
|
|
703
|
+
].includes(token) || regexTest(
|
|
704
|
+
String.raw`^(?:--filter|--prefix|--dir|--loglevel|--reporter|--package-import-method|--workspace-concurrency|-F|-C)=`,
|
|
705
|
+
token
|
|
706
|
+
)) {
|
|
707
|
+
index += 1;
|
|
708
|
+
continue;
|
|
709
|
+
}
|
|
710
|
+
break;
|
|
711
|
+
}
|
|
712
|
+
return tokens[index] === "install" || tokens[index] === "i";
|
|
713
|
+
}
|
|
714
|
+
function isGitProgressCommand(segment) {
|
|
715
|
+
const tokens = splitWhitespace(segment);
|
|
716
|
+
const index = gitSubcommandIndex(tokens);
|
|
717
|
+
if (index === undefined) {
|
|
718
|
+
return false;
|
|
719
|
+
}
|
|
720
|
+
const subcommand = tokens[index];
|
|
721
|
+
return subcommand === "clone" || subcommand === "fetch" || subcommand === "pull" || (subcommand === "submodule" && tokens[index + 1] === "update");
|
|
722
|
+
}
|
|
723
|
+
function isGitCleanOrResetCommand(segment) {
|
|
724
|
+
const tokens = splitWhitespace(segment);
|
|
725
|
+
const index = gitSubcommandIndex(tokens);
|
|
726
|
+
if (index === undefined) {
|
|
727
|
+
return false;
|
|
728
|
+
}
|
|
729
|
+
const subcommand = tokens[index];
|
|
730
|
+
const args = tokens.slice(index + 1);
|
|
731
|
+
if (subcommand === "reset") {
|
|
732
|
+
return args.includes("--hard");
|
|
733
|
+
}
|
|
734
|
+
return subcommand === "clean" && ( args.some(arg => isGitCleanForceOption(arg)));
|
|
735
|
+
}
|
|
736
|
+
function isGitCleanForceOption(arg) {
|
|
737
|
+
return arg === "--force" || (regexTest(String.raw`^-[A-Za-z]+$`, arg) && arg.includes("f"));
|
|
738
|
+
}
|
|
739
|
+
function isBenignGitCommand(segment) {
|
|
740
|
+
const tokens = splitWhitespace(segment);
|
|
741
|
+
const index = gitSubcommandIndex(tokens);
|
|
742
|
+
if (index === undefined) {
|
|
743
|
+
return false;
|
|
744
|
+
}
|
|
745
|
+
const subcommand = tokens[index];
|
|
746
|
+
const args = tokens.slice(index + 1);
|
|
747
|
+
if (subcommand === "status") {
|
|
748
|
+
return args.every(
|
|
749
|
+
arg => arg === "--short" || arg === "-s" || arg === "--porcelain" || arg.startsWith("--untracked-files")
|
|
750
|
+
);
|
|
751
|
+
}
|
|
752
|
+
if (subcommand === "diff") {
|
|
753
|
+
const hasSummaryOutput = ( args.some(arg => [
|
|
754
|
+
"--stat",
|
|
755
|
+
"--shortstat",
|
|
756
|
+
"--numstat",
|
|
757
|
+
"--name-only",
|
|
758
|
+
"--name-status",
|
|
759
|
+
"--summary",
|
|
760
|
+
"--compact-summary"
|
|
761
|
+
].includes(arg)));
|
|
762
|
+
return hasSummaryOutput && !( args.some(
|
|
763
|
+
arg => arg === "-p" || arg === "-u" || arg === "--patch" || arg.startsWith("--patch-") || arg.startsWith("--word-diff") || arg.startsWith("--color-words")
|
|
764
|
+
));
|
|
765
|
+
}
|
|
766
|
+
return subcommand === "rev-parse" && args.every(arg => arg === "--show-toplevel" || arg === "--show-prefix");
|
|
767
|
+
}
|
|
768
|
+
function gitSubcommandIndex(tokens) {
|
|
769
|
+
if (tokens[0] !== "git") {
|
|
770
|
+
return undefined;
|
|
771
|
+
}
|
|
772
|
+
let index = 1;
|
|
773
|
+
while (index < tokens.length) {
|
|
774
|
+
const token = tokens[index];
|
|
775
|
+
if (token === "-C" || token === "--git-dir" || token === "--work-tree") {
|
|
776
|
+
index += 2;
|
|
777
|
+
continue;
|
|
778
|
+
}
|
|
779
|
+
if (token.startsWith("-c")) {
|
|
780
|
+
index += token === "-c" ? 2 : 1;
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
783
|
+
if (token.startsWith("--")) {
|
|
784
|
+
index += 1;
|
|
785
|
+
continue;
|
|
786
|
+
}
|
|
787
|
+
break;
|
|
788
|
+
}
|
|
789
|
+
return index < tokens.length ? index : undefined;
|
|
790
|
+
}
|
|
791
|
+
function isJsTestCommand(segment) {
|
|
792
|
+
return !regexTest(
|
|
793
|
+
String.raw`(?:^|\s)(?:-w|--watch(?:[=\s]|$)|--watchAll(?:[=\s]|$)|--watch-all(?:[=\s]|$)|--watch-files(?:[=\s]|$))`,
|
|
794
|
+
segment
|
|
795
|
+
) && regexTest(
|
|
796
|
+
String.raw`^(?:npx\s+|(?:npm|pnpm|yarn)\s+exec\s+)?(?:vitest|jest|mocha|tap)(?:\s|$)`,
|
|
797
|
+
segment
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
function isYarnBerryCommand(segment) {
|
|
801
|
+
return regexTest(
|
|
802
|
+
String.raw`^(?:yarn|corepack\s+yarn)\s+(?:install|add|workspaces|run\s+install)\b`,
|
|
803
|
+
segment
|
|
804
|
+
) || regexTest(String.raw`^node\s+(?:\./)?script/yarn\.js\s+(?:install|add)\b`, segment);
|
|
805
|
+
}
|
|
806
|
+
function isNxCommand(segment) {
|
|
807
|
+
return regexTest(
|
|
808
|
+
String.raw`^(?:nx|(?:yarn|pnpm)\s+(?:nx|release:build|typescript|test:ts|lint))\b`,
|
|
809
|
+
segment
|
|
810
|
+
);
|
|
811
|
+
}
|
|
812
|
+
function isDjangoTestCommand(segment) {
|
|
813
|
+
const pythonWithOptions = pythonWithOptionsPattern();
|
|
814
|
+
return regexTest(
|
|
815
|
+
String.raw`^${pythonWithOptions}\s+(?:(?:\./)?(?:tests/)?runtests\.py|manage\.py\s+test|-m\s+django\s+test)\b`,
|
|
816
|
+
segment
|
|
817
|
+
) || regexTest(String.raw`^django-admin\s+test\b`, segment);
|
|
818
|
+
}
|
|
819
|
+
function isGolangciLintCommand(segment) {
|
|
820
|
+
return regexTest(String.raw`^(?:[A-Za-z0-9_./+-]+/)?golangci-lint\s+run\b`, segment) || regexTest(
|
|
821
|
+
String.raw`^go\s+run\s+github\.com/golangci/golangci-lint/cmd/golangci-lint(?:@\S+)?\s+run\b`,
|
|
822
|
+
segment
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
function isClangFormatLinterCommand(segment) {
|
|
826
|
+
return regexTest(
|
|
827
|
+
String.raw`^${pythonWithOptionsPattern()}\s+\S*tools/linter/adapters/clangformat_linter\.py\b`,
|
|
828
|
+
segment
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
function isGradleCommand(segment) {
|
|
832
|
+
return regexTest(
|
|
833
|
+
String.raw`^(?:(?:\./|/\S+/)?gradlew?|\$GRADLE|\$\{GRADLE\})(?:\s|$)`,
|
|
834
|
+
segment
|
|
835
|
+
);
|
|
836
|
+
}
|
|
837
|
+
function isCmakeConfigureCommand(segment) {
|
|
838
|
+
return regexTest(String.raw`^cmake(?:\s|$)`, segment) && !( splitWhitespace(segment).some(token => regexTest(
|
|
839
|
+
String.raw`^(?:--build|--install|-E|-P|--version|-N|-h|--help(?:-.+)?)$`,
|
|
840
|
+
token
|
|
841
|
+
)));
|
|
842
|
+
}
|
|
843
|
+
function isMavenCommand(segment) {
|
|
844
|
+
return regexTest(String.raw`^(?:(?:\./)?mvnw?|mvn)(?:\s|$)`, segment);
|
|
845
|
+
}
|
|
846
|
+
function isDotnetCommand(segment) {
|
|
847
|
+
return regexTest(String.raw`^dotnet\s+(?:build|test|restore|publish|pack)(?:\s|$)`, segment);
|
|
848
|
+
}
|
|
849
|
+
function isUvCommand(segment) {
|
|
850
|
+
return regexTest(
|
|
851
|
+
String.raw`^(?:uv|(?:python|python3(?:\.\d+)?)\s+-m\s+uv)\s+(?:sync|pip\s+(?:install|sync|compile)|venv|add|lock|run)\b`,
|
|
852
|
+
segment
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
function isPipInstallCommand(segment) {
|
|
856
|
+
return regexTest(
|
|
857
|
+
String.raw`^(?:(?:${pythonExecutablePattern()})\s+-m\s+pip|pip|pip3)\s+install\b`,
|
|
858
|
+
segment
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
function isGoCommand(segment) {
|
|
862
|
+
return regexTest(
|
|
863
|
+
String.raw`^(?:go|/(?:\S+/)*go)\s+(?:test|build|install|get|mod\s+(?:tidy|download|verify|graph)|work\s+sync)\b`,
|
|
864
|
+
segment
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
function isPytestCommand(segment) {
|
|
868
|
+
return regexTest(
|
|
869
|
+
String.raw`^(?:(?:${pythonWithOptionsPattern()})\s+-m\s+pytest|(?:(?:[A-Za-z0-9_./+-]+/)?pytest))(?:\s|$)`,
|
|
870
|
+
segment
|
|
871
|
+
);
|
|
872
|
+
}
|
|
873
|
+
function isPythonUnittestCommand(segment) {
|
|
874
|
+
return regexTest(String.raw`^${pythonWithOptionsPattern()}\s+-m\s+unittest\b`, segment);
|
|
875
|
+
}
|
|
876
|
+
function isPythonBuildCommand(segment) {
|
|
877
|
+
return regexTest(String.raw`^${pythonWithOptionsPattern()}\s+-m\s+build(?:\s|$)`, segment);
|
|
878
|
+
}
|
|
879
|
+
function isPythonBuildExtCommand(segment) {
|
|
880
|
+
return regexTest(
|
|
881
|
+
String.raw`^${pythonExecutablePattern()}\s+setup\.py\s+build_ext\b`,
|
|
882
|
+
segment
|
|
883
|
+
);
|
|
884
|
+
}
|
|
885
|
+
function isPythonScriptCommand(segment, isHeredocStdinSegment) {
|
|
886
|
+
return isHeredocStdinPythonCommand(segment, isHeredocStdinSegment) || regexTest(
|
|
887
|
+
String.raw`^${pythonWithOptionsPattern()}\s+(?:-c\s+(?:"[^"]*"|'[^']*'|\S+)|(?:"[^"]+\.py"|'[^']+\.py'|[^\s-]\S*\.py))(?:\s|$)`,
|
|
888
|
+
segment
|
|
889
|
+
);
|
|
890
|
+
}
|
|
891
|
+
function isHeredocStdinPythonCommand(segment, isHeredocStdinSegment) {
|
|
892
|
+
return isHeredocStdinSegment && regexTest(String.raw`^${pythonExecutablePattern()}\s+-$`, segment);
|
|
893
|
+
}
|
|
894
|
+
function isBenignSetupCommand(segment) {
|
|
895
|
+
return isSourceActivateCommand(segment) || isBenignPythonVenvCommand(segment) || regexTest(
|
|
896
|
+
String.raw`^mkdir\s+-p\s+(?:"[^"]*"|'[^']*'|[^\s]+)(?:\s+(?:"[^"]*"|'[^']*'|[^\s]+))*$`,
|
|
897
|
+
segment
|
|
898
|
+
) || regexTest(String.raw`^umask\s+[0-7]{3,4}$`, segment) || regexTest(
|
|
899
|
+
String.raw`^unset\s+[A-Za-z_][A-Za-z0-9_]*(?:\s+[A-Za-z_][A-Za-z0-9_]*)*$`,
|
|
900
|
+
segment
|
|
901
|
+
) || segment === "hash -r" || isBenignCorepackYarnSetupCommand(segment) || isLiteralSeparatorCommand(segment);
|
|
902
|
+
}
|
|
903
|
+
function isSourceActivateCommand(segment) {
|
|
904
|
+
return regexTest(
|
|
905
|
+
String.raw`^(?:source|\.)\s+(?:"[^"]*(?:^|/)activate"|'[^']*(?:^|/)activate'|\S*(?:^|/)activate)$`,
|
|
906
|
+
segment
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
function isBenignCorepackYarnSetupCommand(segment) {
|
|
910
|
+
return regexTest(
|
|
911
|
+
String.raw`^corepack\s+(?:enable|prepare\s+yarn@\S+\s+--activate)$`,
|
|
912
|
+
segment
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
function isBenignPythonVenvCommand(segment) {
|
|
916
|
+
return regexTest(String.raw`^${pythonExecutablePattern()}\s+-m\s+venv(?:\s+\S+)+$`, segment) && !regexTest(String.raw`\s(?:--help|-h)(?:\s|$)`, segment);
|
|
917
|
+
}
|
|
918
|
+
function isBenignGofmtWriteCommand(segment) {
|
|
919
|
+
return regexTest(
|
|
920
|
+
String.raw`^gofmt\s+-w(?:\s+(?:"[^"-][^"]*"|'[^'-][^']*'|[^-\s]\S*))+$`,
|
|
921
|
+
segment
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
function isBenignTarballCleanupCommand(segment) {
|
|
925
|
+
return regexTest(String.raw`^rm\s+-f\s+(?:"[^"]+\.tgz"|'[^']+\.tgz'|\S+\.tgz)$`, segment);
|
|
926
|
+
}
|
|
927
|
+
function isBenignPythonBuildCleanupCommand(segment) {
|
|
928
|
+
return regexTest(String.raw`^rm\s+-rf\s+dist\s+build\s+\*\.egg-info$`, segment);
|
|
929
|
+
}
|
|
930
|
+
function isBenignVersionCommand(segment) {
|
|
931
|
+
return regexTest(String.raw`^/\S+\s+(?:--version|-version|version)$`, segment);
|
|
932
|
+
}
|
|
933
|
+
function isAssignmentList(segment) {
|
|
934
|
+
return regexTest(
|
|
935
|
+
String.raw`^(?:[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|[^\s]+))(?:\s+[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|[^\s]+))*$`,
|
|
936
|
+
segment
|
|
937
|
+
);
|
|
938
|
+
}
|
|
939
|
+
function stripEnvironmentAssignmentPrefix(segment) {
|
|
940
|
+
return regexReplaceAll(
|
|
941
|
+
String.raw`^([A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|\S+)\s+)+`,
|
|
942
|
+
segment,
|
|
943
|
+
""
|
|
944
|
+
);
|
|
945
|
+
}
|
|
946
|
+
function stripSafeCommandWrappers(segment) {
|
|
947
|
+
let current = segment;
|
|
948
|
+
for (let iteration = 0; iteration < 3; iteration++) {
|
|
949
|
+
const before = current;
|
|
950
|
+
current = stripEnvironmentAssignmentPrefix(regexReplaceAll(String.raw`^timeout\s+\d+(?:[smhd])?\s+`, current, ""));
|
|
951
|
+
current = stripEnvironmentAssignmentPrefix(regexReplaceAll(
|
|
952
|
+
String.raw`^env(?:\s+[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|\S+))+\s+`,
|
|
953
|
+
current,
|
|
954
|
+
""
|
|
955
|
+
));
|
|
956
|
+
if (current === before) {
|
|
957
|
+
return current;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
return current;
|
|
961
|
+
}
|
|
962
|
+
function isLiteralSeparatorCommand(segment) {
|
|
963
|
+
return regexTest(
|
|
964
|
+
String.raw`^echo(?:\s+-n)?(?:\s+(?:"[\s#=_.:/*+\-[\]]{1,19}"|'[\s#=_.:/*+\-[\]]{1,19}'))+$`,
|
|
965
|
+
segment
|
|
966
|
+
) || regexTest(
|
|
967
|
+
String.raw`^printf\s+(?:"(?:[\s#=_.:/*+\-[\]]|\\n|\\t){1,19}"|'(?:[\s#=_.:/*+\-[\]]|\\n|\\t){1,19}')$`,
|
|
968
|
+
segment
|
|
969
|
+
);
|
|
970
|
+
}
|
|
971
|
+
function isSafeShellGrepCommand(segment) {
|
|
972
|
+
const tokens = splitWhitespace(segment);
|
|
973
|
+
const command = tokens[0];
|
|
974
|
+
if (command === undefined) {
|
|
975
|
+
return false;
|
|
976
|
+
}
|
|
977
|
+
if (!(command === "rg" || command === "grep" || command === "egrep" || command === "fgrep")) {
|
|
978
|
+
return false;
|
|
979
|
+
}
|
|
980
|
+
const args = tokens.slice(1);
|
|
981
|
+
let patternCount = 0;
|
|
982
|
+
let i = 0;
|
|
983
|
+
while (i < args.length) {
|
|
984
|
+
const arg = args[i];
|
|
985
|
+
if (arg === "--") {
|
|
986
|
+
return i < args.length - 1 && !( args.slice(i + 1).some(a => isSavedToolOutputPath(a)));
|
|
987
|
+
}
|
|
988
|
+
if (arg === "-e" || arg === "--regexp") {
|
|
989
|
+
i += 1;
|
|
990
|
+
if (i >= args.length) {
|
|
991
|
+
return false;
|
|
992
|
+
}
|
|
993
|
+
patternCount += 1;
|
|
994
|
+
if (patternCount > 1) {
|
|
995
|
+
return false;
|
|
996
|
+
}
|
|
997
|
+
i += 1;
|
|
998
|
+
continue;
|
|
999
|
+
}
|
|
1000
|
+
if ((arg.startsWith("-e") && arg.length > 2) || arg.startsWith("--regexp=")) {
|
|
1001
|
+
patternCount += 1;
|
|
1002
|
+
if (patternCount > 1) {
|
|
1003
|
+
return false;
|
|
1004
|
+
}
|
|
1005
|
+
i += 1;
|
|
1006
|
+
continue;
|
|
1007
|
+
}
|
|
1008
|
+
if (isShellGrepFlagWithValue(arg)) {
|
|
1009
|
+
i += 1;
|
|
1010
|
+
if (i >= args.length) {
|
|
1011
|
+
return false;
|
|
1012
|
+
}
|
|
1013
|
+
i += 1;
|
|
1014
|
+
continue;
|
|
1015
|
+
}
|
|
1016
|
+
if (regexTest(String.raw`^(?:--glob|--include|--exclude|--exclude-dir)=`, arg)) {
|
|
1017
|
+
i += 1;
|
|
1018
|
+
continue;
|
|
1019
|
+
}
|
|
1020
|
+
if (arg.startsWith("-")) {
|
|
1021
|
+
if (isUnsafeShellGrepFlag(arg) || !isSafeShellGrepFlag(command, arg)) {
|
|
1022
|
+
return false;
|
|
1023
|
+
}
|
|
1024
|
+
i += 1;
|
|
1025
|
+
continue;
|
|
1026
|
+
}
|
|
1027
|
+
if (isSavedToolOutputPath(arg)) {
|
|
1028
|
+
return false;
|
|
1029
|
+
}
|
|
1030
|
+
if (patternCount === 0) {
|
|
1031
|
+
patternCount += 1;
|
|
1032
|
+
}
|
|
1033
|
+
i += 1;
|
|
1034
|
+
}
|
|
1035
|
+
return patternCount === 1;
|
|
1036
|
+
}
|
|
1037
|
+
function isShellGrepFlagWithValue(arg) {
|
|
1038
|
+
return arg === "-g" || arg === "--glob" || arg === "--include" || arg === "--exclude" || arg === "--exclude-dir";
|
|
1039
|
+
}
|
|
1040
|
+
function isSafeShellGrepFlag(command, arg) {
|
|
1041
|
+
return (command === "rg" ? regexTest(String.raw`^-[nHiwxEFP]+$`, arg) : regexTest(String.raw`^-[nHiwxErRFP]+$`, arg)) || regexTest(
|
|
1042
|
+
String.raw`^(?:--line-number|--with-filename|--no-heading|--ignore-case|--word-regexp|--line-regexp|--recursive|--extended-regexp|--fixed-strings|--perl-regexp|--color=never)$`,
|
|
1043
|
+
arg
|
|
1044
|
+
);
|
|
1045
|
+
}
|
|
1046
|
+
function isUnsafeShellGrepFlag(arg) {
|
|
1047
|
+
return arg === "-f" || arg === "--file" || arg.startsWith("--file=") || regexTest(
|
|
1048
|
+
String.raw`^(?:--json|--vimgrep|--files|--type-list|--heading|--no-line-number|--no-filename|--count|--count-matches|--files-with(?:out)?-matches|--only-matching|--quiet|--null|--null-data|--text|--binary|--context|--before-context|--after-context|--invert-match|--passthru|--replace|--line-buffered|--color=always)$`,
|
|
1049
|
+
arg
|
|
1050
|
+
) || regexTest(String.raw`^-[^-]*[A-CLlcoqvZ0]`, arg);
|
|
1051
|
+
}
|
|
1052
|
+
function isSafeStreamingGrepTail(segment) {
|
|
1053
|
+
const argsText = stripPrefix(segment, "grep ") ?? stripPrefix(segment, "egrep ") ?? stripPrefix(segment, "fgrep ");
|
|
1054
|
+
if (argsText === undefined) {
|
|
1055
|
+
return false;
|
|
1056
|
+
}
|
|
1057
|
+
const args = splitWhitespace(argsText);
|
|
1058
|
+
let patternCount = 0;
|
|
1059
|
+
let i = 0;
|
|
1060
|
+
while (i < args.length) {
|
|
1061
|
+
const arg = args[i];
|
|
1062
|
+
if (arg === "--") {
|
|
1063
|
+
return i === args.length - 1;
|
|
1064
|
+
}
|
|
1065
|
+
if (arg === "-e" || arg === "--regexp") {
|
|
1066
|
+
i += 1;
|
|
1067
|
+
if (i >= args.length) {
|
|
1068
|
+
return false;
|
|
1069
|
+
}
|
|
1070
|
+
patternCount += 1;
|
|
1071
|
+
i += 1;
|
|
1072
|
+
continue;
|
|
1073
|
+
}
|
|
1074
|
+
if ((arg.startsWith("-e") && arg.length > 2) || arg.startsWith("--regexp=")) {
|
|
1075
|
+
patternCount += 1;
|
|
1076
|
+
i += 1;
|
|
1077
|
+
continue;
|
|
1078
|
+
}
|
|
1079
|
+
if (arg === "-f" || arg === "--file" || arg.startsWith("--file=") || regexTest(String.raw`^-[^-]*[cCfFPRrLlmoq]`, arg) || regexTest(
|
|
1080
|
+
String.raw`^(?:--(?:count|fixed-strings|perl-regexp|recursive|dereference-recursive|files-with-matches|files-without-match|only-matching|quiet|include|exclude|exclude-dir)|--(?:include|exclude|exclude-dir)=)`,
|
|
1081
|
+
arg
|
|
1082
|
+
)) {
|
|
1083
|
+
return false;
|
|
1084
|
+
}
|
|
1085
|
+
if (arg.startsWith("-")) {
|
|
1086
|
+
i += 1;
|
|
1087
|
+
continue;
|
|
1088
|
+
}
|
|
1089
|
+
patternCount += 1;
|
|
1090
|
+
if (patternCount > 1) {
|
|
1091
|
+
return false;
|
|
1092
|
+
}
|
|
1093
|
+
i += 1;
|
|
1094
|
+
}
|
|
1095
|
+
return patternCount === 1;
|
|
1096
|
+
}
|
|
1097
|
+
function isSafeStreamingFlagOnlyTail(segment) {
|
|
1098
|
+
const tokens = splitWhitespace(segment);
|
|
1099
|
+
const command = tokens[0];
|
|
1100
|
+
if (command === undefined) {
|
|
1101
|
+
return false;
|
|
1102
|
+
}
|
|
1103
|
+
if (!(command === "wc" || command === "sort" || command === "uniq" || command === "cut")) {
|
|
1104
|
+
return false;
|
|
1105
|
+
}
|
|
1106
|
+
const args = tokens.slice(1);
|
|
1107
|
+
let i = 0;
|
|
1108
|
+
while (i < args.length) {
|
|
1109
|
+
const arg = args[i];
|
|
1110
|
+
if (arg === "--") {
|
|
1111
|
+
return i === args.length - 1;
|
|
1112
|
+
}
|
|
1113
|
+
if (command === "sort" && (arg === "-o" || arg === "--output" || arg.startsWith("--output="))) {
|
|
1114
|
+
return false;
|
|
1115
|
+
}
|
|
1116
|
+
if (command === "cut" && (arg === "-d" || arg === "-f" || arg === "-c" || arg === "-b")) {
|
|
1117
|
+
i += 1;
|
|
1118
|
+
if (i >= args.length) {
|
|
1119
|
+
return false;
|
|
1120
|
+
}
|
|
1121
|
+
i += 1;
|
|
1122
|
+
continue;
|
|
1123
|
+
}
|
|
1124
|
+
if (!arg.startsWith("-")) {
|
|
1125
|
+
return false;
|
|
1126
|
+
}
|
|
1127
|
+
i += 1;
|
|
1128
|
+
}
|
|
1129
|
+
return true;
|
|
1130
|
+
}
|
|
1131
|
+
function isSavedToolOutputPath(arg) {
|
|
1132
|
+
return regexTest(
|
|
1133
|
+
String.raw`(?:^|/)(?:\d+-copilot-tool-output-|copilot-tool-output(?:-original)?-|original-output-\d+-)`,
|
|
1134
|
+
arg
|
|
1135
|
+
);
|
|
1136
|
+
}
|
|
1137
|
+
function normalizeSegment(segment) {
|
|
1138
|
+
const trimmed = segment.trim();
|
|
1139
|
+
const withoutRedirects = regexReplaceAll(String.raw`\s+(?:2>&1|1>&2)\b`, trimmed, "");
|
|
1140
|
+
return regexReplaceAll(String.raw`\s+`, withoutRedirects, " ");
|
|
1141
|
+
}
|
|
1142
|
+
function replaceSafeCommandSubstitutions(command) {
|
|
1143
|
+
if (!regexTest(String.raw`\btools/linter/adapters/clangformat_linter\.py\b`, command)) {
|
|
1144
|
+
return command;
|
|
1145
|
+
}
|
|
1146
|
+
return regexReplaceAll(
|
|
1147
|
+
"\\$\\(\\s*git\\s+--no-pager\\s+ls-files(?:\\s+(?:\"[^\"`$()]*\"|'[^'`$()]*'|[^'\"`()$;&<>|\\s]+))*\\s*\\)",
|
|
1148
|
+
command,
|
|
1149
|
+
"__SAFE_GIT_LS_FILES__"
|
|
1150
|
+
);
|
|
1151
|
+
}
|
|
1152
|
+
function splitCommandSegments(command) {
|
|
1153
|
+
const segments = [];
|
|
1154
|
+
let start = 0;
|
|
1155
|
+
let inSingle = false;
|
|
1156
|
+
let inDouble = false;
|
|
1157
|
+
let idx = 0;
|
|
1158
|
+
while (idx < command.length) {
|
|
1159
|
+
const ch = command[idx];
|
|
1160
|
+
const next = idx + 1 < command.length ? command[idx + 1] : undefined;
|
|
1161
|
+
if (ch === "'" && !inDouble) {
|
|
1162
|
+
inSingle = !inSingle;
|
|
1163
|
+
} else if (ch === "\"" && !inSingle && !isEscapedByOddBackslashes(command, idx)) {
|
|
1164
|
+
inDouble = !inDouble;
|
|
1165
|
+
} else if (!inSingle && !inDouble && ((ch === "&" && next === "&") || (ch === "|" && next === "|"))) {
|
|
1166
|
+
pushCommandSegment(segments, command.slice(start, idx));
|
|
1167
|
+
start = idx + 2;
|
|
1168
|
+
idx += 1;
|
|
1169
|
+
} else if (!inSingle && !inDouble && (ch === "\n" || ch === "\r")) {
|
|
1170
|
+
pushCommandSegment(segments, command.slice(start, idx));
|
|
1171
|
+
let nextStart = idx + 1;
|
|
1172
|
+
if (ch === "\r" && next === "\n") {
|
|
1173
|
+
idx += 1;
|
|
1174
|
+
nextStart += 1;
|
|
1175
|
+
}
|
|
1176
|
+
start = nextStart;
|
|
1177
|
+
}
|
|
1178
|
+
idx += 1;
|
|
1179
|
+
}
|
|
1180
|
+
pushCommandSegment(segments, command.slice(start));
|
|
1181
|
+
return segments;
|
|
1182
|
+
}
|
|
1183
|
+
function pushCommandSegment(segments, segment) {
|
|
1184
|
+
const trimmed = segment.trim();
|
|
1185
|
+
if (trimmed.length !== 0) {
|
|
1186
|
+
segments.push(trimmed);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
function stripQuotedText(command) {
|
|
1190
|
+
let stripped = "";
|
|
1191
|
+
let inSingle = false;
|
|
1192
|
+
let inDouble = false;
|
|
1193
|
+
for (let i = 0; i < command.length; i++) {
|
|
1194
|
+
const ch = command[i];
|
|
1195
|
+
if (ch === "'" && !inDouble) {
|
|
1196
|
+
inSingle = !inSingle;
|
|
1197
|
+
stripped += ch;
|
|
1198
|
+
} else if (ch === "\"" && !inSingle && !isEscapedByOddBackslashes(command, i)) {
|
|
1199
|
+
inDouble = !inDouble;
|
|
1200
|
+
stripped += ch;
|
|
1201
|
+
} else if (inSingle) {
|
|
1202
|
+
stripped += " ";
|
|
1203
|
+
} else if (inDouble) {
|
|
1204
|
+
stripped += (ch === "$" || ch === "(" || ch === "`") ? ch : " ";
|
|
1205
|
+
} else {
|
|
1206
|
+
stripped += ch;
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
return stripped;
|
|
1210
|
+
}
|
|
1211
|
+
function isEscapedByOddBackslashes(text, index) {
|
|
1212
|
+
let count = 0;
|
|
1213
|
+
let i = index;
|
|
1214
|
+
while (i > 0) {
|
|
1215
|
+
i -= 1;
|
|
1216
|
+
if (text[i] === "\\") {
|
|
1217
|
+
count += 1;
|
|
1218
|
+
} else {
|
|
1219
|
+
break;
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
return count % 2 === 1;
|
|
1223
|
+
}
|
|
1224
|
+
function isWhitespaceChar(ch) {
|
|
1225
|
+
return /\s/.test(ch);
|
|
1226
|
+
}
|
|
1227
|
+
function startsWithWhitespace(line) {
|
|
1228
|
+
return line.length > 0 && isWhitespaceChar(line[0]);
|
|
1229
|
+
}
|
|
1230
|
+
function stripHeredocBodies(command) {
|
|
1231
|
+
const lines = ( command.split("\n").map(line => stripSuffix(line, "\r") ?? line));
|
|
1232
|
+
const stripped = [];
|
|
1233
|
+
const heredocStdinSegmentIndexes = ( new Set());
|
|
1234
|
+
let i = 0;
|
|
1235
|
+
while (i < lines.length) {
|
|
1236
|
+
const line = lines[i];
|
|
1237
|
+
const heredoc = parseHeredocOpener(line);
|
|
1238
|
+
if (heredoc === undefined) {
|
|
1239
|
+
stripped.push(line);
|
|
1240
|
+
i += 1;
|
|
1241
|
+
continue;
|
|
1242
|
+
}
|
|
1243
|
+
const commandBeforeHeredoc = lastChainSegment(heredoc.prefix);
|
|
1244
|
+
if (regexTest(
|
|
1245
|
+
String.raw`^${pythonExecutablePattern()}\s+-$`,
|
|
1246
|
+
normalizeSegment(commandBeforeHeredoc)
|
|
1247
|
+
)) {
|
|
1248
|
+
let commandThroughHeredocOpener = stripped.join("\n");
|
|
1249
|
+
if (commandThroughHeredocOpener.length !== 0) {
|
|
1250
|
+
commandThroughHeredocOpener += "\n";
|
|
1251
|
+
}
|
|
1252
|
+
commandThroughHeredocOpener += heredoc.prefix;
|
|
1253
|
+
heredocStdinSegmentIndexes.add(saturatingSub(splitCommandSegments(commandThroughHeredocOpener).length, 1));
|
|
1254
|
+
}
|
|
1255
|
+
stripped.push(`${heredoc.prefix} ${heredoc.suffix}`.trimEnd());
|
|
1256
|
+
i += 1;
|
|
1257
|
+
while (i < lines.length && lines[i].trim() !== heredoc.delimiter) {
|
|
1258
|
+
i += 1;
|
|
1259
|
+
}
|
|
1260
|
+
if (i >= lines.length) {
|
|
1261
|
+
return undefined;
|
|
1262
|
+
}
|
|
1263
|
+
i += 1;
|
|
1264
|
+
}
|
|
1265
|
+
return {
|
|
1266
|
+
command: stripped.join("\n"),
|
|
1267
|
+
heredocStdinSegmentIndexes
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
1270
|
+
function parseHeredocOpener(line) {
|
|
1271
|
+
let inSingle = false;
|
|
1272
|
+
let inDouble = false;
|
|
1273
|
+
let index = 0;
|
|
1274
|
+
while (index + 1 < line.length) {
|
|
1275
|
+
const ch = line[index];
|
|
1276
|
+
if (ch === "'" && !inDouble) {
|
|
1277
|
+
inSingle = !inSingle;
|
|
1278
|
+
index += 1;
|
|
1279
|
+
continue;
|
|
1280
|
+
}
|
|
1281
|
+
if (ch === "\"" && !inSingle && !isEscapedByOddBackslashes(line, index)) {
|
|
1282
|
+
inDouble = !inDouble;
|
|
1283
|
+
index += 1;
|
|
1284
|
+
continue;
|
|
1285
|
+
}
|
|
1286
|
+
if (!inSingle && !inDouble && ch === "#" && (index === 0 || isWhitespaceChar(line[index - 1]))) {
|
|
1287
|
+
return undefined;
|
|
1288
|
+
}
|
|
1289
|
+
if (inSingle || inDouble || ch !== "<" || line[index + 1] !== "<") {
|
|
1290
|
+
index += 1;
|
|
1291
|
+
continue;
|
|
1292
|
+
}
|
|
1293
|
+
let cursor = index + 2;
|
|
1294
|
+
if (line[cursor] === "-") {
|
|
1295
|
+
cursor += 1;
|
|
1296
|
+
}
|
|
1297
|
+
while (cursor < line.length && isWhitespaceChar(line[cursor])) {
|
|
1298
|
+
cursor += 1;
|
|
1299
|
+
}
|
|
1300
|
+
let delimiter = "";
|
|
1301
|
+
const quote = cursor < line.length ? line[cursor] : undefined;
|
|
1302
|
+
if (quote === "'" || quote === "\"") {
|
|
1303
|
+
cursor += 1;
|
|
1304
|
+
const start = cursor;
|
|
1305
|
+
while (cursor < line.length && line[cursor] !== quote) {
|
|
1306
|
+
cursor += 1;
|
|
1307
|
+
}
|
|
1308
|
+
if (cursor >= line.length) {
|
|
1309
|
+
return undefined;
|
|
1310
|
+
}
|
|
1311
|
+
delimiter += line.slice(start, cursor);
|
|
1312
|
+
cursor += 1;
|
|
1313
|
+
} else {
|
|
1314
|
+
const start = cursor;
|
|
1315
|
+
while (cursor < line.length && !isWhitespaceChar(line[cursor])) {
|
|
1316
|
+
cursor += 1;
|
|
1317
|
+
}
|
|
1318
|
+
delimiter += line.slice(start, cursor);
|
|
1319
|
+
}
|
|
1320
|
+
if (!regexTest(String.raw`^[A-Za-z_][A-Za-z0-9_]*$`, delimiter)) {
|
|
1321
|
+
return undefined;
|
|
1322
|
+
}
|
|
1323
|
+
return {
|
|
1324
|
+
prefix: line.slice(0, index),
|
|
1325
|
+
suffix: line.slice(cursor),
|
|
1326
|
+
delimiter
|
|
1327
|
+
};
|
|
1328
|
+
}
|
|
1329
|
+
return undefined;
|
|
1330
|
+
}
|
|
1331
|
+
function lastChainSegment(commandPrefix) {
|
|
1332
|
+
const parts = commandPrefix.split(( new RegExp(String.raw`\s*(?:&&|\|\||;)\s*`)));
|
|
1333
|
+
const last = parts.length > 0 ? parts[parts.length - 1] : commandPrefix;
|
|
1334
|
+
return last.trim();
|
|
1335
|
+
}
|
|
1336
|
+
function hasErrexitBeforeFirstCommand(segments, segmentKinds) {
|
|
1337
|
+
let firstNonBenign = segmentKinds.findIndex(kind => !segmentsEqual(kind, BENIGN_SEGMENT));
|
|
1338
|
+
if (firstNonBenign === -1) {
|
|
1339
|
+
firstNonBenign = segmentKinds.length;
|
|
1340
|
+
}
|
|
1341
|
+
return ( segments.slice(0, firstNonBenign).some(segment => isSetECommand(segment)));
|
|
1342
|
+
}
|
|
1343
|
+
function isSetECommand(segment) {
|
|
1344
|
+
const normalized = normalizeSegment(segment);
|
|
1345
|
+
return regexTest(
|
|
1346
|
+
String.raw`^set\s+-(?=[A-Za-z]*e)[A-Za-z]+(?:\s+[-+A-Za-z]+)*$`,
|
|
1347
|
+
normalized
|
|
1348
|
+
) || regexTest(String.raw`\s-o\s+errexit\b`, normalized);
|
|
1349
|
+
}
|
|
1350
|
+
function commandRunsGoTest(command) {
|
|
1351
|
+
return regexTest(String.raw`(?:^|[\s;&|(])go\s+test(?:\s|$)`, stripQuotedText(command));
|
|
1352
|
+
}
|
|
1353
|
+
function commandMentionsSavedToolOutput(command) {
|
|
1354
|
+
return ( splitWhitespace(command).some(token => isSavedToolOutputPath(token)));
|
|
1355
|
+
}
|
|
1356
|
+
function looksLikeNpmPackOutput(output) {
|
|
1357
|
+
return output.includes("npm notice Tarball Contents") && output.includes("npm notice Tarball Details");
|
|
1358
|
+
}
|
|
1359
|
+
function hasDocusaurusProgress(output) {
|
|
1360
|
+
return ( output.split("\n").some(line => regexTest(String.raw`^\s*\u25CF\s+Client\s+`, line))) && ( output.split("\n").some(line => regexTest(String.raw`^\s*[\u25CF\u25EF]\s+Server(?:\s+|$)`, line)));
|
|
1361
|
+
}
|
|
1362
|
+
function hasPassingGoTestOutput(output) {
|
|
1363
|
+
return !hasGoTestFailureOutput(output) && ( output.split("\n").some(line => isGoModuleDownloadChatterLine(line)));
|
|
1364
|
+
}
|
|
1365
|
+
function hasGoTestFailureOutput(output) {
|
|
1366
|
+
return regexTest(
|
|
1367
|
+
String.raw`(?:^|\n)(?:--- FAIL:|FAIL(?:\s|$)|panic:|fatal error:|\s*Error Trace:|\S+\.go:\d+:|# \S+|diff \S+|--- (?!PASS:)|\+\+\+ |@@ |.*\[(?:build|setup) failed\])`,
|
|
1368
|
+
output
|
|
1369
|
+
);
|
|
1370
|
+
}
|
|
1371
|
+
function pythonExecutablePattern() {
|
|
1372
|
+
return String.raw`(?:(?:[A-Za-z0-9_./+-]+/)?(?:python|python3(?:\.\d+)?))`;
|
|
1373
|
+
}
|
|
1374
|
+
function pythonWithOptionsPattern() {
|
|
1375
|
+
return String.raw`${pythonExecutablePattern()}(?:\s+(?:-[BEsStuUvVqQ]|-W\S+|-X\s+\S+))*`;
|
|
1376
|
+
}
|
|
1377
|
+
function compactShellOutput(
|
|
1378
|
+
commandKinds,
|
|
1379
|
+
output,
|
|
1380
|
+
compactGoPassingTestOutput,
|
|
1381
|
+
shellGrepLargeOutputThreshold
|
|
1382
|
+
) {
|
|
1383
|
+
const state = {
|
|
1384
|
+
output,
|
|
1385
|
+
lossless: true
|
|
1386
|
+
};
|
|
1387
|
+
applyStringCompactor(state, compactCarriageReturnProgress);
|
|
1388
|
+
applyStringCompactor(state, compactNeedrestartNoopProgress);
|
|
1389
|
+
applyStringCompactor(state, compactGoRuntimePanicDump);
|
|
1390
|
+
if (compactGoPassingTestOutput && !commandKinds.includes("go")) {
|
|
1391
|
+
applyStringCompactor(state, compactGoOutput);
|
|
1392
|
+
}
|
|
1393
|
+
applyStringCompactor(state, compactJestRunsProgress);
|
|
1394
|
+
applyStringCompactor(state, compactDocusaurusProgress);
|
|
1395
|
+
applyStringCompactor(state, compactSphinxProgressFallback);
|
|
1396
|
+
if (!commandKinds.includes("npm-pack")) {
|
|
1397
|
+
applyStringCompactor(state, compactNpmPackOutput);
|
|
1398
|
+
}
|
|
1399
|
+
for (const kind of COMMAND_COMPACTOR_ORDER.filter(candidate => commandKinds.includes(candidate))) {
|
|
1400
|
+
const result = compactCommandEntry(kind, state.output, shellGrepLargeOutputThreshold);
|
|
1401
|
+
state.output = result.output;
|
|
1402
|
+
state.lossless = state.lossless && result.lossless;
|
|
1403
|
+
}
|
|
1404
|
+
if (state.output === output) {
|
|
1405
|
+
return undefined;
|
|
1406
|
+
}
|
|
1407
|
+
return {
|
|
1408
|
+
output: state.output,
|
|
1409
|
+
lossless: state.lossless
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
function applyStringCompactor(state, compact) {
|
|
1413
|
+
const next = compact(state.output);
|
|
1414
|
+
if (next !== state.output) {
|
|
1415
|
+
state.lossless = false;
|
|
1416
|
+
}
|
|
1417
|
+
state.output = next;
|
|
1418
|
+
}
|
|
1419
|
+
function compactCommandEntry(kind, output, shellGrepLargeOutputThreshold) {
|
|
1420
|
+
if (kind === "shell-grep") {
|
|
1421
|
+
return compactToolOutput("grep-content", output, shellGrepLargeOutputThreshold) ?? unchanged(output);
|
|
1422
|
+
}
|
|
1423
|
+
const original = output;
|
|
1424
|
+
let result;
|
|
1425
|
+
switch (kind) {
|
|
1426
|
+
case "pip":
|
|
1427
|
+
{
|
|
1428
|
+
let next = applyPythonBuildNoise(output);
|
|
1429
|
+
next = compactGitProgress(next);
|
|
1430
|
+
next = compactPackageManagerOperations(next);
|
|
1431
|
+
next = compactPythonNinjaBuildProgress(next);
|
|
1432
|
+
result = compactPipInstallProgress(next);
|
|
1433
|
+
break;
|
|
1434
|
+
}
|
|
1435
|
+
case "python-build":
|
|
1436
|
+
{
|
|
1437
|
+
let next = applyPythonBuildNoise(output);
|
|
1438
|
+
next = compactGitProgress(next);
|
|
1439
|
+
next = compactSetuptoolsFileStagingRuns(next);
|
|
1440
|
+
next = compactPythonNinjaBuildProgress(next);
|
|
1441
|
+
result = compactPipInstallProgress(next);
|
|
1442
|
+
break;
|
|
1443
|
+
}
|
|
1444
|
+
case "pytest":
|
|
1445
|
+
{
|
|
1446
|
+
let next = compactPythonEcosystemNoise(output);
|
|
1447
|
+
next = compactPytestProgress(next);
|
|
1448
|
+
next = compactPytestFailureBlocks(next);
|
|
1449
|
+
next = compactPytestWarningsSummary(next);
|
|
1450
|
+
next = compactPytestSessionMetadata(next);
|
|
1451
|
+
next = compactSphinxProgress(next);
|
|
1452
|
+
result = compactRepeatedDiagnosticBlocks(next);
|
|
1453
|
+
break;
|
|
1454
|
+
}
|
|
1455
|
+
case "python-build-ext":
|
|
1456
|
+
{
|
|
1457
|
+
let next = applyPythonBuildNoise(output);
|
|
1458
|
+
next = compactPythonNinjaBuildProgress(next);
|
|
1459
|
+
next = compactPythonBuildExtProgress(next);
|
|
1460
|
+
next = compactSphinxProgress(next);
|
|
1461
|
+
result = compactRepeatedDiagnosticBlocks(next);
|
|
1462
|
+
break;
|
|
1463
|
+
}
|
|
1464
|
+
case "django-test":
|
|
1465
|
+
{
|
|
1466
|
+
let next = compactPythonEcosystemNoise(output);
|
|
1467
|
+
next = compactDjangoTestBoilerplate(next);
|
|
1468
|
+
next = compactDjangoTestProgress(next);
|
|
1469
|
+
next = compactPytestWarningsSummary(next);
|
|
1470
|
+
next = compactSphinxProgress(next);
|
|
1471
|
+
result = compactRepeatedDiagnosticBlocks(next);
|
|
1472
|
+
break;
|
|
1473
|
+
}
|
|
1474
|
+
case "python-script":
|
|
1475
|
+
{
|
|
1476
|
+
let next = applyPythonBuildNoise(output);
|
|
1477
|
+
next = compactSphinxProgress(next);
|
|
1478
|
+
result = compactRepeatedDiagnosticBlocks(next);
|
|
1479
|
+
break;
|
|
1480
|
+
}
|
|
1481
|
+
case "apt":
|
|
1482
|
+
result = compactAptOutput(output);
|
|
1483
|
+
break;
|
|
1484
|
+
case "npm":
|
|
1485
|
+
result = compactNpmOutput(output);
|
|
1486
|
+
break;
|
|
1487
|
+
case "npm-pack":
|
|
1488
|
+
result = compactNpmPackOutput(output);
|
|
1489
|
+
break;
|
|
1490
|
+
case "yarn-berry":
|
|
1491
|
+
result = compactYarnBerryOutput(output);
|
|
1492
|
+
break;
|
|
1493
|
+
case "pnpm":
|
|
1494
|
+
result = compactPnpmOutput(output);
|
|
1495
|
+
break;
|
|
1496
|
+
case "composer":
|
|
1497
|
+
case "poetry":
|
|
1498
|
+
result = compactPackageManagerOperations(output);
|
|
1499
|
+
break;
|
|
1500
|
+
case "uv":
|
|
1501
|
+
result = compactUvProgress(compactPackageManagerOperations(output));
|
|
1502
|
+
break;
|
|
1503
|
+
case "maven":
|
|
1504
|
+
result = compactMavenOutput(output);
|
|
1505
|
+
break;
|
|
1506
|
+
case "dotnet":
|
|
1507
|
+
result = compactDotnetTimingProgress(output);
|
|
1508
|
+
break;
|
|
1509
|
+
case "go":
|
|
1510
|
+
result = compactGoCommandOutput(output);
|
|
1511
|
+
break;
|
|
1512
|
+
case "unittest":
|
|
1513
|
+
result = compactUnittestOutput(output);
|
|
1514
|
+
break;
|
|
1515
|
+
case "js-test":
|
|
1516
|
+
result = compactJsTestOutput(output);
|
|
1517
|
+
break;
|
|
1518
|
+
case "cargo":
|
|
1519
|
+
result = compactCargoProgress(output);
|
|
1520
|
+
break;
|
|
1521
|
+
case "node":
|
|
1522
|
+
result = compactRepeatedNodeWarnings(output);
|
|
1523
|
+
break;
|
|
1524
|
+
case "git":
|
|
1525
|
+
result = compactGitProgress(output);
|
|
1526
|
+
break;
|
|
1527
|
+
case "git-clean":
|
|
1528
|
+
result = compactGitCleanRemovingRuns(output);
|
|
1529
|
+
break;
|
|
1530
|
+
case "nx":
|
|
1531
|
+
result = compactNxLernaFrameProgress(output);
|
|
1532
|
+
break;
|
|
1533
|
+
case "golangci-lint":
|
|
1534
|
+
result = compactGolangciLintOutput(output, false);
|
|
1535
|
+
break;
|
|
1536
|
+
case "clang-format-linter":
|
|
1537
|
+
result = compactClangFormatLinterOutput(output);
|
|
1538
|
+
break;
|
|
1539
|
+
case "gradle":
|
|
1540
|
+
result = compactGradleOutput(output);
|
|
1541
|
+
break;
|
|
1542
|
+
case "cmake":
|
|
1543
|
+
result = compactCmakeConfigureProbeRuns(output);
|
|
1544
|
+
break;
|
|
1545
|
+
case "make":
|
|
1546
|
+
result = compactMakeOutput(output);
|
|
1547
|
+
break;
|
|
1548
|
+
default:
|
|
1549
|
+
result = output;
|
|
1550
|
+
break;
|
|
1551
|
+
}
|
|
1552
|
+
return stringCompactionResult(original, result);
|
|
1553
|
+
}
|
|
1554
|
+
function stringCompactionResult(original, output) {
|
|
1555
|
+
const lossless = output === original;
|
|
1556
|
+
return {
|
|
1557
|
+
output,
|
|
1558
|
+
lossless
|
|
1559
|
+
};
|
|
1560
|
+
}
|
|
1561
|
+
function applyPythonBuildNoise(output) {
|
|
1562
|
+
let next = compactSetuptoolsDeprecationBlocks(output);
|
|
1563
|
+
next = compactCythonPerformanceHints(next);
|
|
1564
|
+
next = compactCompilerWarningRuns(next);
|
|
1565
|
+
next = compactPythonEcosystemNoise(next);
|
|
1566
|
+
return compactNumpyDistutilsProbes(next);
|
|
1567
|
+
}
|
|
1568
|
+
function compactGoCommandOutput(output) {
|
|
1569
|
+
return compactRepeatedDiagnosticBlocks(compactGoOutput(output));
|
|
1570
|
+
}
|
|
1571
|
+
function compactMavenOutput(output) {
|
|
1572
|
+
return compactMavenInfoBoilerplate(compactMavenPassingTests(compactMavenDependencyTransfer(output)));
|
|
1573
|
+
}
|
|
1574
|
+
function compactPythonEcosystemNoise(output) {
|
|
1575
|
+
return omitNonDiagnosticLines(output, "python ecosystem noise", isPythonEcosystemNoiseLine);
|
|
1576
|
+
}
|
|
1577
|
+
function compactPipInstallProgress(output) {
|
|
1578
|
+
return omitNonDiagnosticLines(output, "pip install progress", isPipInstallProgressLine);
|
|
1579
|
+
}
|
|
1580
|
+
function compactPythonNinjaBuildProgress(output) {
|
|
1581
|
+
return omitNonDiagnosticLines(output, "python ninja build progress", isPythonNinjaBuildProgressLine);
|
|
1582
|
+
}
|
|
1583
|
+
function compactPythonBuildExtProgress(output) {
|
|
1584
|
+
return omitNonDiagnosticLines(output, "python build_ext progress", isPythonBuildExtProgressLine);
|
|
1585
|
+
}
|
|
1586
|
+
function compactSphinxProgressFallback(output) {
|
|
1587
|
+
if (hasSphinxProgress(output)) {
|
|
1588
|
+
return compactSphinxProgress(output);
|
|
1589
|
+
}
|
|
1590
|
+
return output;
|
|
1591
|
+
}
|
|
1592
|
+
function compactPytestSessionMetadata(output) {
|
|
1593
|
+
return omitNonDiagnosticLines(output, "pytest session metadata", isPytestSessionMetadataLine);
|
|
1594
|
+
}
|
|
1595
|
+
function compactDjangoTestBoilerplate(output) {
|
|
1596
|
+
return omitNonDiagnosticLines(output, "django test boilerplate", isDjangoTestBoilerplateLine);
|
|
1597
|
+
}
|
|
1598
|
+
function compactDjangoTestProgress(output) {
|
|
1599
|
+
return omitNonDiagnosticLines(output, "django test progress", isDjangoTestProgressLine);
|
|
1600
|
+
}
|
|
1601
|
+
function compactClangFormatLinterOutput(output) {
|
|
1602
|
+
return omitNonDiagnosticLines(output, "clang-format debug", isClangFormatDebugLine);
|
|
1603
|
+
}
|
|
1604
|
+
function compactDotnetTimingProgress(output) {
|
|
1605
|
+
const compacted = [];
|
|
1606
|
+
const bufferedProgress = [];
|
|
1607
|
+
const timing = {
|
|
1608
|
+
count: 0
|
|
1609
|
+
};
|
|
1610
|
+
for (const line of output.split("\n")) {
|
|
1611
|
+
if (line.trim().length === 0 || isDotnetStandaloneTimingLine(line)) {
|
|
1612
|
+
bufferedProgress.push(line);
|
|
1613
|
+
if (isDotnetStandaloneTimingLine(line)) {
|
|
1614
|
+
timing.count += 1;
|
|
1615
|
+
}
|
|
1616
|
+
continue;
|
|
1617
|
+
}
|
|
1618
|
+
flushDotnetTimingProgress(compacted, bufferedProgress, timing);
|
|
1619
|
+
compacted.push(line);
|
|
1620
|
+
}
|
|
1621
|
+
flushDotnetTimingProgress(compacted, bufferedProgress, timing);
|
|
1622
|
+
return compacted.join("\n");
|
|
1623
|
+
}
|
|
1624
|
+
function flushDotnetTimingProgress(compacted, bufferedProgress, timing) {
|
|
1625
|
+
if (timing.count >= 3) {
|
|
1626
|
+
compacted.push(`[dotnet timing progress: omitted ${timing.count} timing line(s)]`);
|
|
1627
|
+
} else {
|
|
1628
|
+
for (const line of bufferedProgress) {
|
|
1629
|
+
compacted.push(line);
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
bufferedProgress.length = 0;
|
|
1633
|
+
timing.count = 0;
|
|
1634
|
+
}
|
|
1635
|
+
function isDotnetStandaloneTimingLine(line) {
|
|
1636
|
+
return regexTest(String.raw`^\s*\(\d+(?:\.\d+)?s\)\s*$`, line);
|
|
1637
|
+
}
|
|
1638
|
+
function compactGitCleanRemovingRuns(output) {
|
|
1639
|
+
return collapseContiguousRuns(output, isGitCleanRemovingLine, 16, block => {
|
|
1640
|
+
const keptStart = block.slice(0, Math.min(5, block.length));
|
|
1641
|
+
const keptEndStart = saturatingSub(block.length, 5);
|
|
1642
|
+
const keptEnd = block.slice(keptEndStart);
|
|
1643
|
+
const omitted = saturatingSub(block.length, keptStart.length + keptEnd.length);
|
|
1644
|
+
if (omitted === 0) {
|
|
1645
|
+
return undefined;
|
|
1646
|
+
}
|
|
1647
|
+
const lines = [...keptStart];
|
|
1648
|
+
lines.push(`[git clean: omitted ${omitted} Removing line(s)]`);
|
|
1649
|
+
lines.push(...keptEnd);
|
|
1650
|
+
return lines.join("\n");
|
|
1651
|
+
});
|
|
1652
|
+
}
|
|
1653
|
+
function isGitCleanRemovingLine(line) {
|
|
1654
|
+
return regexTest(String.raw`^Removing \S+`, line);
|
|
1655
|
+
}
|
|
1656
|
+
function collapseContiguousRuns(output, isMember, minRun, summarize) {
|
|
1657
|
+
const lines = output.split("\n");
|
|
1658
|
+
const compacted = [];
|
|
1659
|
+
let i = 0;
|
|
1660
|
+
while (i < lines.length) {
|
|
1661
|
+
if (!isMember(lines[i])) {
|
|
1662
|
+
compacted.push(lines[i]);
|
|
1663
|
+
i += 1;
|
|
1664
|
+
continue;
|
|
1665
|
+
}
|
|
1666
|
+
const start = i;
|
|
1667
|
+
while (i < lines.length && isMember(lines[i])) {
|
|
1668
|
+
i += 1;
|
|
1669
|
+
}
|
|
1670
|
+
const block = lines.slice(start, i);
|
|
1671
|
+
const summary = block.length >= minRun ? summarize(block) : undefined;
|
|
1672
|
+
if (summary !== undefined) {
|
|
1673
|
+
compacted.push(summary);
|
|
1674
|
+
} else {
|
|
1675
|
+
compacted.push(...block);
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
return compacted.join("\n");
|
|
1679
|
+
}
|
|
1680
|
+
function collapseRunsWithExamples(output, isMember, example, summarize) {
|
|
1681
|
+
return collapseContiguousRuns(output, isMember, 5, block => {
|
|
1682
|
+
const examples = [];
|
|
1683
|
+
for (const line of block) {
|
|
1684
|
+
const ex = example(line);
|
|
1685
|
+
if (ex !== undefined) {
|
|
1686
|
+
examples.push(ex);
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
if (examples.length !== block.length) {
|
|
1690
|
+
return undefined;
|
|
1691
|
+
}
|
|
1692
|
+
return summarize(block.length, summarizeWithMore(uniqueStrings(examples), 10));
|
|
1693
|
+
});
|
|
1694
|
+
}
|
|
1695
|
+
function compactRepeatedNodeWarnings(output) {
|
|
1696
|
+
const seen = [];
|
|
1697
|
+
return omitMatchingLines(output, "node warnings", line => {
|
|
1698
|
+
const key = getNodeWarningKey(line);
|
|
1699
|
+
if (key === undefined) {
|
|
1700
|
+
return false;
|
|
1701
|
+
}
|
|
1702
|
+
if (seen.includes(key)) {
|
|
1703
|
+
return true;
|
|
1704
|
+
}
|
|
1705
|
+
seen.push(key);
|
|
1706
|
+
return false;
|
|
1707
|
+
}, "repeated warning");
|
|
1708
|
+
}
|
|
1709
|
+
function getNodeWarningKey(line) {
|
|
1710
|
+
if (regexTest(
|
|
1711
|
+
String.raw`^\(node:\d+\) (?:\[[A-Z0-9_-]+\] )?(?:ExperimentalWarning|DeprecationWarning|Warning): `,
|
|
1712
|
+
line
|
|
1713
|
+
)) {
|
|
1714
|
+
return regexReplaceAll(String.raw`^\(node:\d+\)`, line, "(node)");
|
|
1715
|
+
}
|
|
1716
|
+
if (line.startsWith("(Use `node --trace-warnings") || line.startsWith("(Use `node --trace-deprecation")) {
|
|
1717
|
+
return line;
|
|
1718
|
+
}
|
|
1719
|
+
return undefined;
|
|
1720
|
+
}
|
|
1721
|
+
function omitMatchingLines(output, label, shouldOmit, summarySuffix) {
|
|
1722
|
+
const compacted = [];
|
|
1723
|
+
const omitted = {
|
|
1724
|
+
count: 0
|
|
1725
|
+
};
|
|
1726
|
+
for (const line of output.split("\n")) {
|
|
1727
|
+
if (shouldOmit(line)) {
|
|
1728
|
+
omitted.count += 1;
|
|
1729
|
+
} else {
|
|
1730
|
+
flushOmittedLines(compacted, label, omitted, summarySuffix);
|
|
1731
|
+
compacted.push(line);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
flushOmittedLines(compacted, label, omitted, summarySuffix);
|
|
1735
|
+
return compacted.join("\n");
|
|
1736
|
+
}
|
|
1737
|
+
function omitNonDiagnosticLines(output, label, shouldOmit) {
|
|
1738
|
+
return omitMatchingLines(output, label, shouldOmit, "non-diagnostic");
|
|
1739
|
+
}
|
|
1740
|
+
function flushOmittedLines(compacted, label, omitted, summarySuffix) {
|
|
1741
|
+
if (omitted.count > 0) {
|
|
1742
|
+
compacted.push(`[${label}: omitted ${omitted.count} ${summarySuffix} line(s)]`);
|
|
1743
|
+
omitted.count = 0;
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
function compactPackageManagerOperations(output) {
|
|
1747
|
+
if (!hasPackageManagerOperations(output)) {
|
|
1748
|
+
return output;
|
|
1749
|
+
}
|
|
1750
|
+
return collapseRunsWithExamples(
|
|
1751
|
+
output,
|
|
1752
|
+
isPackageManagerOperationLine,
|
|
1753
|
+
packageManagerOperationExample,
|
|
1754
|
+
(len, examples) => `[package operations: omitted ${len} row(s); examples: ${examples}]`
|
|
1755
|
+
);
|
|
1756
|
+
}
|
|
1757
|
+
function hasPackageManagerOperations(output) {
|
|
1758
|
+
const hasMarker = output.includes("Installing dependencies from lock file") || output.includes("Lock file operations:") || output.includes("Package operations:") || output.includes("Writing lock file") || output.includes("Generating autoload files") || output.includes("Lock file is up to date");
|
|
1759
|
+
return hasMarker && ( output.split("\n").some(line => isPackageManagerOperationLine(line)));
|
|
1760
|
+
}
|
|
1761
|
+
function isPackageManagerOperationLine(line) {
|
|
1762
|
+
if (regexTestWithFlags(String.raw`(?:Failed|Error|Exception|Traceback|fatal)`, line, "i")) {
|
|
1763
|
+
return false;
|
|
1764
|
+
}
|
|
1765
|
+
return parsePackageManagerOperation(line) !== undefined;
|
|
1766
|
+
}
|
|
1767
|
+
function packageManagerOperationExample(line) {
|
|
1768
|
+
const parsed = parsePackageManagerOperation(line);
|
|
1769
|
+
if (parsed === undefined) {
|
|
1770
|
+
return undefined;
|
|
1771
|
+
}
|
|
1772
|
+
return parsed.version !== undefined ? `${parsed.pkg} (${parsed.version})` : parsed.pkg;
|
|
1773
|
+
}
|
|
1774
|
+
function parsePackageManagerOperation(line) {
|
|
1775
|
+
const restAfterDash = stripPrefix(line, " - ");
|
|
1776
|
+
if (restAfterDash === undefined) {
|
|
1777
|
+
return undefined;
|
|
1778
|
+
}
|
|
1779
|
+
const operationSplit = splitOnce(restAfterDash, " ");
|
|
1780
|
+
if (operationSplit === undefined) {
|
|
1781
|
+
return undefined;
|
|
1782
|
+
}
|
|
1783
|
+
const operation = operationSplit[0];
|
|
1784
|
+
let rest = operationSplit[1];
|
|
1785
|
+
if (!["Installing", "Locking", "Updating", "Removing", "Downloading"].includes(operation)) {
|
|
1786
|
+
return undefined;
|
|
1787
|
+
}
|
|
1788
|
+
const packageSplit = splitOnce(rest, " ");
|
|
1789
|
+
let pkg;
|
|
1790
|
+
if (packageSplit === undefined) {
|
|
1791
|
+
pkg = rest;
|
|
1792
|
+
rest = "";
|
|
1793
|
+
} else {
|
|
1794
|
+
pkg = packageSplit[0];
|
|
1795
|
+
rest = packageSplit[1];
|
|
1796
|
+
}
|
|
1797
|
+
if (pkg.length === 0) {
|
|
1798
|
+
return undefined;
|
|
1799
|
+
}
|
|
1800
|
+
if (rest.length === 0) {
|
|
1801
|
+
return {
|
|
1802
|
+
operation,
|
|
1803
|
+
pkg,
|
|
1804
|
+
version: undefined
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
const afterOpen = stripPrefix(rest, "(");
|
|
1808
|
+
if (afterOpen !== undefined) {
|
|
1809
|
+
const closeSplit = splitOnce(afterOpen, ")");
|
|
1810
|
+
if (closeSplit !== undefined) {
|
|
1811
|
+
const version = closeSplit[0];
|
|
1812
|
+
const afterClose = closeSplit[1];
|
|
1813
|
+
if (afterClose.length === 0 || afterClose.startsWith(": ")) {
|
|
1814
|
+
return {
|
|
1815
|
+
operation,
|
|
1816
|
+
pkg,
|
|
1817
|
+
version
|
|
1818
|
+
};
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
if (rest.startsWith(": ")) {
|
|
1823
|
+
return {
|
|
1824
|
+
operation,
|
|
1825
|
+
pkg,
|
|
1826
|
+
version: undefined
|
|
1827
|
+
};
|
|
1828
|
+
}
|
|
1829
|
+
return undefined;
|
|
1830
|
+
}
|
|
1831
|
+
function uniqueStrings(items) {
|
|
1832
|
+
const unique = [];
|
|
1833
|
+
for (const item of items) {
|
|
1834
|
+
if (!unique.includes(item)) {
|
|
1835
|
+
unique.push(item);
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
return unique;
|
|
1839
|
+
}
|
|
1840
|
+
function summarizeWithMore(items, maxItems) {
|
|
1841
|
+
const shown = items.slice(0, maxItems);
|
|
1842
|
+
const omitted = saturatingSub(items.length, shown.length);
|
|
1843
|
+
if (omitted > 0) {
|
|
1844
|
+
return `${shown.join(", ")}, ... +${omitted} more`;
|
|
1845
|
+
}
|
|
1846
|
+
return shown.join(", ");
|
|
1847
|
+
}
|
|
1848
|
+
function compactNpmPackOutput(output) {
|
|
1849
|
+
if (!looksLikeNpmPackOutput(output)) {
|
|
1850
|
+
return output;
|
|
1851
|
+
}
|
|
1852
|
+
const compacted = [];
|
|
1853
|
+
let inTarballContents = false;
|
|
1854
|
+
const omittedFileRows = {
|
|
1855
|
+
count: 0
|
|
1856
|
+
};
|
|
1857
|
+
for (const line of output.split("\n")) {
|
|
1858
|
+
const normalizedLine = stripNpmSpinnerPrefix(line);
|
|
1859
|
+
if (normalizedLine === "npm notice Tarball Contents") {
|
|
1860
|
+
inTarballContents = true;
|
|
1861
|
+
compacted.push(line);
|
|
1862
|
+
continue;
|
|
1863
|
+
}
|
|
1864
|
+
if (normalizedLine === "npm notice Tarball Details") {
|
|
1865
|
+
flushNpmPackOmitted(compacted, omittedFileRows);
|
|
1866
|
+
inTarballContents = false;
|
|
1867
|
+
compacted.push(line);
|
|
1868
|
+
continue;
|
|
1869
|
+
}
|
|
1870
|
+
if (inTarballContents && isNpmPackFileListingLine(normalizedLine)) {
|
|
1871
|
+
omittedFileRows.count += 1;
|
|
1872
|
+
continue;
|
|
1873
|
+
}
|
|
1874
|
+
compacted.push(line);
|
|
1875
|
+
}
|
|
1876
|
+
flushNpmPackOmitted(compacted, omittedFileRows);
|
|
1877
|
+
return compacted.join("\n");
|
|
1878
|
+
}
|
|
1879
|
+
function flushNpmPackOmitted(compacted, omittedFileRows) {
|
|
1880
|
+
if (omittedFileRows.count > 0) {
|
|
1881
|
+
compacted.push(
|
|
1882
|
+
`[npm pack tarball contents: omitted ${omittedFileRows.count} file listing line(s)]`
|
|
1883
|
+
);
|
|
1884
|
+
omittedFileRows.count = 0;
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
function isNpmPackFileListingLine(line) {
|
|
1888
|
+
const rest0 = stripPrefix(line, "npm notice ");
|
|
1889
|
+
if (rest0 === undefined) {
|
|
1890
|
+
return false;
|
|
1891
|
+
}
|
|
1892
|
+
let numberEnd = rest0.length;
|
|
1893
|
+
for (let i = 0; i < rest0.length; i++) {
|
|
1894
|
+
const ch = rest0[i];
|
|
1895
|
+
if (!isAsciiDigit(ch) && ch !== ".") {
|
|
1896
|
+
numberEnd = i;
|
|
1897
|
+
break;
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
if (numberEnd === 0 || !isDecimalNumber(rest0.slice(0, numberEnd))) {
|
|
1901
|
+
return false;
|
|
1902
|
+
}
|
|
1903
|
+
const rest = rest0.slice(numberEnd).trimStart();
|
|
1904
|
+
return ( ["B", "kB", "MB", "GB"].some(unit => {
|
|
1905
|
+
const value = stripPrefix(rest, unit);
|
|
1906
|
+
return value !== undefined && value.startsWith(" ");
|
|
1907
|
+
}));
|
|
1908
|
+
}
|
|
1909
|
+
function stripNpmSpinnerPrefix(line) {
|
|
1910
|
+
const trimmed = trimStartMatchesChars(line, ["|", "/", "-"]);
|
|
1911
|
+
if (trimmed.startsWith("npm notice ")) {
|
|
1912
|
+
return trimmed;
|
|
1913
|
+
}
|
|
1914
|
+
return line;
|
|
1915
|
+
}
|
|
1916
|
+
function isDecimalNumber(value) {
|
|
1917
|
+
if (value.length === 0) {
|
|
1918
|
+
return false;
|
|
1919
|
+
}
|
|
1920
|
+
let hasDigit = false;
|
|
1921
|
+
let dotCount = 0;
|
|
1922
|
+
for (const ch of value) {
|
|
1923
|
+
if (isAsciiDigit(ch)) {
|
|
1924
|
+
hasDigit = true;
|
|
1925
|
+
} else if (ch === ".") {
|
|
1926
|
+
dotCount += 1;
|
|
1927
|
+
} else {
|
|
1928
|
+
return false;
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
return dotCount <= 1 && hasDigit;
|
|
1932
|
+
}
|
|
1933
|
+
function compactGoOutput(output) {
|
|
1934
|
+
const compacted = [];
|
|
1935
|
+
const downloadCount = {
|
|
1936
|
+
count: 0
|
|
1937
|
+
};
|
|
1938
|
+
for (const line of output.split("\n")) {
|
|
1939
|
+
if (isGoModuleDownloadChatterLine(line)) {
|
|
1940
|
+
downloadCount.count += 1;
|
|
1941
|
+
} else {
|
|
1942
|
+
flushGoDownloads(compacted, downloadCount);
|
|
1943
|
+
compacted.push(line);
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
flushGoDownloads(compacted, downloadCount);
|
|
1947
|
+
return compacted.join("\n");
|
|
1948
|
+
}
|
|
1949
|
+
function flushGoDownloads(compacted, downloadCount) {
|
|
1950
|
+
if (downloadCount.count > 0) {
|
|
1951
|
+
compacted.push(`[go test: omitted ${downloadCount.count} dependency download line(s)]`);
|
|
1952
|
+
downloadCount.count = 0;
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
function isGoModuleDownloadChatterLine(line) {
|
|
1956
|
+
if (isDiagnosticLine(line)) {
|
|
1957
|
+
return false;
|
|
1958
|
+
}
|
|
1959
|
+
return line.startsWith("go: downloading ") || line.startsWith("go: finding module for package ") || line.startsWith("go: extracting ") || (line.startsWith("go: found ") && line.includes(" in "));
|
|
1960
|
+
}
|
|
1961
|
+
function compactRepeatedDiagnosticBlocks(output) {
|
|
1962
|
+
const lines = output.split("\n");
|
|
1963
|
+
const diagnosticLines = ( lines.map(line => isDiagnosticLine(line)));
|
|
1964
|
+
const compacted = [];
|
|
1965
|
+
let i = 0;
|
|
1966
|
+
while (i < lines.length) {
|
|
1967
|
+
const repeatedBlock = findRepeatedDiagnosticBlock(lines, diagnosticLines, i);
|
|
1968
|
+
if (repeatedBlock === undefined) {
|
|
1969
|
+
compacted.push(lines[i]);
|
|
1970
|
+
i += 1;
|
|
1971
|
+
continue;
|
|
1972
|
+
}
|
|
1973
|
+
compacted.push(...lines.slice(i, i + repeatedBlock.lineCount));
|
|
1974
|
+
compacted.push(
|
|
1975
|
+
`[repeated diagnostic block: previous ${repeatedBlock.lineCount} line(s) repeated ${repeatedBlock.repetitions} more time(s)]`
|
|
1976
|
+
);
|
|
1977
|
+
i += repeatedBlock.lineCount * (repeatedBlock.repetitions + 1);
|
|
1978
|
+
}
|
|
1979
|
+
return compacted.join("\n");
|
|
1980
|
+
}
|
|
1981
|
+
function findRepeatedDiagnosticBlock(lines, diagnosticLines, start) {
|
|
1982
|
+
for (let lineCount = 6; lineCount >= 2; lineCount--) {
|
|
1983
|
+
if (start + lineCount * 2 > lines.length) {
|
|
1984
|
+
continue;
|
|
1985
|
+
}
|
|
1986
|
+
if (!( diagnosticLines.slice(start, start + lineCount).some(isDiagnostic => isDiagnostic))) {
|
|
1987
|
+
continue;
|
|
1988
|
+
}
|
|
1989
|
+
let repetitions = 0;
|
|
1990
|
+
while (start + (repetitions + 2) * lineCount <= lines.length) {
|
|
1991
|
+
const offset = start + (repetitions + 1) * lineCount;
|
|
1992
|
+
if (!arraySliceEqual(lines, start, offset, lineCount)) {
|
|
1993
|
+
break;
|
|
1994
|
+
}
|
|
1995
|
+
repetitions += 1;
|
|
1996
|
+
}
|
|
1997
|
+
if (repetitions > 0) {
|
|
1998
|
+
return {
|
|
1999
|
+
lineCount,
|
|
2000
|
+
repetitions
|
|
2001
|
+
};
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
return undefined;
|
|
2005
|
+
}
|
|
2006
|
+
function isDiagnosticLine(line) {
|
|
2007
|
+
return regexTestWithFlags(
|
|
2008
|
+
String.raw`(?:\u2715|\u2717|\u00D7)|\b(?:error|warning|warn|fatal|failed|failure|traceback|exception|panic|assertion|aborted|abort trap|segmentation fault|core dumped)\b|npm ERR!|^E:|^W:|^FAIL\b`,
|
|
2009
|
+
line,
|
|
2010
|
+
"i"
|
|
2011
|
+
);
|
|
2012
|
+
}
|
|
2013
|
+
function compactCargoProgress(output) {
|
|
2014
|
+
if (!hasCargoProgressOutput(output)) {
|
|
2015
|
+
return output;
|
|
2016
|
+
}
|
|
2017
|
+
return omitMatchingLines(output, "cargo progress", isCargoProgressLine, "progress");
|
|
2018
|
+
}
|
|
2019
|
+
function hasCargoProgressOutput(output) {
|
|
2020
|
+
return !hasCargoFailure(output) && hasCargoTerminalSummary(output) && hasCargoProgressEvidence(output);
|
|
2021
|
+
}
|
|
2022
|
+
function hasCargoProgressEvidence(output) {
|
|
2023
|
+
return ( output.split("\n").some(line => {
|
|
2024
|
+
const trimmed = line.trimStart();
|
|
2025
|
+
return ( CARGO_PROGRESS_PREFIXES.some(prefix => trimmed.startsWith(prefix)));
|
|
2026
|
+
}));
|
|
2027
|
+
}
|
|
2028
|
+
function isCargoProgressLine(line) {
|
|
2029
|
+
if (isDiagnosticLine(line)) {
|
|
2030
|
+
return false;
|
|
2031
|
+
}
|
|
2032
|
+
const trimmed = line.trimStart();
|
|
2033
|
+
return ( CARGO_PROGRESS_PREFIXES.some(prefix => trimmed.startsWith(prefix)));
|
|
2034
|
+
}
|
|
2035
|
+
function hasCargoFailure(output) {
|
|
2036
|
+
return ( output.split("\n").some(line => {
|
|
2037
|
+
const trimmed = line.trimStart();
|
|
2038
|
+
return trimmed.startsWith("error:") || trimmed.startsWith("error[") || trimmed.startsWith("test result: FAILED") || trimmed.startsWith("failures:");
|
|
2039
|
+
}));
|
|
2040
|
+
}
|
|
2041
|
+
function hasCargoTerminalSummary(output) {
|
|
2042
|
+
return ( output.split("\n").some(line => {
|
|
2043
|
+
const trimmed = line.trimStart();
|
|
2044
|
+
return (trimmed.startsWith("Finished ") && trimmed.includes(" target(s) in")) || trimmed.startsWith("test result: ok.");
|
|
2045
|
+
}));
|
|
2046
|
+
}
|
|
2047
|
+
function compactUnittestOutput(output) {
|
|
2048
|
+
if (hasPassingUnittestSummary(output)) {
|
|
2049
|
+
return omitNonDiagnosticLines(output, "unittest progress", isUnittestSuccessProgressLine);
|
|
2050
|
+
}
|
|
2051
|
+
return output;
|
|
2052
|
+
}
|
|
2053
|
+
function hasPassingUnittestSummary(output) {
|
|
2054
|
+
return regexTest(String.raw`(?:^|\n)Ran \d+ tests? in \d+(?:\.\d+)?s\s*(?:\n|$)`, output) && regexTest(String.raw`(?:^|\n)OK(?:\s+\([^)]+\))?\s*(?:\n|$)`, output) && !regexTestWithFlags(
|
|
2055
|
+
String.raw`(?:^|\n)(?:FAILED|ERROR|FAIL):|\b(?:failures?|errors?)=\d*[1-9]\d*`,
|
|
2056
|
+
output,
|
|
2057
|
+
"i"
|
|
2058
|
+
);
|
|
2059
|
+
}
|
|
2060
|
+
function isUnittestSuccessProgressLine(line) {
|
|
2061
|
+
if (isDiagnosticLine(line)) {
|
|
2062
|
+
return false;
|
|
2063
|
+
}
|
|
2064
|
+
const allDashes = [...line].every(ch => ch === "-") && byteLength(line) >= 20;
|
|
2065
|
+
const allProgressChars = line.length > 0 && [...line].every(ch => ".sSxXuUbB".includes(ch));
|
|
2066
|
+
const testLine = regexTest(String.raw`^test_\S+ \([^)]+\) \.\.\. ok$`, line);
|
|
2067
|
+
return allDashes || allProgressChars || testLine;
|
|
2068
|
+
}
|
|
2069
|
+
function isClangFormatDebugLine(line) {
|
|
2070
|
+
return regexTest(String.raw`^<Thread_\d+:DEBUG> (?:\$ .+|took \d+ms)$`, line);
|
|
2071
|
+
}
|
|
2072
|
+
function compactCmakeConfigureProbeRuns(output) {
|
|
2073
|
+
return collapseContiguousRuns(
|
|
2074
|
+
output,
|
|
2075
|
+
isCmakeConfigureProbeLine,
|
|
2076
|
+
8,
|
|
2077
|
+
block => `[cmake configure: omitted ${block.length} status probe line(s)]`
|
|
2078
|
+
);
|
|
2079
|
+
}
|
|
2080
|
+
function isCmakeConfigureProbeLine(line) {
|
|
2081
|
+
if (!line.startsWith("-- ") || regexTest(
|
|
2082
|
+
String.raw`^-- (?:Configuring done|Generating done|Build files have been written to:)`,
|
|
2083
|
+
line
|
|
2084
|
+
)) {
|
|
2085
|
+
return false;
|
|
2086
|
+
}
|
|
2087
|
+
return regexTest(String.raw`^-- Performing Test \S+(?: - Success)?$`, line) || isCmakeLookingForProbeLine(line) || regexTest(String.raw`^-- Detecting .+(?: - done)?$`, line) || regexTest(String.raw`^-- Check(?:ing)? .+(?: - done)?$`, line) || regexTest(
|
|
2088
|
+
String.raw`^-- Check for working \S+ compiler: .+(?: - (?:skipped|works))?$`,
|
|
2089
|
+
line
|
|
2090
|
+
);
|
|
2091
|
+
}
|
|
2092
|
+
function isCmakeLookingForProbeLine(line) {
|
|
2093
|
+
return !line.endsWith(" - not found") && regexTest(String.raw`^-- Looking for .+(?: - found)?$`, line);
|
|
2094
|
+
}
|
|
2095
|
+
function compactMavenDependencyTransfer(output) {
|
|
2096
|
+
if (!hasMavenDependencyTransfer(output)) {
|
|
2097
|
+
return output;
|
|
2098
|
+
}
|
|
2099
|
+
return collapseRunsWithExamples(
|
|
2100
|
+
output,
|
|
2101
|
+
isMavenDependencyTransferLine,
|
|
2102
|
+
mavenDependencyTransferExample,
|
|
2103
|
+
(len, examples) => `[maven dependency transfer: omitted ${len} row(s); examples: ${examples}]`
|
|
2104
|
+
);
|
|
2105
|
+
}
|
|
2106
|
+
function compactMavenPassingTests(output) {
|
|
2107
|
+
if (!hasMavenPassingTests(output)) {
|
|
2108
|
+
return output;
|
|
2109
|
+
}
|
|
2110
|
+
return collapseRunsWithExamples(
|
|
2111
|
+
output,
|
|
2112
|
+
isMavenPassingTestLine,
|
|
2113
|
+
mavenPassingTestExample,
|
|
2114
|
+
(len, examples) => `[maven test summary: omitted ${len} passing class row(s); examples: ${examples}]`
|
|
2115
|
+
);
|
|
2116
|
+
}
|
|
2117
|
+
function compactMavenInfoBoilerplate(output) {
|
|
2118
|
+
if (!hasMavenInfoBoilerplate(output)) {
|
|
2119
|
+
return output;
|
|
2120
|
+
}
|
|
2121
|
+
return omitMatchingLines(output, "maven boilerplate", isMavenInfoBoilerplateLine, "boilerplate");
|
|
2122
|
+
}
|
|
2123
|
+
function hasMavenDependencyTransfer(output) {
|
|
2124
|
+
return isMavenOutput(output) && ( output.split("\n").some(
|
|
2125
|
+
line => line.startsWith("[INFO] Downloading from ") || line.startsWith("[INFO] Downloaded from ")
|
|
2126
|
+
));
|
|
2127
|
+
}
|
|
2128
|
+
function hasMavenPassingTests(output) {
|
|
2129
|
+
return isMavenOutput(output) && ( output.split("\n").some(
|
|
2130
|
+
line => line.startsWith("[INFO] Tests run: ") && line.includes(", Failures: 0, Errors: 0, Skipped: ")
|
|
2131
|
+
));
|
|
2132
|
+
}
|
|
2133
|
+
function hasMavenInfoBoilerplate(output) {
|
|
2134
|
+
return isMavenOutput(output) && ( output.split("\n").some(line => isMavenInfoBoilerplateLine(line)));
|
|
2135
|
+
}
|
|
2136
|
+
function isMavenOutput(output) {
|
|
2137
|
+
return ( output.split("\n").some(
|
|
2138
|
+
line => line.startsWith("[INFO] Scanning for projects...") || line.startsWith("[INFO] BUILD SUCCESS") || line.startsWith("[INFO] BUILD FAILURE") || line.startsWith("[INFO] Reactor Build Order:") || line.startsWith("[INFO] Total time:")
|
|
2139
|
+
));
|
|
2140
|
+
}
|
|
2141
|
+
function isMavenDependencyTransferLine(line) {
|
|
2142
|
+
return regexTest(
|
|
2143
|
+
String.raw`^\[INFO\] (?:Downloading|Downloaded) from \S+: https?://\S+(?: \([^)]+\))?$`,
|
|
2144
|
+
line
|
|
2145
|
+
);
|
|
2146
|
+
}
|
|
2147
|
+
function mavenDependencyTransferExample(line) {
|
|
2148
|
+
const split = rsplitOnce(line, " (");
|
|
2149
|
+
const withoutSize = split !== undefined ? split[0] : line;
|
|
2150
|
+
const parts = withoutSize.split("/");
|
|
2151
|
+
if (parts.length < 3) {
|
|
2152
|
+
return undefined;
|
|
2153
|
+
}
|
|
2154
|
+
const version = parts[parts.length - 2];
|
|
2155
|
+
const name = parts[parts.length - 3];
|
|
2156
|
+
return `${name} ${version}`;
|
|
2157
|
+
}
|
|
2158
|
+
function isMavenPassingTestLine(line) {
|
|
2159
|
+
return regexTest(
|
|
2160
|
+
String.raw`^\[INFO\] Tests run: \d+, Failures: 0, Errors: 0, Skipped: \d+, Time elapsed: \S+\s+s(?:\s+(?:--|-)\s+in\s+\S+)?$`,
|
|
2161
|
+
line
|
|
2162
|
+
);
|
|
2163
|
+
}
|
|
2164
|
+
function mavenPassingTestExample(line) {
|
|
2165
|
+
return regexCaptureFirst(String.raw`\s(?:--|-)\s+in\s+(\S+)$`, line) ?? "summary";
|
|
2166
|
+
}
|
|
2167
|
+
function isMavenInfoBoilerplateLine(line) {
|
|
2168
|
+
const trimmed = line.trimEnd();
|
|
2169
|
+
return trimmed === "[INFO]" || regexTest(String.raw`^\[INFO\] -{20,}\s*$`, trimmed) || regexTest(String.raw`^\[INFO\] -{20,}\[\s*\S+\s*\]-{20,}\s*$`, trimmed) || regexTest(String.raw`^\[INFO\] -{2,}<\s*[^>\n]+\s*>-{2,}\s*$`, trimmed) || regexTest(String.raw`^\[INFO\] Building .+ \[\d+/\d+\]\s*$`, trimmed) || regexTest(
|
|
2170
|
+
String.raw`^\[INFO\] --- \S+(?::\S+)+ (?:\([^)]+\) )?@ \S+ ---\s*$`,
|
|
2171
|
+
trimmed
|
|
2172
|
+
);
|
|
2173
|
+
}
|
|
2174
|
+
function compactGolangciLintOutput(output, requireMarker) {
|
|
2175
|
+
if (requireMarker && !hasGolangciLintMarker(output)) {
|
|
2176
|
+
return output;
|
|
2177
|
+
}
|
|
2178
|
+
return omitNonDiagnosticLines(output, "golangci-lint progress", isGolangciLintOmittableLine);
|
|
2179
|
+
}
|
|
2180
|
+
function hasGolangciLintMarker(output) {
|
|
2181
|
+
return ( output.split("\n").some(line => regexTest(
|
|
2182
|
+
String.raw`^(?:go run github\.com/golangci/golangci-lint/cmd/golangci-lint(?:@\S+)?|(?:[A-Za-z0-9_./+-]+/)?golangci-lint)\s+run\b`,
|
|
2183
|
+
line
|
|
2184
|
+
))) || ((output.includes("level=info") || output.includes("INFO")) && ( output.split("\n").some(line => regexTest(String.raw`^(?:level=info\b|INFO\b)`, line))) && ( output.split("\n").some(line => hasGolangciLintSafeInfoPrefix(line))));
|
|
2185
|
+
}
|
|
2186
|
+
function isGolangciLintOmittableLine(line) {
|
|
2187
|
+
if (isDiagnosticLine(line)) {
|
|
2188
|
+
return false;
|
|
2189
|
+
}
|
|
2190
|
+
return isGoModuleDownloadChatterLine(line) || (regexTest(String.raw`^(?:level=info\b|INFO\b)`, line) && hasGolangciLintSafeInfoPrefix(line));
|
|
2191
|
+
}
|
|
2192
|
+
function hasGolangciLintSafeInfoPrefix(line) {
|
|
2193
|
+
return regexTest(
|
|
2194
|
+
String.raw`\[(?:config_reader|lintersdb|loader|runner|linters_context|filename_unadjuster|uniq_by_line|source_code)\b`,
|
|
2195
|
+
line
|
|
2196
|
+
);
|
|
2197
|
+
}
|
|
2198
|
+
function compactGitProgress(output) {
|
|
2199
|
+
const lines = ( output.split("\n").map(line => compactGitProgressLine(line)));
|
|
2200
|
+
const compacted = [];
|
|
2201
|
+
let i = 0;
|
|
2202
|
+
while (i < lines.length) {
|
|
2203
|
+
const line = lines[i];
|
|
2204
|
+
const progressKey = getGitProgressLineKey(line.output);
|
|
2205
|
+
if (progressKey === undefined) {
|
|
2206
|
+
pushCompactedLine(compacted, line);
|
|
2207
|
+
i += 1;
|
|
2208
|
+
continue;
|
|
2209
|
+
}
|
|
2210
|
+
let j = i + 1;
|
|
2211
|
+
while (j < lines.length && getGitProgressLineKey(lines[j].output) === progressKey) {
|
|
2212
|
+
j += 1;
|
|
2213
|
+
}
|
|
2214
|
+
const omittedLines = j - i - 1;
|
|
2215
|
+
if (omittedLines > 0) {
|
|
2216
|
+
compacted.push(`[git progress: omitted ${omittedLines} earlier ${progressKey} line(s)]`);
|
|
2217
|
+
compacted.push(lines[j - 1].output);
|
|
2218
|
+
} else {
|
|
2219
|
+
pushCompactedLine(compacted, line);
|
|
2220
|
+
}
|
|
2221
|
+
i = j;
|
|
2222
|
+
}
|
|
2223
|
+
return compacted.join("\n");
|
|
2224
|
+
}
|
|
2225
|
+
function unchangedLine(line) {
|
|
2226
|
+
return {
|
|
2227
|
+
output: line,
|
|
2228
|
+
omittedFrames: 0
|
|
2229
|
+
};
|
|
2230
|
+
}
|
|
2231
|
+
function pushCompactedLine(compacted, line) {
|
|
2232
|
+
if (line.omittedFrames > 0) {
|
|
2233
|
+
compacted.push(`[git progress: omitted ${line.omittedFrames} earlier frame(s)]`);
|
|
2234
|
+
}
|
|
2235
|
+
compacted.push(line.output);
|
|
2236
|
+
}
|
|
2237
|
+
function compactGitProgressLine(line) {
|
|
2238
|
+
return compactProgressPatternsUnlessDiagnostic(line, [
|
|
2239
|
+
String.raw`(?:remote: )?(?:Enumerating|Counting|Compressing) objects:\s+\d+%[^)]*\(\d+/\d+\)(?:, done\.)?`,
|
|
2240
|
+
String.raw`(?:remote: )?Receiving objects:\s+\d+%[^)]*\(\d+/\d+\)(?:, [^)]*)?`,
|
|
2241
|
+
String.raw`(?:remote: )?Resolving deltas:\s+\d+%[^)]*\(\d+/\d+\)(?:, done\.)?`,
|
|
2242
|
+
String.raw`(?:remote: )?Writing objects:\s+\d+%[^)]*\(\d+/\d+\)(?:, [^)]*)?`
|
|
2243
|
+
]);
|
|
2244
|
+
}
|
|
2245
|
+
function compactProgressPatternsUnlessDiagnostic(line, patterns) {
|
|
2246
|
+
if (isDiagnosticLine(line)) {
|
|
2247
|
+
return unchangedLine(line);
|
|
2248
|
+
}
|
|
2249
|
+
return compactProgressPatterns(line, patterns);
|
|
2250
|
+
}
|
|
2251
|
+
function compactProgressPatterns(line, patterns) {
|
|
2252
|
+
let output = line;
|
|
2253
|
+
let omittedFrames = 0;
|
|
2254
|
+
for (const pattern of patterns) {
|
|
2255
|
+
const result = compactRepeatedProgressFrames(output, pattern);
|
|
2256
|
+
output = result.output;
|
|
2257
|
+
omittedFrames += result.omittedFrames;
|
|
2258
|
+
}
|
|
2259
|
+
return {
|
|
2260
|
+
output,
|
|
2261
|
+
omittedFrames
|
|
2262
|
+
};
|
|
2263
|
+
}
|
|
2264
|
+
function compactRepeatedProgressFrames(line, pattern) {
|
|
2265
|
+
const matches = regexFindAll(pattern, line);
|
|
2266
|
+
if (matches.length <= 1) {
|
|
2267
|
+
return unchangedLine(line);
|
|
2268
|
+
}
|
|
2269
|
+
const first = matches[0];
|
|
2270
|
+
const last = matches[matches.length - 1];
|
|
2271
|
+
const output = line.slice(0, first.start) + line.slice(last.start, last.end) + line.slice(last.end);
|
|
2272
|
+
return {
|
|
2273
|
+
output,
|
|
2274
|
+
omittedFrames: matches.length - 1
|
|
2275
|
+
};
|
|
2276
|
+
}
|
|
2277
|
+
function getGitProgressLineKey(line) {
|
|
2278
|
+
if (isDiagnosticLine(line)) {
|
|
2279
|
+
return undefined;
|
|
2280
|
+
}
|
|
2281
|
+
const stripped = stripPrefix(line, "remote:");
|
|
2282
|
+
const normalized = stripped !== undefined ? stripped.trimStart() : line;
|
|
2283
|
+
const split = splitOnce(normalized, ":");
|
|
2284
|
+
if (split === undefined) {
|
|
2285
|
+
return undefined;
|
|
2286
|
+
}
|
|
2287
|
+
const key = split[0];
|
|
2288
|
+
const rest = split[1];
|
|
2289
|
+
if (![
|
|
2290
|
+
"Enumerating objects",
|
|
2291
|
+
"Counting objects",
|
|
2292
|
+
"Compressing objects",
|
|
2293
|
+
"Receiving objects",
|
|
2294
|
+
"Writing objects",
|
|
2295
|
+
"Resolving deltas"
|
|
2296
|
+
].includes(key)) {
|
|
2297
|
+
return undefined;
|
|
2298
|
+
}
|
|
2299
|
+
if (regexTest(String.raw`^\s+\d+%`, rest)) {
|
|
2300
|
+
return key;
|
|
2301
|
+
}
|
|
2302
|
+
return undefined;
|
|
2303
|
+
}
|
|
2304
|
+
function compactJsTestOutput(output) {
|
|
2305
|
+
let compacted = compactRepeatedNodeWarnings(output);
|
|
2306
|
+
compacted = compactJestRunsProgress(compacted);
|
|
2307
|
+
if (hasPassingJsTestSummary(compacted)) {
|
|
2308
|
+
compacted = omitNonDiagnosticLines(compacted, "js test progress", isJsTestProgressLine);
|
|
2309
|
+
}
|
|
2310
|
+
return compacted;
|
|
2311
|
+
}
|
|
2312
|
+
function compactJestRunsProgress(output) {
|
|
2313
|
+
if (!hasJestRunsProgress(output)) {
|
|
2314
|
+
return output;
|
|
2315
|
+
}
|
|
2316
|
+
return omitMatchingLines(output, "jest runs progress", isJestRunsProgressLine, "progress");
|
|
2317
|
+
}
|
|
2318
|
+
function hasPassingJsTestSummary(output) {
|
|
2319
|
+
if (regexTest(String.raw`(?:^|\n)\s*(?:FAIL|\u2717|\u00D7|\u2716)\s`, output) || regexTestWithFlags(String.raw`\b[1-9]\d*\s+failed\b`, output, "i") || regexTest(String.raw`(?:^|\n)\s*\d+\s+failing\b`, output) || regexTest(String.raw`(?:^|\n)\s*not\s+ok\s+\d+\b`, output) || regexTest(String.raw`(?:^|\n)#\s+fail\s+[1-9]\d*\b`, output) || regexTest(String.raw`(?:^|\n)\s*Bail out!`, output) || regexTest(String.raw`(?:^|\n).*ERR!`, output)) {
|
|
2320
|
+
return false;
|
|
2321
|
+
}
|
|
2322
|
+
return regexTestWithFlags(
|
|
2323
|
+
String.raw`(?:^|\n)\s*(?:Test Files|Tests?:|Test Suites:)\s+\d+\s+passed\b`,
|
|
2324
|
+
output,
|
|
2325
|
+
"i"
|
|
2326
|
+
) || regexTest(String.raw`(?:^|\n)\s+\d+\s+passing\b`, output) || regexTest(String.raw`(?:^|\n)#\s+ok\b`, output) || regexTest(String.raw`(?:^|\n)#\s+pass\s+[1-9]\d*\b`, output);
|
|
2327
|
+
}
|
|
2328
|
+
function hasJestRunsProgress(output) {
|
|
2329
|
+
return ( output.split("\n").some(line => regexTest(String.raw`^\s*RUNS\s+\S`, line))) && hasJestSummaryMarker(output);
|
|
2330
|
+
}
|
|
2331
|
+
function hasJestSummaryMarker(output) {
|
|
2332
|
+
return ( output.split("\n").some(
|
|
2333
|
+
line => line.startsWith("Test Suites:") || line.startsWith("Tests:") || line.startsWith("Snapshots:") || line.startsWith("Ran all test suites")
|
|
2334
|
+
));
|
|
2335
|
+
}
|
|
2336
|
+
function isJestRunsProgressLine(line) {
|
|
2337
|
+
return regexTest(String.raw`^\s*RUNS\s+\S`, line);
|
|
2338
|
+
}
|
|
2339
|
+
function isJsTestProgressLine(line) {
|
|
2340
|
+
return !isDiagnosticLine(line) && (regexTest(String.raw`^\s*RUN\s+v?\d+\.\d+\.\d+`, line) || regexTest(
|
|
2341
|
+
String.raw`^\s*(?:\u2713|\u2714|\u221A)\s+.+(?:\s+\d+ms|\s+\(\d+(?:ms|s)\))$`,
|
|
2342
|
+
line
|
|
2343
|
+
) || regexTest(String.raw`^\s*PASS\s+.+$`, line) || regexTest(String.raw`^\s*ok\s+\d+\b`, line) || regexTest(String.raw`^[.]+(?:\s+\[\s*\d+%\])?\s*$`, line));
|
|
2344
|
+
}
|
|
2345
|
+
function compactGradleOutput(output) {
|
|
2346
|
+
const compacted = compactIntralineProgress(output, "gradle rich-console progress", compactGradleProgressFrames);
|
|
2347
|
+
return omitNonDiagnosticLines(compacted, "gradle boilerplate", isGradleBoilerplateLine);
|
|
2348
|
+
}
|
|
2349
|
+
function compactIntralineProgress(output, label, compactLine) {
|
|
2350
|
+
let omittedFrames = 0;
|
|
2351
|
+
const compacted = ( output.split("\n").map(line => {
|
|
2352
|
+
const result = compactLine(line);
|
|
2353
|
+
omittedFrames += result.omittedFrames;
|
|
2354
|
+
return result.output;
|
|
2355
|
+
})).join("\n");
|
|
2356
|
+
if (omittedFrames === 0) {
|
|
2357
|
+
return output;
|
|
2358
|
+
}
|
|
2359
|
+
return `[${label}: omitted ${omittedFrames} earlier frame(s)]\n${compacted}`;
|
|
2360
|
+
}
|
|
2361
|
+
function compactGradleProgressFrames(line) {
|
|
2362
|
+
if (isDiagnosticLine(line)) {
|
|
2363
|
+
return unchangedLine(line);
|
|
2364
|
+
}
|
|
2365
|
+
const matches = regexFindAll(
|
|
2366
|
+
String.raw`(?:<[-=]+>|\u2502[^\u2502\n]+\u2502)\s+\d+%\s+(?:INITIALIZING|CONFIGURING|EXECUTING|WAITING)\s+\[[^\]\n]+\]`,
|
|
2367
|
+
line
|
|
2368
|
+
);
|
|
2369
|
+
if (matches.length <= 1) {
|
|
2370
|
+
return unchangedLine(line);
|
|
2371
|
+
}
|
|
2372
|
+
let output = "";
|
|
2373
|
+
let cursor = 0;
|
|
2374
|
+
let omittedFrames = 0;
|
|
2375
|
+
let start = 0;
|
|
2376
|
+
while (start < matches.length) {
|
|
2377
|
+
let end = start;
|
|
2378
|
+
while (end + 1 < matches.length && isGradleProgressFrameSeparator(line, matches[end], matches[end + 1])) {
|
|
2379
|
+
end += 1;
|
|
2380
|
+
}
|
|
2381
|
+
const startRange = matches[start];
|
|
2382
|
+
const endRange = matches[end];
|
|
2383
|
+
if (end > start) {
|
|
2384
|
+
output += line.slice(cursor, startRange.start);
|
|
2385
|
+
output += line.slice(endRange.start, endRange.end);
|
|
2386
|
+
omittedFrames += end - start;
|
|
2387
|
+
} else {
|
|
2388
|
+
output += line.slice(cursor, endRange.end);
|
|
2389
|
+
}
|
|
2390
|
+
cursor = endRange.end;
|
|
2391
|
+
start = end + 1;
|
|
2392
|
+
}
|
|
2393
|
+
output += line.slice(cursor);
|
|
2394
|
+
return {
|
|
2395
|
+
output,
|
|
2396
|
+
omittedFrames
|
|
2397
|
+
};
|
|
2398
|
+
}
|
|
2399
|
+
function isGradleProgressFrameSeparator(line, previous, next) {
|
|
2400
|
+
const separator = line.slice(previous.end, next.start);
|
|
2401
|
+
if (separator.length === 0) {
|
|
2402
|
+
return true;
|
|
2403
|
+
}
|
|
2404
|
+
for (let i = 0; i < separator.length; i += 6) {
|
|
2405
|
+
if (separator.slice(i, i + 6) !== "> IDLE") {
|
|
2406
|
+
return false;
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
return true;
|
|
2410
|
+
}
|
|
2411
|
+
function isGradleBoilerplateLine(line) {
|
|
2412
|
+
return (line.startsWith(
|
|
2413
|
+
"Consider enabling configuration cache to speed up this build: https://docs.gradle.org/"
|
|
2414
|
+
) && line.endsWith("/userguide/configuration_cache_enabling.html")) || line === "> Run with --stacktrace option to get the stack trace." || line === "> Run with --info or --debug option to get more log output." || line === "> Run with --scan to get full insights from a Build Scan (powered by Develocity)." || line === "> Get more help at https://help.gradle.org.";
|
|
2415
|
+
}
|
|
2416
|
+
function compactUvProgress(output) {
|
|
2417
|
+
if (!(hasUvSummaryMarker(output) && ( output.split("\n").some(line => isUvProgressLine(line))))) {
|
|
2418
|
+
return output;
|
|
2419
|
+
}
|
|
2420
|
+
const compacted = collapseContiguousRuns(output, isUvProgressLine, 4, block => {
|
|
2421
|
+
const examples = [];
|
|
2422
|
+
for (const line of block) {
|
|
2423
|
+
const example = uvProgressExample(line);
|
|
2424
|
+
if (example !== undefined) {
|
|
2425
|
+
examples.push(example);
|
|
2426
|
+
}
|
|
2427
|
+
}
|
|
2428
|
+
if (examples.length !== block.length) {
|
|
2429
|
+
return undefined;
|
|
2430
|
+
}
|
|
2431
|
+
const activityList = [];
|
|
2432
|
+
for (const line of block) {
|
|
2433
|
+
const activity = uvProgressActivity(line);
|
|
2434
|
+
if (activity !== undefined) {
|
|
2435
|
+
activityList.push(activity);
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
const activities = uniqueStrings(activityList);
|
|
2439
|
+
const activitySummary = activities.length === 0 ? "" : `; active: ${summarizeWithMore(activities, 5)}`;
|
|
2440
|
+
return `[uv progress: omitted ${block.length} row(s); examples: ${summarizeWithMore(uniqueStrings(examples), 10)}${activitySummary}]`;
|
|
2441
|
+
});
|
|
2442
|
+
return compacted.replace(/\n+$/, "");
|
|
2443
|
+
}
|
|
2444
|
+
function hasUvSummaryMarker(output) {
|
|
2445
|
+
return ( output.split("\n").some(
|
|
2446
|
+
line => (line.startsWith("Using CPython ") && line.includes(" interpreter at:")) || regexTest(
|
|
2447
|
+
String.raw`^(?:Resolved|Prepared|Installed|Audited) \d+ packages? in \S+`,
|
|
2448
|
+
line
|
|
2449
|
+
)
|
|
2450
|
+
));
|
|
2451
|
+
}
|
|
2452
|
+
function isUvProgressLine(line) {
|
|
2453
|
+
const normalized = stripAnsi(line).trim();
|
|
2454
|
+
if (isDiagnosticLine(normalized)) {
|
|
2455
|
+
return false;
|
|
2456
|
+
}
|
|
2457
|
+
return regexTest(
|
|
2458
|
+
String.raw`^[\u2801-\u28FF]\s+(?:Resolving dependencies|Preparing packages|Installing packages|Building|Downloading)\b`,
|
|
2459
|
+
normalized
|
|
2460
|
+
) || regexTest(
|
|
2461
|
+
String.raw`^[A-Za-z0-9_.-]+\s+-{10,}\s+\d+(?:\.\d+)?\s*(?:B|KiB|MiB|GiB|KB|MB|GB)/\d+(?:\.\d+)?\s*(?:B|KiB|MiB|GiB|KB|MB|GB)(?:\s+.+)?$`,
|
|
2462
|
+
normalized
|
|
2463
|
+
);
|
|
2464
|
+
}
|
|
2465
|
+
function uvProgressExample(line) {
|
|
2466
|
+
const normalized = stripAnsi(line).trim();
|
|
2467
|
+
const pkg = regexCaptureFirst(String.raw`^([A-Za-z0-9_.-]+)\s+-{10,}`, normalized);
|
|
2468
|
+
if (pkg !== undefined) {
|
|
2469
|
+
return pkg;
|
|
2470
|
+
}
|
|
2471
|
+
const firstCodePoint = normalized.codePointAt(0);
|
|
2472
|
+
if (firstCodePoint === undefined) {
|
|
2473
|
+
return undefined;
|
|
2474
|
+
}
|
|
2475
|
+
const firstChar = String.fromCodePoint(firstCodePoint);
|
|
2476
|
+
if (!(firstChar >= "⠁" && firstChar <= "⣿")) {
|
|
2477
|
+
return undefined;
|
|
2478
|
+
}
|
|
2479
|
+
const withoutSpinner = normalized.slice(firstChar.length).trimStart();
|
|
2480
|
+
const dotsIndex = withoutSpinner.indexOf("...");
|
|
2481
|
+
const spacesIndex = withoutSpinner.indexOf(" ");
|
|
2482
|
+
const candidates = [dotsIndex, spacesIndex].filter(index => index !== -1);
|
|
2483
|
+
const end = candidates.length > 0 ? Math.min(...candidates) : withoutSpinner.length;
|
|
2484
|
+
return withoutSpinner.slice(0, end).trim();
|
|
2485
|
+
}
|
|
2486
|
+
function uvProgressActivity(line) {
|
|
2487
|
+
return regexCaptureFirst(
|
|
2488
|
+
String.raw`\s{2,}((?:Building|Downloading|Installing) .+)$`,
|
|
2489
|
+
stripAnsi(line).trim()
|
|
2490
|
+
);
|
|
2491
|
+
}
|
|
2492
|
+
function stripAnsi(text) {
|
|
2493
|
+
let output = "";
|
|
2494
|
+
const chars = Array.from(text);
|
|
2495
|
+
let i = 0;
|
|
2496
|
+
while (i < chars.length) {
|
|
2497
|
+
const ch = chars[i];
|
|
2498
|
+
i += 1;
|
|
2499
|
+
if (ch !== "\u001b" || chars[i] !== "[") {
|
|
2500
|
+
output += ch;
|
|
2501
|
+
continue;
|
|
2502
|
+
}
|
|
2503
|
+
i += 1;
|
|
2504
|
+
while (i < chars.length) {
|
|
2505
|
+
const next = chars[i];
|
|
2506
|
+
i += 1;
|
|
2507
|
+
if (next >= "@" && next <= "~") {
|
|
2508
|
+
break;
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
return output;
|
|
2513
|
+
}
|
|
2514
|
+
function compactNxLernaFrameProgress(output) {
|
|
2515
|
+
if (!hasNxLernaFrameProgress(output)) {
|
|
2516
|
+
return output;
|
|
2517
|
+
}
|
|
2518
|
+
const canOmitStaticTaskTable = ( output.split("\n").some(line => regexTest(String.raw`^\s*NX\s+Successfully ran target\b`, line)));
|
|
2519
|
+
const compacted = [];
|
|
2520
|
+
const omitted = {
|
|
2521
|
+
count: 0
|
|
2522
|
+
};
|
|
2523
|
+
for (const line of output.split("\n")) {
|
|
2524
|
+
if (isNxLernaFrameNoiseLine(line, canOmitStaticTaskTable)) {
|
|
2525
|
+
omitted.count += 1;
|
|
2526
|
+
continue;
|
|
2527
|
+
}
|
|
2528
|
+
if (line.trim().length === 0 && omitted.count > 0) {
|
|
2529
|
+
continue;
|
|
2530
|
+
}
|
|
2531
|
+
flushNxLernaOmitted(compacted, omitted);
|
|
2532
|
+
compacted.push(line);
|
|
2533
|
+
}
|
|
2534
|
+
flushNxLernaOmitted(compacted, omitted);
|
|
2535
|
+
return compacted.join("\n");
|
|
2536
|
+
}
|
|
2537
|
+
function flushNxLernaOmitted(compacted, omitted) {
|
|
2538
|
+
if (omitted.count > 0) {
|
|
2539
|
+
compacted.push(`[nx frame progress: omitted ${omitted.count} frame line(s)]`);
|
|
2540
|
+
omitted.count = 0;
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
function isNxLernaFrameNoiseLine(line, canOmitStaticTaskTable) {
|
|
2544
|
+
return regexTest(String.raw`^\u2014{20,}$`, line) || regexTest(
|
|
2545
|
+
String.raw`^\s*(?:NX|Lerna \(powered by Nx\))\s+Running target \S+ for \d+ projects?$`,
|
|
2546
|
+
line
|
|
2547
|
+
) || regexTest(String.raw`^\s*NX\s+Running \d+ \S+ tasks\.\.\.\s+Cache\s+Duration$`, line) || (canOmitStaticTaskTable && regexTest(
|
|
2548
|
+
String.raw`^\s*NX\s+Running \d+ \S+ tasks\.\.\.\s+Cache\s+Duration\s+.+$`,
|
|
2549
|
+
line
|
|
2550
|
+
)) || regexTest(
|
|
2551
|
+
String.raw`^\s+\u2192\s+Executing \d+/\d+ remaining tasks(?: in parallel)?\.\.\.$`,
|
|
2552
|
+
line
|
|
2553
|
+
) || regexTest(
|
|
2554
|
+
String.raw`^\s+[\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F]\s+(?:nx run \S+|@[\w.-]+/[\w.-]+:\S+)$`,
|
|
2555
|
+
line
|
|
2556
|
+
);
|
|
2557
|
+
}
|
|
2558
|
+
function hasNxLernaFrameProgress(output) {
|
|
2559
|
+
return output.includes("NX Running target") || output.includes("Lerna (powered by Nx)") || ( output.split("\n").some(
|
|
2560
|
+
line => regexTest(String.raw`^\s*NX\s+Running \d+ \S+ tasks\.\.\.\s+Cache\s+Duration`, line)
|
|
2561
|
+
));
|
|
2562
|
+
}
|
|
2563
|
+
function compactPnpmOutput(output) {
|
|
2564
|
+
let compacted = compactRepeatedNodeWarnings(output);
|
|
2565
|
+
compacted = compactPackageManagerOperations(compacted);
|
|
2566
|
+
return compactPnpmInstallProgress(compacted);
|
|
2567
|
+
}
|
|
2568
|
+
function compactPnpmInstallProgress(output) {
|
|
2569
|
+
const lines = output.split("\n");
|
|
2570
|
+
const lastProgressIndexes = ( new Map());
|
|
2571
|
+
const lastDownloadIndexes = ( new Map());
|
|
2572
|
+
const lastWarningCounterIndexes = ( new Map());
|
|
2573
|
+
for (let index = 0; index < lines.length; index++) {
|
|
2574
|
+
const line = lines[index];
|
|
2575
|
+
if (isPnpmProgressLine(line)) {
|
|
2576
|
+
lastProgressIndexes.set(pnpmWorkspacePrefix(line), index);
|
|
2577
|
+
}
|
|
2578
|
+
const packageName = pnpmDownloadPackage(line);
|
|
2579
|
+
if (packageName !== undefined) {
|
|
2580
|
+
lastDownloadIndexes.set(packageName, index);
|
|
2581
|
+
}
|
|
2582
|
+
if (isPnpmWarningCounterLine(line)) {
|
|
2583
|
+
lastWarningCounterIndexes.set(pnpmWorkspacePrefix(line), index);
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
const compacted = [];
|
|
2587
|
+
const omittedProgress = {
|
|
2588
|
+
count: 0
|
|
2589
|
+
};
|
|
2590
|
+
const omittedWarningCounters = {
|
|
2591
|
+
count: 0
|
|
2592
|
+
};
|
|
2593
|
+
const omittedDownloads = ( new Map());
|
|
2594
|
+
for (let index = 0; index < lines.length; index++) {
|
|
2595
|
+
const line = lines[index];
|
|
2596
|
+
const packageBarSize = pnpmPackageBarSize(index >= 1 ? lines[index - 1] : undefined, line);
|
|
2597
|
+
if (packageBarSize !== undefined) {
|
|
2598
|
+
compacted.push(`[pnpm install package bar: omitted ${packageBarSize} plus character(s)]`);
|
|
2599
|
+
continue;
|
|
2600
|
+
}
|
|
2601
|
+
const progressPrefix = pnpmWorkspacePrefix(line);
|
|
2602
|
+
if (isPnpmProgressLine(line) && lastProgressIndexes.get(progressPrefix) !== index) {
|
|
2603
|
+
omittedProgress.count += 1;
|
|
2604
|
+
continue;
|
|
2605
|
+
}
|
|
2606
|
+
const packageName = pnpmDownloadPackage(line);
|
|
2607
|
+
if (packageName !== undefined && lastDownloadIndexes.get(packageName) !== index) {
|
|
2608
|
+
omittedDownloads.set(packageName, (omittedDownloads.get(packageName) ?? 0) + 1);
|
|
2609
|
+
continue;
|
|
2610
|
+
}
|
|
2611
|
+
const warningPrefix = pnpmWorkspacePrefix(line);
|
|
2612
|
+
if (isPnpmWarningCounterLine(line) && lastWarningCounterIndexes.get(warningPrefix) !== index) {
|
|
2613
|
+
omittedWarningCounters.count += 1;
|
|
2614
|
+
continue;
|
|
2615
|
+
}
|
|
2616
|
+
if (isPnpmProgressLine(line)) {
|
|
2617
|
+
flushPnpmProgress(compacted, omittedProgress);
|
|
2618
|
+
} else if (packageName !== undefined) {
|
|
2619
|
+
flushPnpmDownload(compacted, omittedDownloads, packageName);
|
|
2620
|
+
} else if (isPnpmWarningCounterLine(line)) {
|
|
2621
|
+
flushPnpmWarningCounters(compacted, omittedWarningCounters);
|
|
2622
|
+
}
|
|
2623
|
+
compacted.push(line);
|
|
2624
|
+
}
|
|
2625
|
+
return compacted.join("\n");
|
|
2626
|
+
}
|
|
2627
|
+
function flushPnpmProgress(compacted, omittedProgress) {
|
|
2628
|
+
if (omittedProgress.count > 0) {
|
|
2629
|
+
compacted.push(
|
|
2630
|
+
`[pnpm install progress: omitted ${omittedProgress.count} earlier progress line(s)]`
|
|
2631
|
+
);
|
|
2632
|
+
omittedProgress.count = 0;
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
function flushPnpmWarningCounters(compacted, omittedWarningCounters) {
|
|
2636
|
+
if (omittedWarningCounters.count > 0) {
|
|
2637
|
+
compacted.push(
|
|
2638
|
+
`[pnpm install warning counter: omitted ${omittedWarningCounters.count} earlier counter line(s)]`
|
|
2639
|
+
);
|
|
2640
|
+
omittedWarningCounters.count = 0;
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
function flushPnpmDownload(compacted, omittedDownloads, packageName) {
|
|
2644
|
+
const omitted = omittedDownloads.get(packageName) ?? 0;
|
|
2645
|
+
omittedDownloads.delete(packageName);
|
|
2646
|
+
if (omitted > 0) {
|
|
2647
|
+
compacted.push(
|
|
2648
|
+
`[pnpm install downloads: omitted ${omitted} earlier frame(s) for ${packageName}]`
|
|
2649
|
+
);
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
function isPnpmProgressLine(line) {
|
|
2653
|
+
const rest = stripPnpmWorkspacePrefix(line);
|
|
2654
|
+
return regexTest(
|
|
2655
|
+
String.raw`^Progress: resolved \d+, reused \d+, downloaded \d+, added \d+(?:, done)?$`,
|
|
2656
|
+
rest
|
|
2657
|
+
);
|
|
2658
|
+
}
|
|
2659
|
+
function pnpmDownloadPackage(line) {
|
|
2660
|
+
const stripped = stripPnpmWorkspacePrefix(line);
|
|
2661
|
+
const rest = stripPrefix(stripped, "Downloading ");
|
|
2662
|
+
if (rest === undefined) {
|
|
2663
|
+
return undefined;
|
|
2664
|
+
}
|
|
2665
|
+
const split = splitOnce(rest, ": ");
|
|
2666
|
+
if (split === undefined) {
|
|
2667
|
+
return undefined;
|
|
2668
|
+
}
|
|
2669
|
+
const [pkg, sizes] = split;
|
|
2670
|
+
if (regexTest(
|
|
2671
|
+
String.raw`^\d+(?:\.\d+)? (?:B|kB|MB|GB)/\d+(?:\.\d+)? (?:B|kB|MB|GB)(?:, done)?$`,
|
|
2672
|
+
sizes
|
|
2673
|
+
)) {
|
|
2674
|
+
return pkg;
|
|
2675
|
+
}
|
|
2676
|
+
return undefined;
|
|
2677
|
+
}
|
|
2678
|
+
function isPnpmWarningCounterLine(line) {
|
|
2679
|
+
return regexTest(String.raw`^\s*WARN\s+\d+ other warnings$`, stripPnpmWorkspacePrefix(line));
|
|
2680
|
+
}
|
|
2681
|
+
function pnpmPackageBarSize(previousLine, line) {
|
|
2682
|
+
if (previousLine === undefined) {
|
|
2683
|
+
return undefined;
|
|
2684
|
+
}
|
|
2685
|
+
const countText = stripPrefix(previousLine, "Packages: +");
|
|
2686
|
+
if (countText === undefined) {
|
|
2687
|
+
return undefined;
|
|
2688
|
+
}
|
|
2689
|
+
const count = parseUsize(countText);
|
|
2690
|
+
if (count === undefined) {
|
|
2691
|
+
return undefined;
|
|
2692
|
+
}
|
|
2693
|
+
if (line.length > 0 && [...line].every(ch => ch === "+") && line.length === count) {
|
|
2694
|
+
return count;
|
|
2695
|
+
}
|
|
2696
|
+
return undefined;
|
|
2697
|
+
}
|
|
2698
|
+
function pnpmWorkspacePrefix(line) {
|
|
2699
|
+
const end = pnpmWorkspacePrefixEnd(line);
|
|
2700
|
+
return end !== undefined ? line.slice(0, end) : "";
|
|
2701
|
+
}
|
|
2702
|
+
function stripPnpmWorkspacePrefix(line) {
|
|
2703
|
+
const end = pnpmWorkspacePrefixEnd(line);
|
|
2704
|
+
return end !== undefined ? line.slice(end) : line;
|
|
2705
|
+
}
|
|
2706
|
+
function pnpmWorkspacePrefixEnd(line) {
|
|
2707
|
+
const index = line.indexOf("|");
|
|
2708
|
+
if (index === -1) {
|
|
2709
|
+
return undefined;
|
|
2710
|
+
}
|
|
2711
|
+
if (index === 0) {
|
|
2712
|
+
return undefined;
|
|
2713
|
+
}
|
|
2714
|
+
let end = index + 1;
|
|
2715
|
+
for (const ch of line.slice(end)) {
|
|
2716
|
+
if (!isWhitespaceChar(ch)) {
|
|
2717
|
+
break;
|
|
2718
|
+
}
|
|
2719
|
+
end += ch.length;
|
|
2720
|
+
}
|
|
2721
|
+
return end;
|
|
2722
|
+
}
|
|
2723
|
+
function compactNpmOutput(output) {
|
|
2724
|
+
let compacted = compactRepeatedNodeWarnings(output);
|
|
2725
|
+
compacted = compactPackageManagerOperations(compacted);
|
|
2726
|
+
compacted = compactIntralineProgress(compacted, "yarn1 install intraline progress", compactYarn1ProgressFrames);
|
|
2727
|
+
return omitNonDiagnosticLines(compacted, "npm install progress", isNpmInstallProgressLine);
|
|
2728
|
+
}
|
|
2729
|
+
function compactYarn1ProgressFrames(line) {
|
|
2730
|
+
return compactProgressPatternsUnlessDiagnostic(line, [String.raw`\[[#-]+\] \d+/\d+`]);
|
|
2731
|
+
}
|
|
2732
|
+
function isNpmInstallProgressLine(line) {
|
|
2733
|
+
if (isDiagnosticLine(line)) {
|
|
2734
|
+
return false;
|
|
2735
|
+
}
|
|
2736
|
+
const lower = asciiLowercase(line);
|
|
2737
|
+
if (regexTest(String.raw`^npm (?:notice|http|timing|info|verb|silly)\b`, lower)) {
|
|
2738
|
+
return true;
|
|
2739
|
+
}
|
|
2740
|
+
if (regexTestWithFlags(
|
|
2741
|
+
String.raw`^(?:reify|idealTree|fetchMetadata|extract|rollbackFailedOptional)[:\s]`,
|
|
2742
|
+
line,
|
|
2743
|
+
"i"
|
|
2744
|
+
)) {
|
|
2745
|
+
return true;
|
|
2746
|
+
}
|
|
2747
|
+
const chars = Array.from(line);
|
|
2748
|
+
const first = chars[0];
|
|
2749
|
+
const second = chars[1];
|
|
2750
|
+
return first !== undefined && first >= "⠁" && first <= "⣿" && second !== undefined && isWhitespaceChar(second);
|
|
2751
|
+
}
|
|
2752
|
+
function compactYarnBerryOutput(output) {
|
|
2753
|
+
let compacted = compactYarnBerryProgress(output);
|
|
2754
|
+
compacted = compactRepeatedNodeWarnings(compacted);
|
|
2755
|
+
compacted = compactPackageManagerOperations(compacted);
|
|
2756
|
+
return compactIntralineProgress(compacted, "yarn1 install intraline progress", compactYarn1ProgressFrames);
|
|
2757
|
+
}
|
|
2758
|
+
function compactYarnBerryProgress(output) {
|
|
2759
|
+
if (!hasYarnBerryCompletedOutput(output)) {
|
|
2760
|
+
return output;
|
|
2761
|
+
}
|
|
2762
|
+
return omitMatchingLines(output, "yarn berry progress", isYarnBerryProgressLine, "progress");
|
|
2763
|
+
}
|
|
2764
|
+
function hasYarnBerryCompletedOutput(output) {
|
|
2765
|
+
return output.includes("➤ YN0000:") && ( output.split("\n").some(
|
|
2766
|
+
line => line.startsWith("➤ YN0000: · Done in ") || line.startsWith("➤ YN0000: · Done with warnings in ")
|
|
2767
|
+
));
|
|
2768
|
+
}
|
|
2769
|
+
function isYarnBerryProgressLine(line) {
|
|
2770
|
+
return line.startsWith("➤ YN0000:") && !line.startsWith("➤ YN0000: · Done in ") && !line.startsWith("➤ YN0000: · Done with warnings in ");
|
|
2771
|
+
}
|
|
2772
|
+
function compactMakeOutput(output) {
|
|
2773
|
+
let compacted = compactIntralineProgress(output, "ninja build intraline progress", compactNinjaProgressFrames);
|
|
2774
|
+
compacted = compactMakeProgress(compacted);
|
|
2775
|
+
compacted = compactGolangciLintOutput(compacted, true);
|
|
2776
|
+
return omitNonDiagnosticLines(compacted, "go module download", isGoModuleDownloadChatterLine);
|
|
2777
|
+
}
|
|
2778
|
+
function compactNinjaProgressFrames(line) {
|
|
2779
|
+
return compactProgressPatternsUnlessDiagnostic(line, [
|
|
2780
|
+
String.raw`\[\s*\d+/\d+\]\s+(?:(?:Building|Linking)\s+(?:C|CXX|CUDA|ASM|OBJC|OBJCXX)\s+(?:object|executable|static library|shared library|module)|Generating|Copying|Processing|Re-running CMake|Scanning dependencies of target|Automatic\s+(?:MOC|UIC|RCC))\b[^[]*`
|
|
2781
|
+
]);
|
|
2782
|
+
}
|
|
2783
|
+
function compactMakeProgress(output) {
|
|
2784
|
+
const lines = output.split("\n");
|
|
2785
|
+
const compacted = [];
|
|
2786
|
+
let i = 0;
|
|
2787
|
+
while (i < lines.length) {
|
|
2788
|
+
const key = getMakeProgressKey(lines[i]);
|
|
2789
|
+
if (key === undefined) {
|
|
2790
|
+
compacted.push(lines[i]);
|
|
2791
|
+
i += 1;
|
|
2792
|
+
continue;
|
|
2793
|
+
}
|
|
2794
|
+
let j = i + 1;
|
|
2795
|
+
while (j < lines.length && getMakeProgressKey(lines[j]) === key) {
|
|
2796
|
+
j += 1;
|
|
2797
|
+
}
|
|
2798
|
+
const count = j - i;
|
|
2799
|
+
if (count >= 4) {
|
|
2800
|
+
compacted.push(lines[i]);
|
|
2801
|
+
compacted.push(`[make progress: omitted ${count - 1} more ${key} line(s)]`);
|
|
2802
|
+
} else {
|
|
2803
|
+
for (let k = i; k < j; k++) {
|
|
2804
|
+
compacted.push(lines[k]);
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
i = j;
|
|
2808
|
+
}
|
|
2809
|
+
return compacted.join("\n");
|
|
2810
|
+
}
|
|
2811
|
+
function getMakeProgressKey(line) {
|
|
2812
|
+
if (isDiagnosticLine(line)) {
|
|
2813
|
+
return undefined;
|
|
2814
|
+
}
|
|
2815
|
+
const trimmed = line.trim();
|
|
2816
|
+
const kind = regexCaptureFirst(String.raw`^\[(Compiling|Linking) .+\]$`, trimmed);
|
|
2817
|
+
if (kind !== undefined) {
|
|
2818
|
+
return asciiLowercase(kind);
|
|
2819
|
+
}
|
|
2820
|
+
const rule = splitMakeRuleLine(trimmed);
|
|
2821
|
+
if (rule !== undefined) {
|
|
2822
|
+
const [ruleName, target] = rule;
|
|
2823
|
+
const suffix = regexCaptureFirst(String.raw`(\.[A-Za-z0-9_.-]+)$`, target) ?? "";
|
|
2824
|
+
return `${ruleName} ${directoryGlob(target, suffix)}`;
|
|
2825
|
+
}
|
|
2826
|
+
const preprocessing = regexCaptureFirst(String.raw`^Preprocessing\s+(.+\.vp)$`, trimmed);
|
|
2827
|
+
if (preprocessing !== undefined) {
|
|
2828
|
+
return `Preprocessing ${directoryGlob(preprocessing, ".vp")}`;
|
|
2829
|
+
}
|
|
2830
|
+
if (regexTest(
|
|
2831
|
+
String.raw`^(?:gcc|g\+\+|cc|c\+\+|clang|clang\+\+|[A-Za-z0-9_-]+-gcc|[A-Za-z0-9_-]+-g\+\+)\b.*\s-c\s`,
|
|
2832
|
+
trimmed
|
|
2833
|
+
)) {
|
|
2834
|
+
return "compile command";
|
|
2835
|
+
}
|
|
2836
|
+
if (regexTest(String.raw`^make(?:\[\d+\])?: (?:Entering|Leaving) directory `, trimmed)) {
|
|
2837
|
+
return "make directory";
|
|
2838
|
+
}
|
|
2839
|
+
return undefined;
|
|
2840
|
+
}
|
|
2841
|
+
function splitMakeRuleLine(line) {
|
|
2842
|
+
const rules = [
|
|
2843
|
+
"HOSTCC",
|
|
2844
|
+
"MKLIB",
|
|
2845
|
+
"MKEXE",
|
|
2846
|
+
"MKDLL",
|
|
2847
|
+
"OCAMLC",
|
|
2848
|
+
"OCAMLOPT",
|
|
2849
|
+
"COQC",
|
|
2850
|
+
"COQDEP",
|
|
2851
|
+
"COQCHK",
|
|
2852
|
+
"COQDOC",
|
|
2853
|
+
"LINK",
|
|
2854
|
+
"CXX",
|
|
2855
|
+
"CPP",
|
|
2856
|
+
"CC",
|
|
2857
|
+
"AR",
|
|
2858
|
+
"AS",
|
|
2859
|
+
"LD",
|
|
2860
|
+
"GEN"
|
|
2861
|
+
];
|
|
2862
|
+
for (const rule of rules) {
|
|
2863
|
+
const target = stripPrefix(line, `${rule} `);
|
|
2864
|
+
if (target !== undefined) {
|
|
2865
|
+
return [rule, target];
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
return undefined;
|
|
2869
|
+
}
|
|
2870
|
+
function directoryGlob(target, suffix) {
|
|
2871
|
+
const slash = target.lastIndexOf("/");
|
|
2872
|
+
if (slash !== -1) {
|
|
2873
|
+
return `${target.slice(0, slash)}/*${suffix}`;
|
|
2874
|
+
}
|
|
2875
|
+
return `*${suffix}`;
|
|
2876
|
+
}
|
|
2877
|
+
function compactAptOutput(output) {
|
|
2878
|
+
let compacted = compactIntralineProgress(output, "apt intraline progress", compactAptProgressFrames);
|
|
2879
|
+
compacted = compactNeedrestartNoopProgress(compacted);
|
|
2880
|
+
compacted = compactPackageManagerOperations(compacted);
|
|
2881
|
+
compacted = compactAptDpkgLifecycleBlocks(compacted);
|
|
2882
|
+
return omitNonDiagnosticLines(compacted, "apt progress", isAptProgressLine);
|
|
2883
|
+
}
|
|
2884
|
+
function compactAptProgressFrames(line) {
|
|
2885
|
+
if (isDiagnosticLine(line)) {
|
|
2886
|
+
return unchangedLine(line);
|
|
2887
|
+
}
|
|
2888
|
+
const result = compactProgressPatterns(line, [
|
|
2889
|
+
String.raw`Reading package lists\.\.\. \d+%`,
|
|
2890
|
+
String.raw`Building dependency tree\.\.\. \d+%`,
|
|
2891
|
+
String.raw`Reading state information\.\.\. \d+%`,
|
|
2892
|
+
String.raw`\(Reading database \.\.\. \d+%`
|
|
2893
|
+
]);
|
|
2894
|
+
const spinnerResult = removeProgressMatches(
|
|
2895
|
+
result.output,
|
|
2896
|
+
String.raw`\d+% \[(?:Working|Waiting for headers|Connecting to [^\]]+|Connected to [^\]]+)\]\s*`
|
|
2897
|
+
);
|
|
2898
|
+
return {
|
|
2899
|
+
output: spinnerResult.output,
|
|
2900
|
+
omittedFrames: result.omittedFrames + spinnerResult.omittedFrames
|
|
2901
|
+
};
|
|
2902
|
+
}
|
|
2903
|
+
function removeProgressMatches(line, pattern) {
|
|
2904
|
+
const matches = regexFindAll(pattern, line);
|
|
2905
|
+
if (matches.length === 0) {
|
|
2906
|
+
return unchangedLine(line);
|
|
2907
|
+
}
|
|
2908
|
+
let output = "";
|
|
2909
|
+
let cursor = 0;
|
|
2910
|
+
for (const match of matches) {
|
|
2911
|
+
output += line.slice(cursor, match.start);
|
|
2912
|
+
cursor = match.end;
|
|
2913
|
+
}
|
|
2914
|
+
output += line.slice(cursor);
|
|
2915
|
+
return {
|
|
2916
|
+
output,
|
|
2917
|
+
omittedFrames: matches.length
|
|
2918
|
+
};
|
|
2919
|
+
}
|
|
2920
|
+
function compactNeedrestartNoopProgress(output) {
|
|
2921
|
+
if (!hasNeedrestartNoopSummary(output) || hasNeedrestartActionableState(output)) {
|
|
2922
|
+
return output;
|
|
2923
|
+
}
|
|
2924
|
+
let omittedFrames = 0;
|
|
2925
|
+
const compacted = ( output.split("\n").map(line => {
|
|
2926
|
+
const result = compactNeedrestartProgressLine(line);
|
|
2927
|
+
omittedFrames += result.omittedFrames;
|
|
2928
|
+
return result.output;
|
|
2929
|
+
})).join("\n");
|
|
2930
|
+
if (omittedFrames > 0) {
|
|
2931
|
+
return `[needrestart progress: omitted ${omittedFrames} no-op scanning frame(s)]\n${compacted}`;
|
|
2932
|
+
}
|
|
2933
|
+
return output;
|
|
2934
|
+
}
|
|
2935
|
+
function hasNeedrestartNoopSummary(output) {
|
|
2936
|
+
return ( output.split("\n").some(isNeedrestartNoopSummaryLine));
|
|
2937
|
+
}
|
|
2938
|
+
function isNeedrestartNoopSummaryLine(line) {
|
|
2939
|
+
switch (line.trim()) {
|
|
2940
|
+
case "Running kernel seems to be up-to-date.":
|
|
2941
|
+
case "The processor microcode seems to be up-to-date.":
|
|
2942
|
+
case "No services need to be restarted.":
|
|
2943
|
+
case "No containers need to be restarted.":
|
|
2944
|
+
case "No user sessions are running outdated binaries.":
|
|
2945
|
+
case "No VM guests are running outdated hypervisor (qemu) binaries on this host.":
|
|
2946
|
+
return true;
|
|
2947
|
+
default:
|
|
2948
|
+
return false;
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
function hasNeedrestartActionableState(output) {
|
|
2952
|
+
return ( output.split("\n").some(line => {
|
|
2953
|
+
const trimmed = line.trim();
|
|
2954
|
+
return !isNeedrestartNoopSummaryLine(trimmed) && regexTestWithFlags(
|
|
2955
|
+
String.raw`\b(?:pending|reboot|required|restart-needed|NEEDRESTART-|Outdated Libraries|Services to be restarted|Containers to be restarted|User sessions running outdated|VM guests are running outdated|need restarting)\b`,
|
|
2956
|
+
trimmed,
|
|
2957
|
+
"i"
|
|
2958
|
+
);
|
|
2959
|
+
}));
|
|
2960
|
+
}
|
|
2961
|
+
function compactNeedrestartProgressLine(line) {
|
|
2962
|
+
if (!line.includes("Scanning ")) {
|
|
2963
|
+
return unchangedLine(line);
|
|
2964
|
+
}
|
|
2965
|
+
const result = removeProgressMatches(
|
|
2966
|
+
line,
|
|
2967
|
+
String.raw`Scanning (?:processes|processor microcode|linux images)\.\.\. \[[^\]\n]*\]\s*`
|
|
2968
|
+
);
|
|
2969
|
+
return {
|
|
2970
|
+
output: result.output.trim().length === 0 ? "[needrestart progress]" : result.output,
|
|
2971
|
+
omittedFrames: result.omittedFrames
|
|
2972
|
+
};
|
|
2973
|
+
}
|
|
2974
|
+
function compactAptDpkgLifecycleBlocks(output) {
|
|
2975
|
+
return collapseContiguousRuns(output, isAptDpkgLifecycleLine, 4, block => {
|
|
2976
|
+
const packages = [];
|
|
2977
|
+
let triggerCount = 0;
|
|
2978
|
+
for (const line of block) {
|
|
2979
|
+
const parsed = parseAptPackageLifecycleLine(line);
|
|
2980
|
+
if (parsed !== undefined) {
|
|
2981
|
+
const [name, version] = parsed;
|
|
2982
|
+
const existing = packages.find(candidate => candidate[0] === name);
|
|
2983
|
+
if (existing !== undefined) {
|
|
2984
|
+
existing[1] = version;
|
|
2985
|
+
} else {
|
|
2986
|
+
packages.push([name, version]);
|
|
2987
|
+
}
|
|
2988
|
+
} else if (line.startsWith("Processing triggers for ")) {
|
|
2989
|
+
triggerCount += 1;
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
if (packages.length === 0) {
|
|
2993
|
+
return undefined;
|
|
2994
|
+
}
|
|
2995
|
+
const packageSummary = summarizePackages(packages);
|
|
2996
|
+
const triggerSummary = triggerCount > 0 ? `; ${triggerCount} trigger line(s)` : "";
|
|
2997
|
+
return `[apt packages: installed ${packages.length} package(s): ${packageSummary}; omitted ${block.length} dpkg lifecycle line(s)${triggerSummary}]`;
|
|
2998
|
+
});
|
|
2999
|
+
}
|
|
3000
|
+
function isAptDpkgLifecycleLine(line) {
|
|
3001
|
+
return !isDiagnosticLine(line) && (line.startsWith("Selecting previously unselected package ") || line.startsWith("Preparing to unpack ") || line.startsWith("Unpacking ") || line.startsWith("Setting up ") || line.startsWith("Processing triggers for ") || regexTest(String.raw`^running python (?:pre-|post-)?rtupdate hooks for `, line) || regexTest(
|
|
3002
|
+
String.raw`^\(Reading database \.\.\. \d+ files and directories currently installed\.\)$`,
|
|
3003
|
+
line
|
|
3004
|
+
));
|
|
3005
|
+
}
|
|
3006
|
+
function parseAptPackageLifecycleLine(line) {
|
|
3007
|
+
const selecting = stripPrefix(line, "Selecting previously unselected package ");
|
|
3008
|
+
if (selecting !== undefined) {
|
|
3009
|
+
const name = stripSuffix(selecting, ".");
|
|
3010
|
+
if (name !== undefined) {
|
|
3011
|
+
return [name, undefined];
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
const unpackingOrSetting = stripPrefix(line, "Unpacking ") ?? stripPrefix(line, "Setting up ");
|
|
3015
|
+
if (unpackingOrSetting !== undefined) {
|
|
3016
|
+
const nameSplit = splitOnce(unpackingOrSetting, " (");
|
|
3017
|
+
if (nameSplit !== undefined) {
|
|
3018
|
+
const versionSplit = splitOnce(nameSplit[1], ")");
|
|
3019
|
+
if (versionSplit !== undefined) {
|
|
3020
|
+
return [nameSplit[0], versionSplit[0]];
|
|
3021
|
+
}
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
3024
|
+
const preparing = stripPrefix(line, "Preparing to unpack ");
|
|
3025
|
+
if (preparing !== undefined) {
|
|
3026
|
+
const debSplit = splitOnce(preparing, " ");
|
|
3027
|
+
if (debSplit !== undefined) {
|
|
3028
|
+
const debSegments = debSplit[0].split("/");
|
|
3029
|
+
const fileName = debSegments[debSegments.length - 1];
|
|
3030
|
+
const nameSplit = splitOnce(fileName, "_");
|
|
3031
|
+
if (nameSplit !== undefined) {
|
|
3032
|
+
const versionSplit = rsplitOnce(nameSplit[1], "_");
|
|
3033
|
+
if (versionSplit !== undefined) {
|
|
3034
|
+
return [nameSplit[0], versionSplit[0]];
|
|
3035
|
+
}
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
}
|
|
3039
|
+
return undefined;
|
|
3040
|
+
}
|
|
3041
|
+
function summarizePackages(packages) {
|
|
3042
|
+
return summarizeWithMore(( packages.map(([name, version]) => version !== undefined ? `${name} (${version})` : name)), 18);
|
|
3043
|
+
}
|
|
3044
|
+
function isAptProgressLine(line) {
|
|
3045
|
+
return !isDiagnosticLine(line) && (regexTest(String.raw`^\d+% \[`, line) || regexTest(String.raw`\b(?:Hit|Get|Ign):\d+ `, line) || line.includes("Reading package lists...") || line.includes("Building dependency tree...") || line.includes("Reading state information...") || line.startsWith("Selecting previously unselected package ") || line.startsWith("Preparing to unpack ") || line.startsWith("Unpacking ") || line.startsWith("Setting up ") || line.startsWith("Processing triggers for ") || line.startsWith("Fetched ") || line.startsWith("Need to get ") || line.startsWith("After this operation ") || line.startsWith("debconf: ") || line.startsWith("(Reading database "));
|
|
3046
|
+
}
|
|
3047
|
+
function isPythonEcosystemNoiseLine(line) {
|
|
3048
|
+
return line.startsWith(`WARNING: Running pip as the 'root' user can result in broken permissions`) || line.startsWith("It is recommended to use a virtual environment instead: ") || line.includes("DeprecationWarning: The distutils package is deprecated") || line.includes("SetuptoolsDeprecationWarning:") || line.includes("`numpy.distutils` is deprecated since NumPy 1.23.0") || line.startsWith("Partial import of sklearn during the build process.") || line.startsWith("Matplotlib is not built with the correct FreeType version");
|
|
3049
|
+
}
|
|
3050
|
+
function compactSetuptoolsDeprecationBlocks(output) {
|
|
3051
|
+
if (!output.includes("SetuptoolsDeprecationWarning") && !output.includes("EasyInstallDeprecationWarning") && !output.includes("DeprecationWarning:")) {
|
|
3052
|
+
return output;
|
|
3053
|
+
}
|
|
3054
|
+
const lines = output.split("\n");
|
|
3055
|
+
const compacted = [];
|
|
3056
|
+
let i = 0;
|
|
3057
|
+
while (i < lines.length) {
|
|
3058
|
+
if (!isSetuptoolsDeprecationHeader(lines[i])) {
|
|
3059
|
+
compacted.push(lines[i]);
|
|
3060
|
+
i += 1;
|
|
3061
|
+
continue;
|
|
3062
|
+
}
|
|
3063
|
+
const start = i;
|
|
3064
|
+
i += 1;
|
|
3065
|
+
let seenSentinel = false;
|
|
3066
|
+
while (i < lines.length && i - start < 30) {
|
|
3067
|
+
const line = lines[i];
|
|
3068
|
+
if (isStrictCompilerDiagnosticLine(line) || isUnsafeCompactionContextLine(line)) {
|
|
3069
|
+
break;
|
|
3070
|
+
}
|
|
3071
|
+
if (regexTest(String.raw`^\s*!!\s*$`, line)) {
|
|
3072
|
+
if (seenSentinel) {
|
|
3073
|
+
i += 1;
|
|
3074
|
+
break;
|
|
3075
|
+
}
|
|
3076
|
+
seenSentinel = true;
|
|
3077
|
+
i += 1;
|
|
3078
|
+
continue;
|
|
3079
|
+
}
|
|
3080
|
+
if (line.trim().length === 0 && i + 1 < lines.length && regexTest(String.raw`^\S`, lines[i + 1]) && !isSetuptoolsBannerLine(lines[i + 1])) {
|
|
3081
|
+
break;
|
|
3082
|
+
}
|
|
3083
|
+
if (!isSetuptoolsBannerLine(line) && regexTest(String.raw`^\S`, line)) {
|
|
3084
|
+
break;
|
|
3085
|
+
}
|
|
3086
|
+
i += 1;
|
|
3087
|
+
}
|
|
3088
|
+
const block = lines.slice(start, i);
|
|
3089
|
+
if (block.length >= 3 && !( block.slice(1).some(line => isUnsafeCompactionContextLine(line)))) {
|
|
3090
|
+
compacted.push(
|
|
3091
|
+
`[setuptools deprecation: ${setuptoolsWarningName(block[0])}; omitted ${block.length - 1} banner line(s)]`
|
|
3092
|
+
);
|
|
3093
|
+
} else {
|
|
3094
|
+
for (const line of block) {
|
|
3095
|
+
compacted.push(line);
|
|
3096
|
+
}
|
|
3097
|
+
}
|
|
3098
|
+
}
|
|
3099
|
+
return compacted.join("\n");
|
|
3100
|
+
}
|
|
3101
|
+
function isSetuptoolsDeprecationHeader(line) {
|
|
3102
|
+
return line.includes("SetuptoolsDeprecationWarning:") || line.includes("EasyInstallDeprecationWarning:") || line.includes("DeprecationWarning:");
|
|
3103
|
+
}
|
|
3104
|
+
function setuptoolsWarningName(line) {
|
|
3105
|
+
return regexCaptureFirst(
|
|
3106
|
+
String.raw`([A-Za-z_][A-Za-z0-9_]*DeprecationWarning|DeprecationWarning):`,
|
|
3107
|
+
line
|
|
3108
|
+
) ?? "deprecation warning";
|
|
3109
|
+
}
|
|
3110
|
+
function isSetuptoolsBannerLine(line) {
|
|
3111
|
+
return line.trim().length === 0 || startsWithWhitespace(line) || regexTest(String.raw`^\s*[-!*]{3,}\s*$`, line) || isSetuptoolsDeprecationHeader(line);
|
|
3112
|
+
}
|
|
3113
|
+
function compactCythonPerformanceHints(output) {
|
|
3114
|
+
if (!output.includes("performance hint:")) {
|
|
3115
|
+
return output;
|
|
3116
|
+
}
|
|
3117
|
+
const lines = output.split("\n");
|
|
3118
|
+
const compacted = [];
|
|
3119
|
+
let omitted = 0;
|
|
3120
|
+
let keptFirstInRun = false;
|
|
3121
|
+
const flush = () => {
|
|
3122
|
+
if (omitted > 0) {
|
|
3123
|
+
compacted.push(`[cython performance hints: omitted ${omitted} hint block(s)]`);
|
|
3124
|
+
omitted = 0;
|
|
3125
|
+
}
|
|
3126
|
+
keptFirstInRun = false;
|
|
3127
|
+
};
|
|
3128
|
+
let i = 0;
|
|
3129
|
+
while (i < lines.length) {
|
|
3130
|
+
if (!isCythonPerformanceHintHeader(lines[i])) {
|
|
3131
|
+
flush();
|
|
3132
|
+
compacted.push(lines[i]);
|
|
3133
|
+
i += 1;
|
|
3134
|
+
continue;
|
|
3135
|
+
}
|
|
3136
|
+
const start = i;
|
|
3137
|
+
i += 1;
|
|
3138
|
+
let hasUnsafeContext = false;
|
|
3139
|
+
while (i < lines.length && i - start < 12) {
|
|
3140
|
+
const line = lines[i];
|
|
3141
|
+
if (isCythonPerformanceHintHeader(line) || isStrictCompilerDiagnosticLine(line) || isUnsafeCompactionContextLine(line)) {
|
|
3142
|
+
hasUnsafeContext = isUnsafeCompactionContextLine(line);
|
|
3143
|
+
if (hasUnsafeContext) {
|
|
3144
|
+
i += 1;
|
|
3145
|
+
}
|
|
3146
|
+
break;
|
|
3147
|
+
}
|
|
3148
|
+
if (line.trim().length === 0 && i + 1 < lines.length && !startsWithWhitespace(lines[i + 1])) {
|
|
3149
|
+
i += 1;
|
|
3150
|
+
break;
|
|
3151
|
+
}
|
|
3152
|
+
if (!startsWithWhitespace(line) && !line.startsWith("Possible solutions:")) {
|
|
3153
|
+
break;
|
|
3154
|
+
}
|
|
3155
|
+
i += 1;
|
|
3156
|
+
}
|
|
3157
|
+
const block = lines.slice(start, i);
|
|
3158
|
+
if (hasUnsafeContext) {
|
|
3159
|
+
flush();
|
|
3160
|
+
for (const line of block) {
|
|
3161
|
+
compacted.push(line);
|
|
3162
|
+
}
|
|
3163
|
+
} else if (!keptFirstInRun) {
|
|
3164
|
+
for (const line of block) {
|
|
3165
|
+
compacted.push(line);
|
|
3166
|
+
}
|
|
3167
|
+
keptFirstInRun = true;
|
|
3168
|
+
} else {
|
|
3169
|
+
omitted += 1;
|
|
3170
|
+
}
|
|
3171
|
+
}
|
|
3172
|
+
flush();
|
|
3173
|
+
return compacted.join("\n");
|
|
3174
|
+
}
|
|
3175
|
+
function isCythonPerformanceHintHeader(line) {
|
|
3176
|
+
return regexTest(String.raw`^\S+\.pyx:\d+:\d+:\s+performance hint: `, line);
|
|
3177
|
+
}
|
|
3178
|
+
function compactCompilerWarningRuns(output) {
|
|
3179
|
+
if (!regexTest(
|
|
3180
|
+
String.raw`(?:^|\n)(?:\S+:\d+(?::\d+)?:\s*(?:warning|(?:fatal\s+)?error):|\S+:\s*internal compiler error:|error: command .+ failed\b)`,
|
|
3181
|
+
output
|
|
3182
|
+
)) {
|
|
3183
|
+
return output;
|
|
3184
|
+
}
|
|
3185
|
+
const inputErrorCount = countCompilerErrorLines(output);
|
|
3186
|
+
const lines = output.split("\n");
|
|
3187
|
+
const compacted = [];
|
|
3188
|
+
let i = 0;
|
|
3189
|
+
while (i < lines.length) {
|
|
3190
|
+
const run = collectCompilerDiagnosticRun(lines, i);
|
|
3191
|
+
if (run === undefined) {
|
|
3192
|
+
compacted.push(lines[i]);
|
|
3193
|
+
i += 1;
|
|
3194
|
+
continue;
|
|
3195
|
+
}
|
|
3196
|
+
if (run.blocks.length < 4) {
|
|
3197
|
+
compacted.push(lines[i]);
|
|
3198
|
+
i += 1;
|
|
3199
|
+
continue;
|
|
3200
|
+
}
|
|
3201
|
+
if (run.hasError) {
|
|
3202
|
+
for (let k = i; k < run.end; k++) {
|
|
3203
|
+
compacted.push(lines[k]);
|
|
3204
|
+
}
|
|
3205
|
+
i = run.end;
|
|
3206
|
+
continue;
|
|
3207
|
+
}
|
|
3208
|
+
for (const block of run.blocks.slice(0, 2)) {
|
|
3209
|
+
compacted.push(...block.lines);
|
|
3210
|
+
}
|
|
3211
|
+
compacted.push(`[compiler warnings: omitted ${run.blocks.length - 3} warning block(s)]`);
|
|
3212
|
+
compacted.push(...run.blocks[run.blocks.length - 1].lines);
|
|
3213
|
+
i = run.end;
|
|
3214
|
+
}
|
|
3215
|
+
const compactedOutput = compacted.join("\n");
|
|
3216
|
+
if (countCompilerErrorLines(compactedOutput) === inputErrorCount) {
|
|
3217
|
+
return compactedOutput;
|
|
3218
|
+
}
|
|
3219
|
+
return output;
|
|
3220
|
+
}
|
|
3221
|
+
function collectCompilerDiagnosticRun(lines, start) {
|
|
3222
|
+
const blocks = [];
|
|
3223
|
+
let i = start;
|
|
3224
|
+
let hasError = false;
|
|
3225
|
+
while (i < lines.length) {
|
|
3226
|
+
const kind = compilerDiagnosticKind(lines[i]);
|
|
3227
|
+
if (kind === undefined) {
|
|
3228
|
+
break;
|
|
3229
|
+
}
|
|
3230
|
+
const blockStart = i;
|
|
3231
|
+
i += 1;
|
|
3232
|
+
let contextLines = 0;
|
|
3233
|
+
while (i < lines.length && contextLines < 4 && compilerDiagnosticKind(lines[i]) === undefined && lines[i].trim().length !== 0) {
|
|
3234
|
+
if (isDiagnosticLine(lines[i]) || isCompilerContextErrorLine(lines[i])) {
|
|
3235
|
+
hasError = true;
|
|
3236
|
+
break;
|
|
3237
|
+
}
|
|
3238
|
+
i += 1;
|
|
3239
|
+
contextLines += 1;
|
|
3240
|
+
}
|
|
3241
|
+
blocks.push({
|
|
3242
|
+
lines: lines.slice(blockStart, i),
|
|
3243
|
+
kind
|
|
3244
|
+
});
|
|
3245
|
+
hasError = hasError || kind === "error";
|
|
3246
|
+
if (i < lines.length && lines[i].trim().length === 0) {
|
|
3247
|
+
break;
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
if (blocks.length === 0) {
|
|
3251
|
+
return undefined;
|
|
3252
|
+
}
|
|
3253
|
+
return {
|
|
3254
|
+
blocks,
|
|
3255
|
+
end: i,
|
|
3256
|
+
hasError
|
|
3257
|
+
};
|
|
3258
|
+
}
|
|
3259
|
+
function compilerDiagnosticKind(line) {
|
|
3260
|
+
if (isCompilerErrorLine(line)) {
|
|
3261
|
+
return "error";
|
|
3262
|
+
}
|
|
3263
|
+
if (regexTest(String.raw`^\S+:\d+(?::\d+)?:\s*warning:\s`, line)) {
|
|
3264
|
+
return "warning";
|
|
3265
|
+
}
|
|
3266
|
+
return undefined;
|
|
3267
|
+
}
|
|
3268
|
+
function isStrictCompilerDiagnosticLine(line) {
|
|
3269
|
+
return compilerDiagnosticKind(line) !== undefined || regexTest(String.raw`^\S+:\d+(?::\d+)?:\s*note:\s`, line);
|
|
3270
|
+
}
|
|
3271
|
+
function isCompilerErrorLine(line) {
|
|
3272
|
+
return regexTest(String.raw`^\S+:\d+(?::\d+)?:\s*(?:fatal\s+)?error:\s`, line) || regexTest(String.raw`^\S+:\s*internal compiler error:\s`, line) || regexTest(String.raw`^error: command .+ failed\b`, line);
|
|
3273
|
+
}
|
|
3274
|
+
function isCompilerContextErrorLine(line) {
|
|
3275
|
+
return regexTestWithFlags(String.raw`^(?:fatal error|error):\s`, line, "i") || line.startsWith("Traceback (most recent call last):");
|
|
3276
|
+
}
|
|
3277
|
+
function isUnsafeCompactionContextLine(line) {
|
|
3278
|
+
return isCompilerContextErrorLine(line.trimStart());
|
|
3279
|
+
}
|
|
3280
|
+
function countCompilerErrorLines(output) {
|
|
3281
|
+
return output.split("\n").filter(line => isCompilerErrorLine(line) || isUnsafeCompactionContextLine(line)).length;
|
|
3282
|
+
}
|
|
3283
|
+
function isPipInstallProgressLine(line) {
|
|
3284
|
+
return isPipRootUserWarning(line) || (!isDiagnosticLine(line) && (line.startsWith("Looking in indexes: ") || line.startsWith("Looking in links: ") || line.startsWith("Collecting ") || line.startsWith("Requirement already satisfied: ") || line.startsWith("Discarding http://") || line.startsWith("Discarding https://") || line.startsWith("Downloading http://") || line.startsWith("Downloading https://") || line.startsWith(" Downloading ") || line.startsWith(" Using cached ") || line.startsWith(" Getting requirements to build wheel ") || line.startsWith(" Installing build dependencies ") || line.startsWith(" Preparing metadata ") || line.startsWith("Building wheels for collected packages: ") || line.startsWith(" Building wheel for ") || line.startsWith(" Created wheel for ") || line.startsWith(" Stored in directory: ") || line.startsWith("Installing collected packages: ") || line.startsWith("Successfully installed ") || line.startsWith("Obtaining ") || line.startsWith("[notice] A new release of pip is available: ") || line.startsWith("[notice] To update, run: ") || regexTest(
|
|
3285
|
+
String.raw`^\s+[\u2501\u2578\u257A ]*[\u2501\u2578\u257A][\u2501\u2578\u257A ]*\d+(?:\.\d+)?(?:\s*[KMG]?B)?[/ ]`,
|
|
3286
|
+
line
|
|
3287
|
+
)));
|
|
3288
|
+
}
|
|
3289
|
+
function isPipRootUserWarning(line) {
|
|
3290
|
+
return line.startsWith(`WARNING: Running pip as the 'root' user can result in broken permissions`) || line.startsWith("It is recommended to use a virtual environment instead: ");
|
|
3291
|
+
}
|
|
3292
|
+
function isPythonNinjaBuildProgressLine(line) {
|
|
3293
|
+
return regexTest(
|
|
3294
|
+
String.raw`^\[\s*\d+/\d+\]\s+Compiling (?:C|C\+\+|Cython) source \S+\.(?:c|cc|cpp|cxx|pyx)$`,
|
|
3295
|
+
line
|
|
3296
|
+
) || regexTest(String.raw`^\[\s*\d+/\d+\]\s+Generating \S+ with a custom command$`, line);
|
|
3297
|
+
}
|
|
3298
|
+
function isPythonBuildExtProgressLine(line) {
|
|
3299
|
+
return !isDiagnosticLine(line) && (regexTest(
|
|
3300
|
+
String.raw`^running (?:bdist_wheel|build|build_py|build_ext|egg_info|install(?:_lib|_egg_info|_scripts|_headers)?|sdist|check)\b`,
|
|
3301
|
+
line
|
|
3302
|
+
) || regexTest(String.raw`^building '.+' extension$`, line) || line.startsWith("creating build") || line.startsWith("compile options: ") || line.startsWith("extra options: ") || regexTest(String.raw`^copying .+ -> `, line) || regexTest(String.raw`^writing .+\.egg-info/`, line) || line.startsWith("reading manifest file ") || regexTest(
|
|
3303
|
+
String.raw`^(?:gcc|g\+\+|cc|c\+\+|clang|clang\+\+)\b.*\s(?:-c|-shared)\s`,
|
|
3304
|
+
line
|
|
3305
|
+
) || regexTest(
|
|
3306
|
+
String.raw`^Compiling \S+\.pyx because (?:it changed|it depends on )`,
|
|
3307
|
+
line
|
|
3308
|
+
) || regexTest(String.raw`^\[\s*\d+/\d+\]\s+Cythonizing \S+\.pyx`, line));
|
|
3309
|
+
}
|
|
3310
|
+
function compactSetuptoolsFileStagingRuns(output) {
|
|
3311
|
+
return collapseContiguousRuns(output, isSetuptoolsFileStagingLine, 5, block => {
|
|
3312
|
+
const operations = uniqueStrings(( block.map(line => splitWhitespace(line)[0] ?? "staging")));
|
|
3313
|
+
return `[setuptools file staging: omitted ${block.length} ${operations.join("/")} line(s)]`;
|
|
3314
|
+
});
|
|
3315
|
+
}
|
|
3316
|
+
function isSetuptoolsFileStagingLine(line) {
|
|
3317
|
+
return regexTest(String.raw`^copying .+ -> .+$`, line) || regexTest(String.raw`^creating (?:build\b|[^/\s]+\.egg-info\b).*$`, line) || regexTest(String.raw`^creating [A-Za-z0-9_.+-]+-[A-Za-z0-9_.+-]+/[\w./+-]+$`, line) || regexTest(String.raw`^adding (?:license file )?(?:'[^']+'|"[^"]+")$`, line) || regexTest(String.raw`^writing .+\.egg-info/.+$`, line) || regexTest(String.raw`^writing manifest file ['"].+['"]$`, line) || regexTest(String.raw`^reading manifest (?:file|template) ['"].+['"]$`, line);
|
|
3318
|
+
}
|
|
3319
|
+
function compactNumpyDistutilsProbes(output) {
|
|
3320
|
+
if (!output.includes("INFO: ")) {
|
|
3321
|
+
return output;
|
|
3322
|
+
}
|
|
3323
|
+
return collapseContiguousRuns(
|
|
3324
|
+
output,
|
|
3325
|
+
isNumpyDistutilsProbeLine,
|
|
3326
|
+
4,
|
|
3327
|
+
block => `[numpy.distutils probes: omitted ${block.length} BLAS/LAPACK probe line(s)]`
|
|
3328
|
+
);
|
|
3329
|
+
}
|
|
3330
|
+
function isNumpyDistutilsProbeLine(line) {
|
|
3331
|
+
return !isDiagnosticLine(line) && line.startsWith("INFO: ") && regexTest(
|
|
3332
|
+
String.raw`(?:_info:|NOT AVAILABLE|libraries .* not found|Setting PTATLAS|customize |compile options:|extra options:)`,
|
|
3333
|
+
line
|
|
3334
|
+
);
|
|
3335
|
+
}
|
|
3336
|
+
function compactSphinxProgress(output) {
|
|
3337
|
+
if (!output.includes("reading sources... [") && !output.includes("writing output... [")) {
|
|
3338
|
+
return output;
|
|
3339
|
+
}
|
|
3340
|
+
return compactIntralineProgress(output, "sphinx progress", compactSphinxProgressLine);
|
|
3341
|
+
}
|
|
3342
|
+
function compactSphinxProgressLine(line) {
|
|
3343
|
+
if (!line.includes("reading sources... [") && !line.includes("writing output... [")) {
|
|
3344
|
+
return unchangedLine(line);
|
|
3345
|
+
}
|
|
3346
|
+
return compactProgressPatternsUnlessDiagnostic(line, [
|
|
3347
|
+
String.raw`reading sources\.\.\. \[\s*\d+%\]\s+\S+\s*`,
|
|
3348
|
+
String.raw`writing output\.\.\. \[\s*\d+%\]\s+\S+\s*`
|
|
3349
|
+
]);
|
|
3350
|
+
}
|
|
3351
|
+
function hasSphinxProgress(output) {
|
|
3352
|
+
return hasSphinxOutputMarker(output) && (output.includes("reading sources... [") || output.includes("writing output... ["));
|
|
3353
|
+
}
|
|
3354
|
+
function hasSphinxOutputMarker(output) {
|
|
3355
|
+
return ( output.split("\n").some(
|
|
3356
|
+
line => line.startsWith("Running Sphinx v") || line.startsWith("Sphinx v") || line.startsWith("loading pickled environment...") || line.startsWith("build succeeded") || line.startsWith("build finished with problems") || line.startsWith("The HTML pages are in ")
|
|
3357
|
+
));
|
|
3358
|
+
}
|
|
3359
|
+
function compactDocusaurusProgress(output) {
|
|
3360
|
+
if (!hasDocusaurusProgress(output)) {
|
|
3361
|
+
return output;
|
|
3362
|
+
}
|
|
3363
|
+
return omitMatchingLines(
|
|
3364
|
+
output,
|
|
3365
|
+
"docusaurus progress",
|
|
3366
|
+
line => regexTest(String.raw`^\s*[\u25CF\u25EF]\s+(?:Client|Server)(?:\s+|$)`, line),
|
|
3367
|
+
"progress"
|
|
3368
|
+
);
|
|
3369
|
+
}
|
|
3370
|
+
function compactCarriageReturnProgress(output) {
|
|
3371
|
+
if (!output.includes("\r")) {
|
|
3372
|
+
return output;
|
|
3373
|
+
}
|
|
3374
|
+
return ( output.split("\n").map(line => {
|
|
3375
|
+
const parts = line.split("\r");
|
|
3376
|
+
for (let idx = parts.length - 1; idx >= 0; idx--) {
|
|
3377
|
+
if (parts[idx].length !== 0) {
|
|
3378
|
+
return parts[idx];
|
|
3379
|
+
}
|
|
3380
|
+
}
|
|
3381
|
+
return "";
|
|
3382
|
+
})).join("\n");
|
|
3383
|
+
}
|
|
3384
|
+
function looksLikeGoRuntimePanic(output) {
|
|
3385
|
+
if (jsStringLen(output) < 4 * 1024 || !regexTest(
|
|
3386
|
+
String.raw`(?:^|\n)(?:fatal error: |runtime stack:|SIGSEGV|SIGABRT|SIGBUS)`,
|
|
3387
|
+
output
|
|
3388
|
+
)) {
|
|
3389
|
+
return false;
|
|
3390
|
+
}
|
|
3391
|
+
let count = 0;
|
|
3392
|
+
for (const line of output.split("\n")) {
|
|
3393
|
+
if (isGoRuntimeGoroutineHeader(line)) {
|
|
3394
|
+
count += 1;
|
|
3395
|
+
if (count === GO_RUNTIME_PANIC_MIN_GOROUTINES) {
|
|
3396
|
+
return true;
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
return false;
|
|
3401
|
+
}
|
|
3402
|
+
function compactGoRuntimePanicDump(output) {
|
|
3403
|
+
if (!looksLikeGoRuntimePanic(output)) {
|
|
3404
|
+
return output;
|
|
3405
|
+
}
|
|
3406
|
+
const lines = output.split("\n");
|
|
3407
|
+
const firstHeader = lines.findIndex(line => isGoRuntimeGoroutineHeader(line));
|
|
3408
|
+
if (firstHeader === -1) {
|
|
3409
|
+
return output;
|
|
3410
|
+
}
|
|
3411
|
+
const blocks = collectGoGoroutineBlocks(lines, firstHeader);
|
|
3412
|
+
if (blocks.length < GO_RUNTIME_PANIC_MIN_GOROUTINES) {
|
|
3413
|
+
return output;
|
|
3414
|
+
}
|
|
3415
|
+
const compacted = lines.slice(0, firstHeader);
|
|
3416
|
+
for (let k = blocks[0].start; k < blocks[0].end; k++) {
|
|
3417
|
+
compacted.push(lines[k]);
|
|
3418
|
+
}
|
|
3419
|
+
let omittedFrameLines = 0;
|
|
3420
|
+
const remainingBlocks = [];
|
|
3421
|
+
for (const block of blocks.slice(1)) {
|
|
3422
|
+
const originalBlock = lines.slice(block.start, block.end);
|
|
3423
|
+
const compactedBlock = compactGoGoroutineBlock(originalBlock);
|
|
3424
|
+
omittedFrameLines += saturatingSub(originalBlock.length, compactedBlock.length);
|
|
3425
|
+
remainingBlocks.push(compactedBlock);
|
|
3426
|
+
}
|
|
3427
|
+
const groupedBlocks = groupRepeatedGoGoroutineBlocks(remainingBlocks);
|
|
3428
|
+
if (omittedFrameLines === 0 && groupedBlocks.omittedBlocks === 0) {
|
|
3429
|
+
return output;
|
|
3430
|
+
}
|
|
3431
|
+
const summary = [];
|
|
3432
|
+
if (omittedFrameLines > 0) {
|
|
3433
|
+
summary.push(
|
|
3434
|
+
`${blocks.length - 1} goroutine block(s) below were condensed; ${omittedFrameLines} frame line(s) omitted`
|
|
3435
|
+
);
|
|
3436
|
+
}
|
|
3437
|
+
if (groupedBlocks.omittedBlocks > 0) {
|
|
3438
|
+
summary.push(`${groupedBlocks.omittedBlocks} repeated goroutine block(s) grouped`);
|
|
3439
|
+
}
|
|
3440
|
+
compacted.push(`[go runtime panic: ${summary.join("; ")}]`);
|
|
3441
|
+
for (const block of groupedBlocks.blocks) {
|
|
3442
|
+
compacted.push(...block);
|
|
3443
|
+
}
|
|
3444
|
+
return compacted.join("\n");
|
|
3445
|
+
}
|
|
3446
|
+
function collectGoGoroutineBlocks(lines, firstHeader) {
|
|
3447
|
+
const blocks = [];
|
|
3448
|
+
let start = firstHeader;
|
|
3449
|
+
for (let i = firstHeader + 1; i < lines.length; i++) {
|
|
3450
|
+
if (isGoRuntimeGoroutineHeader(lines[i])) {
|
|
3451
|
+
blocks.push({
|
|
3452
|
+
start,
|
|
3453
|
+
end: i
|
|
3454
|
+
});
|
|
3455
|
+
start = i;
|
|
3456
|
+
}
|
|
3457
|
+
}
|
|
3458
|
+
blocks.push({
|
|
3459
|
+
start,
|
|
3460
|
+
end: lines.length
|
|
3461
|
+
});
|
|
3462
|
+
return blocks;
|
|
3463
|
+
}
|
|
3464
|
+
function compactGoGoroutineBlock(block) {
|
|
3465
|
+
const footerStart = findGoGoroutineFooterStart(block);
|
|
3466
|
+
const stack = block.slice(0, footerStart);
|
|
3467
|
+
const footer = block.slice(footerStart);
|
|
3468
|
+
if (stack.length <= 4) {
|
|
3469
|
+
return [...stack, ...footer];
|
|
3470
|
+
}
|
|
3471
|
+
let createdByIndex;
|
|
3472
|
+
for (let idx = stack.length - 1; idx >= 0; idx--) {
|
|
3473
|
+
if (stack[idx].startsWith("created by ")) {
|
|
3474
|
+
createdByIndex = idx;
|
|
3475
|
+
break;
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3478
|
+
const kept = stack.slice(0, Math.min(3, stack.length));
|
|
3479
|
+
if (createdByIndex !== undefined && createdByIndex >= kept.length) {
|
|
3480
|
+
kept.push(...stack.slice(createdByIndex));
|
|
3481
|
+
}
|
|
3482
|
+
kept.push(...footer);
|
|
3483
|
+
return kept;
|
|
3484
|
+
}
|
|
3485
|
+
function groupRepeatedGoGoroutineBlocks(blocks) {
|
|
3486
|
+
const signatures = ( blocks.map(block => goGoroutineSignature(block)));
|
|
3487
|
+
const counts = ( new Map());
|
|
3488
|
+
for (const signature of signatures) {
|
|
3489
|
+
if (signature !== undefined) {
|
|
3490
|
+
counts.set(signature.key, (counts.get(signature.key) ?? 0) + 1);
|
|
3491
|
+
}
|
|
3492
|
+
}
|
|
3493
|
+
const grouped = [];
|
|
3494
|
+
const seen = [];
|
|
3495
|
+
let omittedBlocks = 0;
|
|
3496
|
+
for (let index = 0; index < blocks.length; index++) {
|
|
3497
|
+
const block = blocks[index];
|
|
3498
|
+
const signature = signatures[index];
|
|
3499
|
+
if (signature === undefined) {
|
|
3500
|
+
grouped.push([...block]);
|
|
3501
|
+
continue;
|
|
3502
|
+
}
|
|
3503
|
+
if ((counts.get(signature.key) ?? 0) < 3) {
|
|
3504
|
+
grouped.push([...block]);
|
|
3505
|
+
continue;
|
|
3506
|
+
}
|
|
3507
|
+
if (seen.includes(signature.key)) {
|
|
3508
|
+
omittedBlocks += 1;
|
|
3509
|
+
continue;
|
|
3510
|
+
}
|
|
3511
|
+
seen.push(signature.key);
|
|
3512
|
+
grouped.push([...block]);
|
|
3513
|
+
grouped.push([
|
|
3514
|
+
`[go runtime panic: omitted ${(counts.get(signature.key) ?? 1) - 1} similar goroutine block(s): state=${signature.state}, top=${signature.top}${signature.location.length === 0 ? "" : " at "}${signature.location}, created by=${signature.createdBy}]`,
|
|
3515
|
+
""
|
|
3516
|
+
]);
|
|
3517
|
+
}
|
|
3518
|
+
return {
|
|
3519
|
+
blocks: grouped,
|
|
3520
|
+
omittedBlocks
|
|
3521
|
+
};
|
|
3522
|
+
}
|
|
3523
|
+
function goGoroutineSignature(block) {
|
|
3524
|
+
if (findGoGoroutineFooterStart(block) < block.length) {
|
|
3525
|
+
return undefined;
|
|
3526
|
+
}
|
|
3527
|
+
const first = block[0];
|
|
3528
|
+
if (first === undefined) {
|
|
3529
|
+
return undefined;
|
|
3530
|
+
}
|
|
3531
|
+
const state = regexCaptureFirst(String.raw`\[([^\]]+)\]:$`, first);
|
|
3532
|
+
if (state === undefined) {
|
|
3533
|
+
return undefined;
|
|
3534
|
+
}
|
|
3535
|
+
let topIndex;
|
|
3536
|
+
for (let index = 0; index < block.length; index++) {
|
|
3537
|
+
const line = block[index];
|
|
3538
|
+
if (index > 0 && line.length !== 0 && !line.startsWith("\t") && !line.startsWith("created by ")) {
|
|
3539
|
+
topIndex = index;
|
|
3540
|
+
break;
|
|
3541
|
+
}
|
|
3542
|
+
}
|
|
3543
|
+
if (topIndex === undefined) {
|
|
3544
|
+
return undefined;
|
|
3545
|
+
}
|
|
3546
|
+
const top = goFunctionName(block[topIndex]);
|
|
3547
|
+
if (top === undefined) {
|
|
3548
|
+
return undefined;
|
|
3549
|
+
}
|
|
3550
|
+
const location = goFileLocation(topIndex + 1 < block.length ? block[topIndex + 1] : undefined);
|
|
3551
|
+
const createdByLine = block.find(line => line.startsWith("created by "));
|
|
3552
|
+
const createdBy = (createdByLine !== undefined ? goCreatedByFunction(createdByLine) : undefined) ?? "<none>";
|
|
3553
|
+
return {
|
|
3554
|
+
key: `${state}\0${top}\0${location}\0${createdBy}`,
|
|
3555
|
+
state,
|
|
3556
|
+
top,
|
|
3557
|
+
location,
|
|
3558
|
+
createdBy
|
|
3559
|
+
};
|
|
3560
|
+
}
|
|
3561
|
+
function goFunctionName(line) {
|
|
3562
|
+
return regexCaptureFirst(String.raw`^([^\s(]+)(?:\(|$)`, line);
|
|
3563
|
+
}
|
|
3564
|
+
function goFileLocation(line) {
|
|
3565
|
+
if (line === undefined) {
|
|
3566
|
+
return "";
|
|
3567
|
+
}
|
|
3568
|
+
return regexCaptureFirst(String.raw`([^/\s]+\.[A-Za-z0-9]+:\d+)`, line) ?? "";
|
|
3569
|
+
}
|
|
3570
|
+
function goCreatedByFunction(line) {
|
|
3571
|
+
return regexCaptureFirst(String.raw`^created by (.+?)(?: in goroutine \d+)?$`, line);
|
|
3572
|
+
}
|
|
3573
|
+
function findGoGoroutineFooterStart(block) {
|
|
3574
|
+
for (let i = 1; i < block.length; i++) {
|
|
3575
|
+
if (!isGoGoroutineStackLine(block[i])) {
|
|
3576
|
+
return i;
|
|
3577
|
+
}
|
|
3578
|
+
}
|
|
3579
|
+
return block.length;
|
|
3580
|
+
}
|
|
3581
|
+
function isGoGoroutineStackLine(line) {
|
|
3582
|
+
return line.length === 0 || line.startsWith("\t") || line.startsWith("created by ") || regexTest(String.raw`^\S.*\)$`, line);
|
|
3583
|
+
}
|
|
3584
|
+
function isGoRuntimeGoroutineHeader(line) {
|
|
3585
|
+
return regexTest(
|
|
3586
|
+
String.raw`^goroutine \d+(?: gp=\S+)?(?: m=\S+)?(?: mp=\S+)? \[[^\]]+\]:$`,
|
|
3587
|
+
line
|
|
3588
|
+
);
|
|
3589
|
+
}
|
|
3590
|
+
function isDjangoTestBoilerplateLine(line) {
|
|
3591
|
+
return !isDiagnosticLine(line) && (line.startsWith("Testing against Django installed in ") || regexTest(String.raw`^Found \d+ test(?:\(s\)|s)?\.$`, line) || line.startsWith("Creating test database for alias ") || line.startsWith("Destroying test database for alias ") || line.startsWith("Skipping setup of unused database") || line.startsWith("System check identified no issues") || line.startsWith("Operations to perform:") || line.startsWith("Apply all migrations:") || regexTest(String.raw`^ {2}Applying \S+\.\S+\.\.\. OK$`, line) || regexTest(String.raw`^test_\S+ \([^)]+\) \.\.\. ok$`, line));
|
|
3592
|
+
}
|
|
3593
|
+
function isDjangoTestProgressLine(line) {
|
|
3594
|
+
return !isDiagnosticLine(line) && (line.includes(".") || line.includes("s") || line.includes("x") || line.includes("X")) && regexTest(String.raw`^[.sxXEF]+(?:\s+\[\s*\d+%\])?$`, line);
|
|
3595
|
+
}
|
|
3596
|
+
function isPytestSessionMetadataLine(line) {
|
|
3597
|
+
return !isDiagnosticLine(line) && (regexTestWithFlags(String.raw`^=+\s*test session starts\s*=+$`, line, "i") || regexTest(String.raw`^platform .*\bpytest-.*\bpluggy-`, line) || regexTest(String.raw`^(?:cachedir|rootdir|configfile|plugins): `, line) || line.startsWith("collecting ...") || regexTest(String.raw`^collected \d+ items?`, line));
|
|
3598
|
+
}
|
|
3599
|
+
function compactPytestProgress(output) {
|
|
3600
|
+
if (hasPytestTerminalSummary(output)) {
|
|
3601
|
+
return omitPytestProgressLines(output, isPytestProgressLine);
|
|
3602
|
+
}
|
|
3603
|
+
if (hasStrictPytestPassedProgressRun(output) && !hasPytestProgressFallbackPoison(output)) {
|
|
3604
|
+
return omitPytestProgressLines(output, isStrictPytestPassedProgressLine);
|
|
3605
|
+
}
|
|
3606
|
+
return output;
|
|
3607
|
+
}
|
|
3608
|
+
function omitPytestProgressLines(output, shouldOmit) {
|
|
3609
|
+
const compacted = [];
|
|
3610
|
+
const omittedLines = [];
|
|
3611
|
+
for (const line of output.split("\n")) {
|
|
3612
|
+
if (shouldOmit(line)) {
|
|
3613
|
+
omittedLines.push(line);
|
|
3614
|
+
} else {
|
|
3615
|
+
flushPytestProgressLines(compacted, omittedLines);
|
|
3616
|
+
compacted.push(line);
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3619
|
+
flushPytestProgressLines(compacted, omittedLines);
|
|
3620
|
+
return compacted.join("\n");
|
|
3621
|
+
}
|
|
3622
|
+
function flushPytestProgressLines(compacted, omittedLines) {
|
|
3623
|
+
if (omittedLines.length === 0) {
|
|
3624
|
+
return;
|
|
3625
|
+
}
|
|
3626
|
+
const summary = omittedLines.every(line => isStrictPytestPassedProgressLine(line)) ? `[pytest progress: omitted ${omittedLines.length} PASSED test result line(s)]` : `[pytest progress: omitted ${omittedLines.length} non-diagnostic line(s)]`;
|
|
3627
|
+
compacted.push(summary);
|
|
3628
|
+
omittedLines.length = 0;
|
|
3629
|
+
}
|
|
3630
|
+
function isPytestProgressLine(line) {
|
|
3631
|
+
return !isDiagnosticLine(line) && (regexTest(String.raw`^[-=]{20,}$`, line) || regexTest(String.raw`^[.sxX]+(?:\s+\[\s*\d+%\])?\s*$`, line) || regexTest(String.raw`^\S+\.py::\S+\s+(?:PASSED|SKIPPED|XFAIL)\s+\[\s*\d+%\]$`, line));
|
|
3632
|
+
}
|
|
3633
|
+
function hasPytestProgressFallbackPoison(output) {
|
|
3634
|
+
return regexTest(
|
|
3635
|
+
String.raw`(?:^|\n)(?:\S+\.py::\S+\s+(?:FAILED|ERROR)\s+\[\s*\d+%\]|(?:FAIL|ERROR|INTERNALERROR)\b)|Traceback \(most recent call last\):`,
|
|
3636
|
+
output
|
|
3637
|
+
) || hasHardCrashLine(output);
|
|
3638
|
+
}
|
|
3639
|
+
function hasHardCrashLine(output) {
|
|
3640
|
+
return regexTestWithFlags(
|
|
3641
|
+
String.raw`(?:Fatal Python error:|Aborted|Abort trap|core dumped|segmentation fault)`,
|
|
3642
|
+
output,
|
|
3643
|
+
"i"
|
|
3644
|
+
);
|
|
3645
|
+
}
|
|
3646
|
+
function hasStrictPytestPassedProgressRun(output) {
|
|
3647
|
+
let runLength = 0;
|
|
3648
|
+
for (const line of output.split("\n")) {
|
|
3649
|
+
if (isStrictPytestPassedProgressLine(line)) {
|
|
3650
|
+
runLength += 1;
|
|
3651
|
+
if (runLength >= 5) {
|
|
3652
|
+
return true;
|
|
3653
|
+
}
|
|
3654
|
+
} else {
|
|
3655
|
+
runLength = 0;
|
|
3656
|
+
}
|
|
3657
|
+
}
|
|
3658
|
+
return false;
|
|
3659
|
+
}
|
|
3660
|
+
function isStrictPytestPassedProgressLine(line) {
|
|
3661
|
+
return !isDiagnosticLine(line) && regexTest(String.raw`^\S+\.py::\S+\s+PASSED\s+\[\s*\d+%\]$`, line);
|
|
3662
|
+
}
|
|
3663
|
+
function hasPytestTerminalSummary(output) {
|
|
3664
|
+
return regexTestWithFlags(
|
|
3665
|
+
String.raw`(?:^|\n)(?:=+\s*)?[^=\n]*(?:passed|failed|errors?|warnings?|skipped|xfailed|xpassed)[^=\n]*\bin \d+(?:\.\d+)?s\s*(?:=+)?\s*(?:\n|$)`,
|
|
3666
|
+
output,
|
|
3667
|
+
"i"
|
|
3668
|
+
);
|
|
3669
|
+
}
|
|
3670
|
+
function compactPytestFailureBlocks(output) {
|
|
3671
|
+
if (!hasPytestTerminalSummary(output)) {
|
|
3672
|
+
return output;
|
|
3673
|
+
}
|
|
3674
|
+
const shortSummaryLines = countPytestShortSummaryLines(output);
|
|
3675
|
+
const sectionHeaders = countPytestSectionHeaders(output);
|
|
3676
|
+
const lines = output.split("\n");
|
|
3677
|
+
const compacted = [];
|
|
3678
|
+
let i = 0;
|
|
3679
|
+
while (i < lines.length) {
|
|
3680
|
+
const section = pytestSectionName(lines[i]);
|
|
3681
|
+
if (section !== "FAILURES" && section !== "ERRORS") {
|
|
3682
|
+
compacted.push(lines[i]);
|
|
3683
|
+
i += 1;
|
|
3684
|
+
continue;
|
|
3685
|
+
}
|
|
3686
|
+
compacted.push(lines[i]);
|
|
3687
|
+
const start = i + 1;
|
|
3688
|
+
let end = start;
|
|
3689
|
+
while (end < lines.length && !isPytestSectionHeader(lines[end])) {
|
|
3690
|
+
end += 1;
|
|
3691
|
+
}
|
|
3692
|
+
compacted.push(
|
|
3693
|
+
...compactPytestFailureRegion(lines.slice(start, end), asciiLowercase(section ?? ""))
|
|
3694
|
+
);
|
|
3695
|
+
i = end;
|
|
3696
|
+
}
|
|
3697
|
+
const result = compacted.join("\n");
|
|
3698
|
+
if (countPytestShortSummaryLines(result) === shortSummaryLines && countPytestSectionHeaders(result) === sectionHeaders) {
|
|
3699
|
+
return result;
|
|
3700
|
+
}
|
|
3701
|
+
return output;
|
|
3702
|
+
}
|
|
3703
|
+
function compactPytestFailureRegion(lines, label) {
|
|
3704
|
+
const entries = [];
|
|
3705
|
+
const groups = ( new Map());
|
|
3706
|
+
let i = 0;
|
|
3707
|
+
while (i < lines.length) {
|
|
3708
|
+
const name = parsePytestFailureBlockHeader(lines[i]);
|
|
3709
|
+
if (name === undefined) {
|
|
3710
|
+
entries.push({
|
|
3711
|
+
type: "line",
|
|
3712
|
+
line: lines[i]
|
|
3713
|
+
});
|
|
3714
|
+
i += 1;
|
|
3715
|
+
continue;
|
|
3716
|
+
}
|
|
3717
|
+
const header = lines[i];
|
|
3718
|
+
i += 1;
|
|
3719
|
+
const bodyStart = i;
|
|
3720
|
+
while (i < lines.length && parsePytestFailureBlockHeader(lines[i]) === undefined && !isPytestSectionHeader(lines[i])) {
|
|
3721
|
+
i += 1;
|
|
3722
|
+
}
|
|
3723
|
+
const body = lines.slice(bodyStart, i);
|
|
3724
|
+
const key = pytestFailureBlockKey(body);
|
|
3725
|
+
const block = {
|
|
3726
|
+
header,
|
|
3727
|
+
name,
|
|
3728
|
+
body,
|
|
3729
|
+
key
|
|
3730
|
+
};
|
|
3731
|
+
if (key !== undefined) {
|
|
3732
|
+
const list = groups.get(key);
|
|
3733
|
+
if (list !== undefined) {
|
|
3734
|
+
list.push(block);
|
|
3735
|
+
} else {
|
|
3736
|
+
groups.set(key, [block]);
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
entries.push({
|
|
3740
|
+
type: "block",
|
|
3741
|
+
block
|
|
3742
|
+
});
|
|
3743
|
+
}
|
|
3744
|
+
const emittedGroups = [];
|
|
3745
|
+
const compacted = [];
|
|
3746
|
+
for (const entry of entries) {
|
|
3747
|
+
if (entry.type === "line") {
|
|
3748
|
+
compacted.push(entry.line);
|
|
3749
|
+
continue;
|
|
3750
|
+
}
|
|
3751
|
+
const block = entry.block;
|
|
3752
|
+
const group = block.key !== undefined ? groups.get(block.key) : undefined;
|
|
3753
|
+
const alreadyEmitted = block.key !== undefined && emittedGroups.includes(block.key);
|
|
3754
|
+
if (block.key === undefined || group === undefined || group.length < 2 || alreadyEmitted) {
|
|
3755
|
+
if (block.key === undefined || group === undefined || group.length < 2) {
|
|
3756
|
+
compacted.push(block.header);
|
|
3757
|
+
compacted.push(...block.body);
|
|
3758
|
+
}
|
|
3759
|
+
continue;
|
|
3760
|
+
}
|
|
3761
|
+
emittedGroups.push(block.key);
|
|
3762
|
+
const first = group[0];
|
|
3763
|
+
compacted.push(first.header);
|
|
3764
|
+
compacted.push(...first.body);
|
|
3765
|
+
const duplicates = group.slice(1);
|
|
3766
|
+
compacted.push(
|
|
3767
|
+
`[pytest ${label}: ${duplicates.length} duplicate traceback block(s) match ${first.name}; also: ${summarizeWithMore(( duplicates.map(duplicate => duplicate.name)), 8)}]`
|
|
3768
|
+
);
|
|
3769
|
+
}
|
|
3770
|
+
return compacted;
|
|
3771
|
+
}
|
|
3772
|
+
function parsePytestFailureBlockHeader(line) {
|
|
3773
|
+
return regexCaptureFirst(String.raw`^_{3,}\s+(.+?)\s+_{3,}\s*$`, line);
|
|
3774
|
+
}
|
|
3775
|
+
function pytestFailureBlockKey(body) {
|
|
3776
|
+
if (body.length < 3 || ( body.some(line => isPytestSummaryLine(line)))) {
|
|
3777
|
+
return undefined;
|
|
3778
|
+
}
|
|
3779
|
+
const normalized = ( body.map(line => normalizePytestFailureLine(line))).filter(line => line.trim().length !== 0).join("\n");
|
|
3780
|
+
if (normalized.split("\n").length >= 3) {
|
|
3781
|
+
return normalized;
|
|
3782
|
+
}
|
|
3783
|
+
return undefined;
|
|
3784
|
+
}
|
|
3785
|
+
function normalizePytestFailureLine(line) {
|
|
3786
|
+
const stripped = stripAnsi(line);
|
|
3787
|
+
return stripped.replace(( new RegExp(String.raw`^\[gw\d+\]\s*`)), "");
|
|
3788
|
+
}
|
|
3789
|
+
function isPytestSummaryLine(line) {
|
|
3790
|
+
return regexTest(String.raw`^(?:FAILED|ERROR)\s+\S`, line);
|
|
3791
|
+
}
|
|
3792
|
+
function countPytestShortSummaryLines(output) {
|
|
3793
|
+
return output.split("\n").filter(line => isPytestSummaryLine(line)).length;
|
|
3794
|
+
}
|
|
3795
|
+
function countPytestSectionHeaders(output) {
|
|
3796
|
+
return output.split("\n").filter(line => isPytestSectionHeader(line)).length;
|
|
3797
|
+
}
|
|
3798
|
+
function isPytestSectionHeader(line) {
|
|
3799
|
+
return pytestSectionName(line) !== undefined || regexTest(String.raw`^=+\s+.*\bin \d+(?:\.\d+)?s\b.*\s*=+\s*$`, line);
|
|
3800
|
+
}
|
|
3801
|
+
function pytestSectionName(line) {
|
|
3802
|
+
const name = regexCaptureFirst(String.raw`^=+\s+([A-Za-z][A-Za-z ]+)\s+=+\s*$`, line);
|
|
3803
|
+
return name !== undefined ? name.trim() : undefined;
|
|
3804
|
+
}
|
|
3805
|
+
function compactPytestWarningsSummary(output) {
|
|
3806
|
+
const lines = output.split("\n");
|
|
3807
|
+
const compacted = [];
|
|
3808
|
+
let i = 0;
|
|
3809
|
+
while (i < lines.length) {
|
|
3810
|
+
if (!regexTestWithFlags(String.raw`^=+\s*warnings summary\s*=+$`, lines[i], "i")) {
|
|
3811
|
+
compacted.push(lines[i]);
|
|
3812
|
+
i += 1;
|
|
3813
|
+
continue;
|
|
3814
|
+
}
|
|
3815
|
+
compacted.push(lines[i]);
|
|
3816
|
+
let j = i + 1;
|
|
3817
|
+
while (j < lines.length && !regexTest(String.raw`^=+\s+.+\s+=+$`, lines[j])) {
|
|
3818
|
+
j += 1;
|
|
3819
|
+
}
|
|
3820
|
+
compacted.push(...compactPytestWarningsSummaryRegion(lines.slice(i + 1, j)));
|
|
3821
|
+
i = j;
|
|
3822
|
+
}
|
|
3823
|
+
return compacted.join("\n");
|
|
3824
|
+
}
|
|
3825
|
+
function compactPytestWarningsSummaryRegion(lines) {
|
|
3826
|
+
const entries = [];
|
|
3827
|
+
const groups = ( new Map());
|
|
3828
|
+
let i = 0;
|
|
3829
|
+
while (i < lines.length) {
|
|
3830
|
+
if (!isPytestWarningTestIdLine(lines[i])) {
|
|
3831
|
+
entries.push({
|
|
3832
|
+
type: "line",
|
|
3833
|
+
line: lines[i]
|
|
3834
|
+
});
|
|
3835
|
+
i += 1;
|
|
3836
|
+
continue;
|
|
3837
|
+
}
|
|
3838
|
+
const testIds = [];
|
|
3839
|
+
while (i < lines.length && isPytestWarningTestIdLine(lines[i])) {
|
|
3840
|
+
testIds.push(lines[i]);
|
|
3841
|
+
i += 1;
|
|
3842
|
+
}
|
|
3843
|
+
const body = [];
|
|
3844
|
+
while (i < lines.length && !isPytestWarningTestIdLine(lines[i]) && !lines[i].startsWith("-- Docs: ")) {
|
|
3845
|
+
body.push(lines[i]);
|
|
3846
|
+
i += 1;
|
|
3847
|
+
}
|
|
3848
|
+
const parsed = parsePytestWarningBody(body);
|
|
3849
|
+
const block = {
|
|
3850
|
+
testIds,
|
|
3851
|
+
body,
|
|
3852
|
+
key: parsed?.key,
|
|
3853
|
+
warningClass: parsed?.warningClass,
|
|
3854
|
+
message: parsed?.message
|
|
3855
|
+
};
|
|
3856
|
+
if (block.key !== undefined) {
|
|
3857
|
+
const list = groups.get(block.key);
|
|
3858
|
+
if (list !== undefined) {
|
|
3859
|
+
list.push(block);
|
|
3860
|
+
} else {
|
|
3861
|
+
groups.set(block.key, [block]);
|
|
3862
|
+
}
|
|
3863
|
+
}
|
|
3864
|
+
entries.push({
|
|
3865
|
+
type: "block",
|
|
3866
|
+
block
|
|
3867
|
+
});
|
|
3868
|
+
}
|
|
3869
|
+
const emittedGroups = [];
|
|
3870
|
+
const compacted = [];
|
|
3871
|
+
for (const entry of entries) {
|
|
3872
|
+
if (entry.type === "line") {
|
|
3873
|
+
compacted.push(entry.line);
|
|
3874
|
+
continue;
|
|
3875
|
+
}
|
|
3876
|
+
const block = entry.block;
|
|
3877
|
+
const group = block.key !== undefined ? groups.get(block.key) : undefined;
|
|
3878
|
+
const shouldGroup = group !== undefined && (group.length > 1 || group[0].testIds.length > 1);
|
|
3879
|
+
const alreadyEmitted = block.key !== undefined && emittedGroups.includes(block.key);
|
|
3880
|
+
if (!shouldGroup || block.key === undefined || alreadyEmitted) {
|
|
3881
|
+
if (!shouldGroup) {
|
|
3882
|
+
compacted.push(...formatPytestWarningBlock(block));
|
|
3883
|
+
}
|
|
3884
|
+
continue;
|
|
3885
|
+
}
|
|
3886
|
+
if (group === undefined) {
|
|
3887
|
+
continue;
|
|
3888
|
+
}
|
|
3889
|
+
emittedGroups.push(block.key);
|
|
3890
|
+
const totalTestIds = group.reduce((sum, item) => sum + item.testIds.length, 0);
|
|
3891
|
+
compacted.push(group[0].testIds[0]);
|
|
3892
|
+
if (totalTestIds > 1) {
|
|
3893
|
+
compacted.push(
|
|
3894
|
+
`[pytest warnings summary: ${totalTestIds} test id line(s) share ${block.warningClass ?? "warning"}: ${block.message ?? ""}]`
|
|
3895
|
+
);
|
|
3896
|
+
}
|
|
3897
|
+
compacted.push(...group[0].body);
|
|
3898
|
+
const duplicateBodies = group.length - 1;
|
|
3899
|
+
if (duplicateBodies > 0) {
|
|
3900
|
+
const locations = [];
|
|
3901
|
+
for (const item of group) {
|
|
3902
|
+
const location = parsePytestWarningLocation(item.body);
|
|
3903
|
+
if (location !== undefined && !locations.includes(location)) {
|
|
3904
|
+
locations.push(location);
|
|
3905
|
+
}
|
|
3906
|
+
}
|
|
3907
|
+
const locationSummary = locations.length > 1 ? ` from ${locations.length} location(s)` : "";
|
|
3908
|
+
compacted.push(
|
|
3909
|
+
`[pytest warnings summary: omitted ${duplicateBodies} duplicate warning block(s)${locationSummary}]`
|
|
3910
|
+
);
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
return compacted;
|
|
3914
|
+
}
|
|
3915
|
+
function formatPytestWarningBlock(block) {
|
|
3916
|
+
if (block.testIds.length <= 1) {
|
|
3917
|
+
return [...block.testIds, ...block.body];
|
|
3918
|
+
}
|
|
3919
|
+
const lines = [block.testIds[0]];
|
|
3920
|
+
lines.push(
|
|
3921
|
+
`[pytest warnings summary: omitted ${block.testIds.length - 1} test id line(s)]`
|
|
3922
|
+
);
|
|
3923
|
+
lines.push(...block.body);
|
|
3924
|
+
return lines;
|
|
3925
|
+
}
|
|
3926
|
+
function parsePytestWarningBody(body) {
|
|
3927
|
+
const regex = ( new RegExp(String.raw`^\s+.+?:\d+:\s+([A-Za-z_][A-Za-z0-9_.]*Warning):\s+(.+)$`));
|
|
3928
|
+
for (const line of body) {
|
|
3929
|
+
const captures = regex.exec(line);
|
|
3930
|
+
if (captures === null) {
|
|
3931
|
+
continue;
|
|
3932
|
+
}
|
|
3933
|
+
const warningClass = captures[1];
|
|
3934
|
+
const messageRaw = captures[2];
|
|
3935
|
+
if (warningClass === undefined || messageRaw === undefined) {
|
|
3936
|
+
return undefined;
|
|
3937
|
+
}
|
|
3938
|
+
const message = normalizePytestWarningMessage(messageRaw);
|
|
3939
|
+
return {
|
|
3940
|
+
key: `${warningClass}\0${message}`,
|
|
3941
|
+
warningClass,
|
|
3942
|
+
message
|
|
3943
|
+
};
|
|
3944
|
+
}
|
|
3945
|
+
return undefined;
|
|
3946
|
+
}
|
|
3947
|
+
function parsePytestWarningLocation(body) {
|
|
3948
|
+
for (const line of body) {
|
|
3949
|
+
const location = regexCaptureFirst(String.raw`^\s+(.+?:\d+):\s+[A-Za-z_][A-Za-z0-9_.]*Warning:\s+.+$`, line);
|
|
3950
|
+
if (location !== undefined) {
|
|
3951
|
+
return location;
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
return undefined;
|
|
3955
|
+
}
|
|
3956
|
+
function normalizePytestWarningMessage(message) {
|
|
3957
|
+
return splitWhitespace(message).join(" ");
|
|
3958
|
+
}
|
|
3959
|
+
function isPytestWarningTestIdLine(line) {
|
|
3960
|
+
const trimmed = line.trimEnd();
|
|
3961
|
+
return line === trimmed && ((!trimmed.includes(" ") && (trimmed.includes(".py::") || regexTest(String.raw`^\S+\.py:\d+$`, trimmed))) || regexTest(String.raw`^\S+\.py:\s+\d+ warnings?$`, trimmed));
|
|
3962
|
+
}
|
|
3963
|
+
function compactGrepContentOutput(output, largeOutputThreshold) {
|
|
3964
|
+
const lines = splitToolOutputLines(output);
|
|
3965
|
+
if (shouldSkipToolOutputCompaction(lines, output, 8)) {
|
|
3966
|
+
return unchanged(output);
|
|
3967
|
+
}
|
|
3968
|
+
const grepLines = lines.filter(line => line !== "--");
|
|
3969
|
+
const parsedMatches = [];
|
|
3970
|
+
for (const line of grepLines) {
|
|
3971
|
+
const parsed = parseGrepContentLine(line);
|
|
3972
|
+
if (parsed !== undefined) {
|
|
3973
|
+
parsedMatches.push(parsed);
|
|
3974
|
+
}
|
|
3975
|
+
}
|
|
3976
|
+
if (parsedMatches.length < 8 || (parsedMatches.length < 20 && jsStringLen(output) < 4000)) {
|
|
3977
|
+
return unchanged(output);
|
|
3978
|
+
}
|
|
3979
|
+
if (parsedMatches.length !== grepLines.length && (fitsLargeOutputThreshold(output, largeOutputThreshold) || (parsedMatches.length / grepLines.length) < 0.6)) {
|
|
3980
|
+
return unchanged(output);
|
|
3981
|
+
}
|
|
3982
|
+
const sortedGroups = grepContentGroups(parsedMatches);
|
|
3983
|
+
const commonPrefix = commonDirectoryPrefix(( parsedMatches.map(m => m.path)));
|
|
3984
|
+
const bodyBudget = compactedBodyBudget(largeOutputThreshold);
|
|
3985
|
+
const lossless = renderGrepContentGroups(sortedGroups, commonPrefix, sortedGroups.length, indexAll);
|
|
3986
|
+
if (byteLength(lossless) >= byteLength(output) && fitsLargeOutputThreshold(output, largeOutputThreshold)) {
|
|
3987
|
+
return unchanged(output);
|
|
3988
|
+
}
|
|
3989
|
+
if (fitsLargeOutputThreshold(lossless, largeOutputThreshold)) {
|
|
3990
|
+
return {
|
|
3991
|
+
output: lossless,
|
|
3992
|
+
lossless: true
|
|
3993
|
+
};
|
|
3994
|
+
}
|
|
3995
|
+
const aggressive = renderGrepContentGroups(sortedGroups, commonPrefix, 12, selectHeadTailToShow);
|
|
3996
|
+
if (fitsLargeOutputThreshold(aggressive, bodyBudget)) {
|
|
3997
|
+
return lossy(aggressive);
|
|
3998
|
+
}
|
|
3999
|
+
const fallback = renderBudgetedGrepContentGroups(sortedGroups, commonPrefix, largeOutputThreshold);
|
|
4000
|
+
if (byteLength(fallback) < byteLength(aggressive)) {
|
|
4001
|
+
return lossy(fallback);
|
|
4002
|
+
}
|
|
4003
|
+
return lossy(aggressive);
|
|
4004
|
+
}
|
|
4005
|
+
function grepContentGroups(matches) {
|
|
4006
|
+
const groups = ( new Map());
|
|
4007
|
+
for (const m of matches) {
|
|
4008
|
+
const list = groups.get(m.path);
|
|
4009
|
+
if (list !== undefined) {
|
|
4010
|
+
list.push(m);
|
|
4011
|
+
} else {
|
|
4012
|
+
groups.set(m.path, [m]);
|
|
4013
|
+
}
|
|
4014
|
+
}
|
|
4015
|
+
return [...groups.entries()];
|
|
4016
|
+
}
|
|
4017
|
+
function renderGrepContentGroups(sortedGroups, commonPrefix, maxGroups, selectMatches) {
|
|
4018
|
+
const totalMatches = totalGroupItems(sortedGroups);
|
|
4019
|
+
const compacted = [];
|
|
4020
|
+
compacted.push(
|
|
4021
|
+
`[grep content: ${totalMatches} matches across ${sortedGroups.length} file(s)${commonPrefix.length === 0 ? "" : ` under ${commonPrefix}`}]`
|
|
4022
|
+
);
|
|
4023
|
+
for (const [filePath, fileMatches] of sortedGroups.slice(0, maxGroups)) {
|
|
4024
|
+
const displayPath = displayPathUnderPrefix(filePath, commonPrefix);
|
|
4025
|
+
if (fileMatches.length === 1) {
|
|
4026
|
+
compacted.push(`${displayPath}:${formatGrepMatch(fileMatches[0])}`);
|
|
4027
|
+
continue;
|
|
4028
|
+
}
|
|
4029
|
+
compacted.push("");
|
|
4030
|
+
compacted.push(`${displayPath} (${fileMatches.length} match(es)):`);
|
|
4031
|
+
const shown = selectMatches(fileMatches);
|
|
4032
|
+
let previousIndex;
|
|
4033
|
+
for (const {
|
|
4034
|
+
item: m,
|
|
4035
|
+
index
|
|
4036
|
+
} of shown) {
|
|
4037
|
+
if (previousIndex !== undefined && index > previousIndex + 1) {
|
|
4038
|
+
compacted.push(` ... ${index - previousIndex - 1} more match(es) omitted in this file`);
|
|
4039
|
+
}
|
|
4040
|
+
compacted.push(` ${formatGrepMatch(m)}`);
|
|
4041
|
+
previousIndex = index;
|
|
4042
|
+
}
|
|
4043
|
+
const omittedAfterLast = previousIndex !== undefined ? saturatingSub(fileMatches.length, previousIndex + 1) : fileMatches.length;
|
|
4044
|
+
if (omittedAfterLast > 0) {
|
|
4045
|
+
compacted.push(` ... ${omittedAfterLast} more match(es) omitted in this file`);
|
|
4046
|
+
}
|
|
4047
|
+
}
|
|
4048
|
+
if (sortedGroups.length > maxGroups) {
|
|
4049
|
+
const omittedMatches = totalGroupItems(sortedGroups.slice(maxGroups));
|
|
4050
|
+
compacted.push("");
|
|
4051
|
+
compacted.push(
|
|
4052
|
+
`[omitted ${omittedMatches} match(es) in ${sortedGroups.length - maxGroups} file(s); see original output for full results]`
|
|
4053
|
+
);
|
|
4054
|
+
}
|
|
4055
|
+
return compacted.join("\n");
|
|
4056
|
+
}
|
|
4057
|
+
function parseGrepContentLine(line) {
|
|
4058
|
+
const numbered = parseNumberedGrepContentLine(line);
|
|
4059
|
+
if (numbered !== undefined) {
|
|
4060
|
+
return numbered;
|
|
4061
|
+
}
|
|
4062
|
+
const separatorIndex = line.indexOf(":");
|
|
4063
|
+
if (separatorIndex < 0) {
|
|
4064
|
+
return undefined;
|
|
4065
|
+
}
|
|
4066
|
+
if (separatorIndex === 0 || separatorIndex === line.length - 1) {
|
|
4067
|
+
return undefined;
|
|
4068
|
+
}
|
|
4069
|
+
const path = line.slice(0, separatorIndex);
|
|
4070
|
+
if (!looksLikeGrepPath(path)) {
|
|
4071
|
+
return undefined;
|
|
4072
|
+
}
|
|
4073
|
+
return {
|
|
4074
|
+
path: normalizeDisplayPathSeparators(path),
|
|
4075
|
+
lineNumber: undefined,
|
|
4076
|
+
separator: ":",
|
|
4077
|
+
text: line.slice(separatorIndex + 1)
|
|
4078
|
+
};
|
|
4079
|
+
}
|
|
4080
|
+
function parseNumberedGrepContentLine(line) {
|
|
4081
|
+
const bytes = ( new TextEncoder()).encode(line);
|
|
4082
|
+
const decoder = ( new TextDecoder());
|
|
4083
|
+
const sliceStr = (start, end) => decoder.decode(bytes.subarray(start, end));
|
|
4084
|
+
const isAsciiDigitByte = byte => byte >= 0x30 && byte <= 0x39;
|
|
4085
|
+
const colon = 0x3A;
|
|
4086
|
+
const dash = 0x2D;
|
|
4087
|
+
const upperBound = saturatingSub(bytes.length, 2);
|
|
4088
|
+
for (let i = 1; i < upperBound; i++) {
|
|
4089
|
+
const pathSeparator = bytes[i];
|
|
4090
|
+
if (pathSeparator !== colon && pathSeparator !== dash) {
|
|
4091
|
+
continue;
|
|
4092
|
+
}
|
|
4093
|
+
const numberStart = i + 1;
|
|
4094
|
+
let numberEnd = numberStart;
|
|
4095
|
+
while (numberEnd < bytes.length && isAsciiDigitByte(bytes[numberEnd])) {
|
|
4096
|
+
numberEnd += 1;
|
|
4097
|
+
}
|
|
4098
|
+
if (numberEnd === numberStart) {
|
|
4099
|
+
continue;
|
|
4100
|
+
}
|
|
4101
|
+
if (numberEnd >= bytes.length) {
|
|
4102
|
+
return undefined;
|
|
4103
|
+
}
|
|
4104
|
+
const separator = bytes[numberEnd];
|
|
4105
|
+
if (separator !== colon && separator !== dash) {
|
|
4106
|
+
continue;
|
|
4107
|
+
}
|
|
4108
|
+
const path = sliceStr(0, i);
|
|
4109
|
+
if (!looksLikeGrepPath(path)) {
|
|
4110
|
+
continue;
|
|
4111
|
+
}
|
|
4112
|
+
return {
|
|
4113
|
+
path: normalizeDisplayPathSeparators(path),
|
|
4114
|
+
lineNumber: sliceStr(numberStart, numberEnd),
|
|
4115
|
+
separator: String.fromCharCode(separator),
|
|
4116
|
+
text: sliceStr(numberEnd + 1, bytes.length)
|
|
4117
|
+
};
|
|
4118
|
+
}
|
|
4119
|
+
return undefined;
|
|
4120
|
+
}
|
|
4121
|
+
function looksLikeGrepPath(path) {
|
|
4122
|
+
return path.includes("/") || path.includes("\\") || regexTest(String.raw`\.[A-Za-z0-9_-]+$`, path);
|
|
4123
|
+
}
|
|
4124
|
+
function renderBudgetedGrepContentGroups(sortedGroups, commonPrefix, largeOutputThreshold) {
|
|
4125
|
+
const budget = compactedBodyBudget(largeOutputThreshold);
|
|
4126
|
+
let smallest = renderBudgetedGrepContentGroupsWithLimit(sortedGroups, commonPrefix, 1, 1);
|
|
4127
|
+
for (const maxGroups of [10, 8, 6, 4, 2, 1]) {
|
|
4128
|
+
for (const maxMatchesPerGroup of [12, 6, 3, 1]) {
|
|
4129
|
+
const candidate = renderBudgetedGrepContentGroupsWithLimit(sortedGroups, commonPrefix, maxGroups, maxMatchesPerGroup);
|
|
4130
|
+
if (fitsLargeOutputThreshold(candidate, budget)) {
|
|
4131
|
+
return candidate;
|
|
4132
|
+
}
|
|
4133
|
+
smallest = candidate;
|
|
4134
|
+
}
|
|
4135
|
+
}
|
|
4136
|
+
return smallest;
|
|
4137
|
+
}
|
|
4138
|
+
function renderBudgetedGrepContentGroupsWithLimit(sortedGroups, commonPrefix, maxGroups, maxMatchesPerGroup) {
|
|
4139
|
+
const totalMatches = totalGroupItems(sortedGroups);
|
|
4140
|
+
const compacted = [];
|
|
4141
|
+
compacted.push(
|
|
4142
|
+
`[grep content: ${totalMatches} matches across ${sortedGroups.length} file(s)${commonPrefix.length === 0 ? "" : ` under ${truncatePathMiddle(commonPrefix, COMMON_PREFIX_DISPLAY_WIDTH)}`}; compact summary]`
|
|
4143
|
+
);
|
|
4144
|
+
for (const [filePath, fileMatches] of sortedGroups.slice(0, maxGroups)) {
|
|
4145
|
+
compacted.push(
|
|
4146
|
+
formatBudgetedGrepGroup(filePath, fileMatches, commonPrefix, maxMatchesPerGroup)
|
|
4147
|
+
);
|
|
4148
|
+
}
|
|
4149
|
+
if (sortedGroups.length > maxGroups) {
|
|
4150
|
+
const omittedMatches = totalGroupItems(sortedGroups.slice(maxGroups));
|
|
4151
|
+
compacted.push(
|
|
4152
|
+
`[omitted ${omittedMatches} match(es) in ${sortedGroups.length - maxGroups} file(s)]`
|
|
4153
|
+
);
|
|
4154
|
+
}
|
|
4155
|
+
const extensionSummary = summarizeExtensions(( sortedGroups.map(([filePath]) => filePath)));
|
|
4156
|
+
if (extensionSummary.length !== 0) {
|
|
4157
|
+
compacted.push(
|
|
4158
|
+
`[extensions: ${truncateInlineText(extensionSummary, EXTENSION_SUMMARY_INLINE_WIDTH)}]`
|
|
4159
|
+
);
|
|
4160
|
+
}
|
|
4161
|
+
return compacted.join("\n");
|
|
4162
|
+
}
|
|
4163
|
+
function formatBudgetedGrepGroup(filePath, fileMatches, commonPrefix, maxMatches) {
|
|
4164
|
+
const displayPath = truncatePathMiddle(displayPathUnderPrefix(filePath, commonPrefix), 140);
|
|
4165
|
+
const shown = selectEvenlySpacedGrepMatches(fileMatches, maxMatches);
|
|
4166
|
+
const lines = [`${displayPath} (${fileMatches.length} match(es)):`];
|
|
4167
|
+
for (const {
|
|
4168
|
+
item: m
|
|
4169
|
+
} of shown) {
|
|
4170
|
+
lines.push(` ${excerptInlineText(formatGrepMatch(m), 180)}`);
|
|
4171
|
+
}
|
|
4172
|
+
if (fileMatches.length > shown.length) {
|
|
4173
|
+
lines.push(
|
|
4174
|
+
` ... ${fileMatches.length - shown.length} more match(es) omitted in this file`
|
|
4175
|
+
);
|
|
4176
|
+
}
|
|
4177
|
+
return lines.join("\n");
|
|
4178
|
+
}
|
|
4179
|
+
function selectEvenlySpacedGrepMatches(matches, maxMatches) {
|
|
4180
|
+
if (matches.length <= maxMatches) {
|
|
4181
|
+
return indexAll(matches);
|
|
4182
|
+
}
|
|
4183
|
+
if (maxMatches <= 1) {
|
|
4184
|
+
return [{
|
|
4185
|
+
item: matches[0],
|
|
4186
|
+
index: 0
|
|
4187
|
+
}];
|
|
4188
|
+
}
|
|
4189
|
+
const selected = [];
|
|
4190
|
+
const seen = [];
|
|
4191
|
+
for (let i = 0; i < maxMatches; i++) {
|
|
4192
|
+
const index = Math.round((i * (matches.length - 1)) / (maxMatches - 1));
|
|
4193
|
+
if (!seen.includes(index)) {
|
|
4194
|
+
seen.push(index);
|
|
4195
|
+
selected.push({
|
|
4196
|
+
index,
|
|
4197
|
+
item: matches[index]
|
|
4198
|
+
});
|
|
4199
|
+
}
|
|
4200
|
+
}
|
|
4201
|
+
return selected;
|
|
4202
|
+
}
|
|
4203
|
+
function formatGrepMatch(m) {
|
|
4204
|
+
if (m.lineNumber !== undefined) {
|
|
4205
|
+
return `${m.lineNumber}${m.separator} ${m.text}`;
|
|
4206
|
+
}
|
|
4207
|
+
return ` ${m.text}`;
|
|
4208
|
+
}
|
|
4209
|
+
function selectHeadTailToShow(items) {
|
|
4210
|
+
if (items.length <= 40) {
|
|
4211
|
+
return indexAll(items);
|
|
4212
|
+
}
|
|
4213
|
+
const indexes = [];
|
|
4214
|
+
for (let i = 0; i < 12; i++) {
|
|
4215
|
+
indexes.push(i);
|
|
4216
|
+
}
|
|
4217
|
+
for (let i = items.length - 12; i < items.length; i++) {
|
|
4218
|
+
indexes.push(i);
|
|
4219
|
+
}
|
|
4220
|
+
return ( indexes.map(index => ({
|
|
4221
|
+
index,
|
|
4222
|
+
item: items[index]
|
|
4223
|
+
})));
|
|
4224
|
+
}
|
|
4225
|
+
function commonDirectoryPrefix(paths) {
|
|
4226
|
+
if (paths.length === 0) {
|
|
4227
|
+
return "";
|
|
4228
|
+
}
|
|
4229
|
+
const directories = ( paths.map(filePath => {
|
|
4230
|
+
const index = filePath.lastIndexOf("/");
|
|
4231
|
+
return index > 0 ? filePath.slice(0, index) : "";
|
|
4232
|
+
}));
|
|
4233
|
+
const firstParts = directories[0].split("/");
|
|
4234
|
+
let prefixLength = firstParts.length;
|
|
4235
|
+
for (const directory of directories.slice(1)) {
|
|
4236
|
+
const parts = directory.split("/");
|
|
4237
|
+
let i = 0;
|
|
4238
|
+
while (i < prefixLength && i < parts.length && firstParts[i] === parts[i]) {
|
|
4239
|
+
i += 1;
|
|
4240
|
+
}
|
|
4241
|
+
prefixLength = i;
|
|
4242
|
+
}
|
|
4243
|
+
return firstParts.slice(0, prefixLength).join("/");
|
|
4244
|
+
}
|
|
4245
|
+
function splitToolOutputLines(output) {
|
|
4246
|
+
if (output.length === 0) {
|
|
4247
|
+
return [];
|
|
4248
|
+
}
|
|
4249
|
+
const pieces = [];
|
|
4250
|
+
let start = 0;
|
|
4251
|
+
for (let i = 0; i < output.length; i++) {
|
|
4252
|
+
if (output[i] === "\n") {
|
|
4253
|
+
pieces.push(output.slice(start, i + 1));
|
|
4254
|
+
start = i + 1;
|
|
4255
|
+
}
|
|
4256
|
+
}
|
|
4257
|
+
if (start < output.length) {
|
|
4258
|
+
pieces.push(output.slice(start));
|
|
4259
|
+
}
|
|
4260
|
+
const result = [];
|
|
4261
|
+
for (const piece of pieces) {
|
|
4262
|
+
let line = piece;
|
|
4263
|
+
if (line.endsWith("\r\n")) {
|
|
4264
|
+
line = line.slice(0, line.length - 2);
|
|
4265
|
+
} else if (line.endsWith("\n")) {
|
|
4266
|
+
line = line.slice(0, line.length - 1);
|
|
4267
|
+
}
|
|
4268
|
+
if (line.length !== 0) {
|
|
4269
|
+
result.push(line);
|
|
4270
|
+
}
|
|
4271
|
+
}
|
|
4272
|
+
return result;
|
|
4273
|
+
}
|
|
4274
|
+
function normalizeDisplayPathSeparators(filePath) {
|
|
4275
|
+
return filePath.replaceAll("\\", "/");
|
|
4276
|
+
}
|
|
4277
|
+
function displayPathUnderPrefix(filePath, commonPrefix) {
|
|
4278
|
+
const normalized = normalizeDisplayPathSeparators(filePath);
|
|
4279
|
+
if (commonPrefix.length === 0) {
|
|
4280
|
+
return normalized;
|
|
4281
|
+
}
|
|
4282
|
+
const relative = trimStartMatchesChars(normalized.slice(commonPrefix.length), ["/"]);
|
|
4283
|
+
return relative.length === 0 ? "." : relative;
|
|
4284
|
+
}
|
|
4285
|
+
function summarizeExtensions(paths) {
|
|
4286
|
+
const counts = [];
|
|
4287
|
+
for (const filePath of paths) {
|
|
4288
|
+
const extension = pathExtension(filePath);
|
|
4289
|
+
const existing = counts.find(candidate => candidate.extension === extension);
|
|
4290
|
+
if (existing !== undefined) {
|
|
4291
|
+
existing.count += 1;
|
|
4292
|
+
} else {
|
|
4293
|
+
counts.push({
|
|
4294
|
+
extension,
|
|
4295
|
+
count: 1
|
|
4296
|
+
});
|
|
4297
|
+
}
|
|
4298
|
+
}
|
|
4299
|
+
counts.sort((a, b) => b.count - a.count);
|
|
4300
|
+
return ( counts.slice(0, 8).map(entry => `${entry.extension}=${entry.count}`)).join(", ");
|
|
4301
|
+
}
|
|
4302
|
+
function pathExtension(filePath) {
|
|
4303
|
+
const pathOnly = filePath.split("::")[0];
|
|
4304
|
+
const slashSegments = pathOnly.split("/");
|
|
4305
|
+
const basename = slashSegments[slashSegments.length - 1];
|
|
4306
|
+
const index = basename.lastIndexOf(".");
|
|
4307
|
+
if (index < 0) {
|
|
4308
|
+
return "[no extension]";
|
|
4309
|
+
}
|
|
4310
|
+
if (index === 0 || index === basename.length - 1) {
|
|
4311
|
+
return "[no extension]";
|
|
4312
|
+
}
|
|
4313
|
+
return basename.slice(index);
|
|
4314
|
+
}
|
|
4315
|
+
|
|
4316
|
+
export { compact, compactShellOutput };
|