@agenthippo-ai/agenthippo 1.110.9 → 1.110.19
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/out/agentpack/types.js +2 -5
- package/out/analytics/dashboard/artifactManager.js +2 -439
- package/out/analytics/dashboard/fleetDisplayUtils.js +2 -162
- package/out/analytics/dashboard/fleetOrchestrator.js +3 -142
- package/out/analytics/dashboard/fleetRegistry.js +2 -79
- package/out/analytics/dashboard/fleetRowDefaults.js +2 -87
- package/out/analytics/dashboard/fleetScriptAdapter.js +2 -146
- package/out/analytics/dashboard/fleetTypes.js +2 -29
- package/out/analytics/dashboard/index.js +2 -17
- package/out/analytics/dashboard/indexingService.js +2 -422
- package/out/analytics/dashboard/localFleetAdapter.js +2 -222
- package/out/analytics/dashboard/performanceMonitor.js +5 -76
- package/out/analytics/dashboard/processManager.js +2 -209
- package/out/analytics/dashboard/provider.js +38 -3817
- package/out/analytics/dashboard/queryRunner.js +62 -750
- package/out/analytics/dashboard/scheduledFleetStorage.js +2 -241
- package/out/analytics/dashboard/sessionJsonlFleet.js +3 -204
- package/out/analytics/dashboard/teamViewDiscovery.js +2 -106
- package/out/analytics/dashboard/webview/panel.js +34 -2318
- package/out/analytics/dashboard/webview/runtime-bridge.js +2 -82
- package/out/analytics/lifecycle.js +2 -43
- package/out/analytics/service.js +8 -1277
- package/out/auth/authBaseUrl.js +2 -59
- package/out/auth/bootstrapApply.js +2 -71
- package/out/auth/brokerClient.js +2 -160
- package/out/auth/callbackUri.js +2 -59
- package/out/auth/githubStoreGate.js +2 -70
- package/out/auth/loopbackAuthServer.js +4 -159
- package/out/auth/onboardingPrompt.js +2 -112
- package/out/auth/pkce.js +2 -9
- package/out/auth/provider.js +2 -226
- package/out/auth/sessionStore.js +2 -156
- package/out/auth/signInFlow.js +2 -183
- package/out/cli/index.js +619 -551
- package/out/cli/run-custom-engine-runner.js +3 -318
- package/out/cli/vscode-shim.js +2 -86
- package/out/engines/factory.js +2 -45
- package/out/engines/types.js +2 -17
- package/out/examples/run-headless-repl.js +6 -286
- package/out/examples/run-headless.js +2 -187
- package/out/extension.js +32 -4473
- package/out/gateway/gatewayRouteIndex.js +6 -371
- package/out/gateway/gatewaySessionStore.js +3 -243
- package/out/gateway/index.js +2 -31
- package/out/gateway/resetMappings.js +2 -52
- package/out/gateway/service.js +5 -1249
- package/out/mcp/publish.js +2 -143
- package/out/remote/handleRemoteChat.js +2 -169
- package/out/remote/remotePackStatusBar.js +3 -103
- package/out/remote/remoteTrust.js +6 -277
- package/out/remote/serveClient.js +4 -277
- package/out/remoteSkills.js +3 -191
- package/out/runtime/index.js +2 -32
- package/out/runtime/vscode/index.js +2 -20
- package/out/runtime/vscode/vscode-config-provider.js +2 -77
- package/out/runtime/vscode/vscode-edit-tracker.js +2 -122
- package/out/runtime/vscode/vscode-logger.js +2 -30
- package/out/runtime/vscode/vscode-permission-handler.js +2 -72
- package/out/scripts/agentide-litellm.sh +0 -1
- package/out/scripts/agentide_litellm_hooks_v1.py +170 -418
- package/out/scripts/analytics/agent-fleet-widget.js +18 -257
- package/out/scripts/analytics/agentide-litellm-otel.config.yaml +4 -4
- package/out/scripts/analytics/duckdbLocator.js +2 -28
- package/out/scripts/analytics/generate-default-charts.py +43 -323
- package/out/scripts/analytics/hotspot-analysis-widget.js +4 -430
- package/out/scripts/analytics/index-traces.py +78 -1036
- package/out/scripts/analytics/session-comparison-widget.js +26 -472
- package/out/scripts/analytics/session-timeline-widget.js +25 -846
- package/out/scripts/analytics/setup-analytics.ps1 +8 -1
- package/out/scripts/analytics/setup-analytics.sh +13 -2
- package/out/scripts/analytics/token-cost-flamegraph-widget.js +4 -461
- package/out/scripts/analytics/token-cost-trend-widget.js +4 -534
- package/out/scripts/analytics/workflows-collector.cjs +4 -314
- package/out/scripts/analytics/workflows-daemon.mjs +9 -185
- package/out/scripts/analytics/workflows-widget.cjs +15 -159
- package/out/scripts/analytics/wow-model-widget.js +10 -120
- package/out/scripts/vendor-tools.mjs +2 -233
- package/out/skills/publish.js +3 -178
- package/out/store/github/setup.js +7 -212
- package/out/store/oramaIndex.js +2 -884
- package/out/sync.js +26 -1829
- package/out/terminalLogger.js +5 -358
- package/out/utils/pathSafety.js +2 -60
- package/out/utils/pythonRunner.js +4 -258
- package/out/utils/toolPath.js +2 -83
- package/out/workspaceFolders.js +2 -59
- package/package.json +1 -1
- package/out/agentpack/github.js +0 -547
- package/out/agentpack/index.js +0 -67
- package/out/agentpack/install.js +0 -297
- package/out/agentpack/manager.js +0 -441
- package/out/agentpack/manifest.js +0 -135
- package/out/agentpack/paths.js +0 -498
- package/out/agentpack/publish.js +0 -248
- package/out/agentpack/stores.js +0 -554
- package/out/analytics/dashboard/fleetStatusUtils.js +0 -30
- package/out/analytics/dashboard/fleetTitleUtils.js +0 -68
- package/out/analytics/dashboard/refreshPolicy.js +0 -16
- package/out/analytics/dashboard/scheduledFleetFingerprint.js +0 -22
- package/out/analytics/dashboard/scheduledFleetUtils.js +0 -22
- package/out/analytics/dashboard/sessionEventFleetStats.js +0 -118
- package/out/analytics/dashboard/viewsConfigMerge.js +0 -221
- package/out/analytics/dashboard/webview/codicon.ttf +0 -0
- package/out/analytics/identity.js +0 -0
- package/out/analytics/sessionEvents.js +0 -323
- package/out/auth/callbackUriParse.js +0 -59
- package/out/auth/types.js +0 -12
- package/out/auth-broker/config.js +0 -112
- package/out/auth-broker/jwt.js +0 -105
- package/out/auth-broker/pkce.js +0 -59
- package/out/auth-broker/server.js +0 -677
- package/out/auth-broker/store.js +0 -275
- package/out/authority/warrant.js +0 -206
- package/out/base-prompts/mcp-servers/.mcp.json +0 -13
- package/out/base-prompts/mcp-servers/langfuse-analytics/README.md +0 -142
- package/out/base-prompts/mcp-servers/langfuse-analytics/mcp.json +0 -13
- package/out/base-prompts/mcp-servers/langfuse-analytics/package-lock.json +0 -1192
- package/out/base-prompts/mcp-servers/langfuse-analytics/package.json +0 -23
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/run-with-env.sh +0 -12
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/sdk-test.js +0 -102
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/simple-test.js +0 -137
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-client.js +0 -118
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-server.js +0 -209
- package/out/base-prompts/mcp-servers/langfuse-analytics/src/client.ts +0 -431
- package/out/base-prompts/mcp-servers/langfuse-analytics/src/index.ts +0 -270
- package/out/base-prompts/mcp-servers/langfuse-analytics/tsconfig.json +0 -18
- package/out/base-prompts/rules/AGENTS.md +0 -204
- package/out/base-prompts/skills/agent-browser/SKILL.md +0 -102
- package/out/base-prompts/skills/agent-builder/SKILL.md +0 -73
- package/out/base-prompts/skills/agent-builder/references/agent-pack.md +0 -63
- package/out/base-prompts/skills/agent-builder/references/crewai.md +0 -66
- package/out/base-prompts/skills/agent-builder/references/langchain.md +0 -60
- package/out/base-prompts/skills/agent-builder/references/raw-sdk.md +0 -73
- package/out/base-prompts/skills/agent-engine-creator/SKILL.md +0 -586
- package/out/base-prompts/skills/agent-engine-installer/SKILL.md +0 -106
- package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.mjs +0 -259
- package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.ps1 +0 -189
- package/out/base-prompts/skills/agenthippo-cli/SKILL.md +0 -69
- package/out/base-prompts/skills/agenthippo-cli/scripts/install.sh +0 -63
- package/out/base-prompts/skills/agentpack-creator/SKILL.md +0 -375
- package/out/base-prompts/skills/agentpack-creator/references/agent-templates.md +0 -261
- package/out/base-prompts/skills/agentpack-creator/references/agents-md-guide.md +0 -195
- package/out/base-prompts/skills/agentpack-creator/scripts/init_pack.py +0 -391
- package/out/base-prompts/skills/agentpack-creator/scripts/init_pack_test.py +0 -294
- package/out/base-prompts/skills/agentpack-testbench/SKILL.md +0 -135
- package/out/base-prompts/skills/algorithmic-art/LICENSE.txt +0 -202
- package/out/base-prompts/skills/algorithmic-art/SKILL.md +0 -405
- package/out/base-prompts/skills/algorithmic-art/templates/generator_template.js +0 -223
- package/out/base-prompts/skills/algorithmic-art/templates/viewer.html +0 -599
- package/out/base-prompts/skills/debug-agent/SKILL.md +0 -83
- package/out/base-prompts/skills/desktop-automation/SKILL.md +0 -166
- package/out/base-prompts/skills/desktop-automation/references/agenthippo-ui-recipes.md +0 -441
- package/out/base-prompts/skills/desktop-automation/scripts/windows-desktop-uia.psm1 +0 -280
- package/out/base-prompts/skills/docx/LICENSE.txt +0 -30
- package/out/base-prompts/skills/docx/SKILL.md +0 -197
- package/out/base-prompts/skills/docx/docx-js.md +0 -350
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/out/base-prompts/skills/docx/ooxml/schemas/mce/mc.xsd +0 -75
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/out/base-prompts/skills/docx/ooxml/scripts/pack.py +0 -159
- package/out/base-prompts/skills/docx/ooxml/scripts/unpack.py +0 -29
- package/out/base-prompts/skills/docx/ooxml/scripts/validate.py +0 -69
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/__init__.py +0 -15
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/base.py +0 -951
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/docx.py +0 -274
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/pptx.py +0 -315
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/redlining.py +0 -279
- package/out/base-prompts/skills/docx/ooxml.md +0 -610
- package/out/base-prompts/skills/docx/scripts/__init__.py +0 -1
- package/out/base-prompts/skills/docx/scripts/document.py +0 -1276
- package/out/base-prompts/skills/docx/scripts/templates/comments.xml +0 -3
- package/out/base-prompts/skills/docx/scripts/templates/commentsExtended.xml +0 -3
- package/out/base-prompts/skills/docx/scripts/templates/commentsExtensible.xml +0 -3
- package/out/base-prompts/skills/docx/scripts/templates/commentsIds.xml +0 -3
- package/out/base-prompts/skills/docx/scripts/templates/people.xml +0 -3
- package/out/base-prompts/skills/docx/scripts/utilities.py +0 -374
- package/out/base-prompts/skills/gateway-outbound/SKILL.md +0 -136
- package/out/base-prompts/skills/mcp-builder/LICENSE.txt +0 -202
- package/out/base-prompts/skills/mcp-builder/SKILL.md +0 -328
- package/out/base-prompts/skills/mcp-builder/reference/evaluation.md +0 -602
- package/out/base-prompts/skills/mcp-builder/reference/mcp_best_practices.md +0 -249
- package/out/base-prompts/skills/mcp-builder/reference/node_mcp_server.md +0 -970
- package/out/base-prompts/skills/mcp-builder/reference/python_mcp_server.md +0 -719
- package/out/base-prompts/skills/mcp-builder/scripts/connections.py +0 -151
- package/out/base-prompts/skills/mcp-builder/scripts/evaluation.py +0 -373
- package/out/base-prompts/skills/mcp-builder/scripts/example_evaluation.xml +0 -22
- package/out/base-prompts/skills/mcp-builder/scripts/requirements.txt +0 -2
- package/out/base-prompts/skills/openclaw/SKILL.md +0 -406
- package/out/base-prompts/skills/openclaw/scripts/run-smoke.sh +0 -61
- package/out/base-prompts/skills/pdf/LICENSE.txt +0 -30
- package/out/base-prompts/skills/pdf/SKILL.md +0 -294
- package/out/base-prompts/skills/pdf/forms.md +0 -205
- package/out/base-prompts/skills/pdf/reference.md +0 -612
- package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes.py +0 -70
- package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes_test.py +0 -226
- package/out/base-prompts/skills/pdf/scripts/check_fillable_fields.py +0 -12
- package/out/base-prompts/skills/pdf/scripts/convert_pdf_to_images.py +0 -35
- package/out/base-prompts/skills/pdf/scripts/create_validation_image.py +0 -41
- package/out/base-prompts/skills/pdf/scripts/extract_form_field_info.py +0 -152
- package/out/base-prompts/skills/pdf/scripts/fill_fillable_fields.py +0 -114
- package/out/base-prompts/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -108
- package/out/base-prompts/skills/pptx/LICENSE.txt +0 -30
- package/out/base-prompts/skills/pptx/SKILL.md +0 -484
- package/out/base-prompts/skills/pptx/html2pptx.md +0 -625
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/out/base-prompts/skills/pptx/ooxml/schemas/mce/mc.xsd +0 -75
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/out/base-prompts/skills/pptx/ooxml/scripts/pack.py +0 -159
- package/out/base-prompts/skills/pptx/ooxml/scripts/unpack.py +0 -29
- package/out/base-prompts/skills/pptx/ooxml/scripts/validate.py +0 -69
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/__init__.py +0 -15
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/base.py +0 -951
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/docx.py +0 -274
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/pptx.py +0 -315
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/redlining.py +0 -279
- package/out/base-prompts/skills/pptx/ooxml.md +0 -427
- package/out/base-prompts/skills/pptx/scripts/html2pptx.js +0 -984
- package/out/base-prompts/skills/pptx/scripts/inventory.py +0 -1020
- package/out/base-prompts/skills/pptx/scripts/rearrange.py +0 -231
- package/out/base-prompts/skills/pptx/scripts/replace.py +0 -385
- package/out/base-prompts/skills/pptx/scripts/thumbnail.py +0 -450
- package/out/base-prompts/skills/prompt-lab/SKILL.md +0 -149
- package/out/base-prompts/skills/prompt-lab/scripts/query-analytics.sh +0 -2551
- package/out/base-prompts/skills/skill-creator/LICENSE.txt +0 -202
- package/out/base-prompts/skills/skill-creator/SKILL.md +0 -371
- package/out/base-prompts/skills/skill-creator/references/output-patterns.md +0 -82
- package/out/base-prompts/skills/skill-creator/references/workflows.md +0 -28
- package/out/base-prompts/skills/skill-creator/scripts/init_skill.py +0 -303
- package/out/base-prompts/skills/skill-creator/scripts/package_skill.py +0 -110
- package/out/base-prompts/skills/skill-creator/scripts/quick_validate.py +0 -95
- package/out/base-prompts/skills/skill-installer/SKILL.md +0 -251
- package/out/base-prompts/skills/skill-installer/references/store-api.md +0 -219
- package/out/base-prompts/skills/spotlight-dashboard/SKILL.md +0 -83
- package/out/base-prompts/skills/spotlight-insights/SKILL.md +0 -101
- package/out/base-prompts/skills/spotlight-optimize/SKILL.md +0 -93
- package/out/base-prompts/skills/spotlight-optimize/scripts/query-analytics.sh +0 -2551
- package/out/base-prompts/skills/spotlight-query/SKILL.md +0 -314
- package/out/base-prompts/skills/spotlight-query/references/otel-schema.md +0 -163
- package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.sh +0 -2551
- package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.test.sh +0 -744
- package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/sessions/sess-test-1.jsonl +0 -14
- package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/.duckdb-index.json +0 -7
- package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/sample.jsonl +0 -5
- package/out/base-prompts/skills/spotlight-report/SKILL.md +0 -86
- package/out/base-prompts/skills/spotlight-visualize/SKILL.md +0 -92
- package/out/base-prompts/skills/spotlight-visualize/scripts/query-analytics.sh +0 -2551
- package/out/base-prompts/skills/xlsx/LICENSE.txt +0 -30
- package/out/base-prompts/skills/xlsx/SKILL.md +0 -289
- package/out/base-prompts/skills/xlsx/recalc.py +0 -178
- package/out/branding.js +0 -49
- package/out/cli/commands/anywhere.js +0 -66
- package/out/cli/commands/ask.js +0 -246
- package/out/cli/commands/auth-broker.js +0 -24
- package/out/cli/commands/auth.js +0 -219
- package/out/cli/commands/chat.js +0 -357
- package/out/cli/commands/conformance.js +0 -249
- package/out/cli/commands/data-plane.js +0 -67
- package/out/cli/commands/deploy.js +0 -263
- package/out/cli/commands/gateway.js +0 -218
- package/out/cli/commands/idp.js +0 -85
- package/out/cli/commands/pack.js +0 -399
- package/out/cli/commands/probe-custom-engine.js +0 -82
- package/out/cli/commands/sandbox.js +0 -332
- package/out/cli/commands/serve.js +0 -1758
- package/out/cli/commands/store.js +0 -927
- package/out/cli/credential-context.js +0 -91
- package/out/cli/data-plane/broker.js +0 -78
- package/out/cli/data-plane/connector-host.js +0 -121
- package/out/cli/data-plane/egress.js +0 -189
- package/out/cli/data-plane/gateway.js +0 -218
- package/out/cli/data-plane/index.js +0 -152
- package/out/cli/data-plane/registry.js +0 -89
- package/out/cli/data-plane/remote.js +0 -106
- package/out/cli/data-plane/sidecar.js +0 -161
- package/out/cli/deploy/blueprints/registry.js +0 -84
- package/out/cli/deploy/layers/identity.js +0 -172
- package/out/cli/deploy-init.js +0 -3023
- package/out/cli/deps.js +0 -342
- package/out/cli/idp-init.js +0 -338
- package/out/cli/pack-install-ref.js +0 -15
- package/out/cli/pack-loader.js +0 -418
- package/out/cli/pack-runtime.js +0 -61
- package/out/cli/runtime.js +0 -450
- package/out/cli/serve-hardening.js +0 -607
- package/out/cli/state-sync.js +0 -424
- package/out/cli/utils.js +0 -231
- package/out/engines/base.js +0 -188
- package/out/engines/claude.js +0 -1254
- package/out/engines/codex.js +0 -862
- package/out/engines/custom.js +0 -674
- package/out/engines/customEngineIpc.js +0 -95
- package/out/engines/customEngineRunnerEmbed.js +0 -107
- package/out/engines/customRegistry.js +0 -274
- package/out/engines/embeddedCustomEngineRunner.generated.js +0 -9
- package/out/engines/engineApiKey.js +0 -138
- package/out/engines/install.js +0 -372
- package/out/engines/persistentEngineWorker.js +0 -320
- package/out/engines/publish.js +0 -341
- package/out/evidence/sessionShip.js +0 -610
- package/out/gateway/bridge.js +0 -843
- package/out/gateway/cli-agent-id.js +0 -36
- package/out/gateway/client.js +0 -336
- package/out/gateway/client.test.js +0 -395
- package/out/gateway/gateway-scope-errors.js +0 -14
- package/out/gateway/gatewayBackup.js +0 -76
- package/out/gateway/installSource.js +0 -68
- package/out/gateway/lifecycle.js +0 -3190
- package/out/gateway/openclaw-channel-routing.js +0 -317
- package/out/gateway/outboundHandles.js +0 -373
- package/out/gateway/outboundPaths.js +0 -75
- package/out/gateway/outboundSend.js +0 -254
- package/out/gateway/protocol.js +0 -48
- package/out/gateway/secretsPreflight.js +0 -90
- package/out/gateway/sessionRouting.js +0 -77
- package/out/headless/index.js +0 -539
- package/out/headless/sync.js +0 -473
- package/out/live-e2e/mcp-demo/server.mjs +0 -32
- package/out/live-probe/connector.mjs +0 -8
- package/out/live-probe/env-report.mjs +0 -8
- package/out/mcp.js +0 -654
- package/out/pack/caps.js +0 -271
- package/out/pack/governor.js +0 -309
- package/out/pack/lease-schema.js +0 -270
- package/out/pack/lease.js +0 -640
- package/out/pack/reconcile.js +0 -217
- package/out/pack/signature.js +0 -839
- package/out/permissions.js +0 -108
- package/out/permissions.mapping.yaml +0 -68
- package/out/registry/index.js +0 -332
- package/out/runner/host.js +0 -131
- package/out/runner/protocol.js +0 -108
- package/out/runner/remoteEngine.js +0 -130
- package/out/runtime/interfaces/config-provider.js +0 -32
- package/out/runtime/interfaces/edit-tracker.js +0 -24
- package/out/runtime/interfaces/index.js +0 -29
- package/out/runtime/interfaces/logger.js +0 -40
- package/out/runtime/interfaces/permission-handler.js +0 -66
- package/out/runtime/interfaces/session-store.js +0 -342
- package/out/runtime/vscode/vscode-session-store.js +0 -22
- package/out/sandbox/containerDriver.js +0 -570
- package/out/sandbox/processDriver.js +0 -315
- package/out/sandbox/sandboxRunner.js +0 -191
- package/out/sandbox/support.js +0 -301
- package/out/sandbox/types.js +0 -55
- package/out/scripts/analytics/fleet-local-adapter.js +0 -246
- package/out/scripts/analytics/live-fleet-4-collector.cjs +0 -315
- package/out/scripts/analytics/live-fleet-4-daemon.mjs +0 -134
- package/out/scripts/analytics/live-fleet-4-widget.cjs +0 -433
- package/out/scripts/gateway/Dockerfile.serve +0 -45
- package/out/scripts/gateway/docker-serve.sh +0 -248
- package/out/scripts/gateway/setup-gateway-server.ps1 +0 -953
- package/out/scripts/gateway/setup-gateway-server.sh +0 -935
- package/out/session.js +0 -272
- package/out/shared/agentEngines.js +0 -170
- package/out/shared/index.js +0 -109
- package/out/shared/models.js +0 -136
- package/out/shared/providers.js +0 -205
- package/out/spotlight/install.js +0 -345
- package/out/spotlight/publish.js +0 -544
- package/out/spotlight/yaml.js +0 -31
- package/out/store/index.js +0 -786
- package/out/store/shared.js +0 -241
- package/out/test/agentEnvFile.test.js +0 -97
- package/out/test/agentYaml.test.js +0 -373
- package/out/test/agentpack.test.js +0 -639
- package/out/test/analytics-lifecycle.test.js +0 -174
- package/out/test/analytics.test.js +0 -756
- package/out/test/auth-baseurl.test.js +0 -132
- package/out/test/auth-bootstrapApply.test.js +0 -123
- package/out/test/auth-broker-hardening.test.js +0 -227
- package/out/test/auth-broker.test.js +0 -541
- package/out/test/auth-callback.test.js +0 -62
- package/out/test/blueprint-registry.test.js +0 -105
- package/out/test/branding.test.js +0 -242
- package/out/test/caps-governor.test.js +0 -455
- package/out/test/cli-agent-id.test.js +0 -55
- package/out/test/codex-new-file-survival.test.js +0 -119
- package/out/test/configuration-scopes.test.js +0 -131
- package/out/test/credential-context.test.js +0 -160
- package/out/test/custom-env-layering.test.js +0 -151
- package/out/test/customEngineInstall.test.js +0 -100
- package/out/test/customRegistry.test.js +0 -122
- package/out/test/data-plane-engine-wiring.test.js +0 -250
- package/out/test/data-plane.test.js +0 -311
- package/out/test/deploy-init.test.js +0 -854
- package/out/test/deps-auto-install.test.js +0 -81
- package/out/test/egress-broker.test.js +0 -172
- package/out/test/engine-integration.test.js +0 -297
- package/out/test/enginePaths.test.js +0 -195
- package/out/test/enginePublish.test.js +0 -82
- package/out/test/fleetDisplayUtils.test.js +0 -100
- package/out/test/gateway-client.test.js +0 -409
- package/out/test/gateway-install-source.test.js +0 -111
- package/out/test/gateway-lifecycle.test.js +0 -608
- package/out/test/gateway-outbound.test.js +0 -538
- package/out/test/gateway-reset-mappings.test.js +0 -221
- package/out/test/gateway-route-index.test.js +0 -235
- package/out/test/gateway-secrets-preflight.test.js +0 -127
- package/out/test/gateway-session-routing.test.js +0 -65
- package/out/test/gateway-session-store.test.js +0 -216
- package/out/test/github.test.js +0 -232
- package/out/test/governor-hardening.test.js +0 -217
- package/out/test/headless-sync.test.js +0 -301
- package/out/test/helpers/manifest-fixtures.js +0 -27
- package/out/test/idp-init.test.js +0 -151
- package/out/test/lease-signature.test.js +0 -357
- package/out/test/lease-trust-root.test.js +0 -273
- package/out/test/lease-validation.test.js +0 -169
- package/out/test/lease.test.js +0 -114
- package/out/test/mcp-obo.test.js +0 -107
- package/out/test/mcp.test.js +0 -389
- package/out/test/model-routing.test.js +0 -133
- package/out/test/openclaw-channel-routing.test.js +0 -191
- package/out/test/pack-admission.test.js +0 -216
- package/out/test/pack-digest-parity.test.js +0 -140
- package/out/test/pack-reconcile.test.js +0 -183
- package/out/test/pack-signature-artifact.test.js +0 -103
- package/out/test/pack-signature.test.js +0 -176
- package/out/test/pack-trust-root.test.js +0 -202
- package/out/test/pathSafety.test.js +0 -63
- package/out/test/permissions.test.js +0 -175
- package/out/test/persistent-engine-worker.test.js +0 -220
- package/out/test/refreshPolicy.test.js +0 -60
- package/out/test/registry.test.js +0 -351
- package/out/test/remote-trust.test.js +0 -242
- package/out/test/runner-protocol.test.js +0 -249
- package/out/test/runtime.test.js +0 -349
- package/out/test/sandbox-driver.test.js +0 -553
- package/out/test/sandbox-hardening.test.js +0 -395
- package/out/test/sandbox-runner.test.js +0 -343
- package/out/test/scheduledFleetStorage.test.js +0 -72
- package/out/test/serve-gateway-turn.test.js +0 -267
- package/out/test/serve-hardening.test.js +0 -418
- package/out/test/serveClient.test.js +0 -209
- package/out/test/sessionJsonlFleet.test.js +0 -78
- package/out/test/sessionShip.test.js +0 -560
- package/out/test/shared.test.js +0 -173
- package/out/test/skills-mcp.test.js +0 -299
- package/out/test/spotlightPublish.test.js +0 -327
- package/out/test/spotlightYaml.test.js +0 -58
- package/out/test/state-sync-peer.test.js +0 -156
- package/out/test/store-install-safe.test.js +0 -69
- package/out/test/store.test.js +0 -331
- package/out/test/stores.test.js +0 -504
- package/out/test/sync-switch.test.js +0 -251
- package/out/test/teamViewDiscovery.test.js +0 -90
- package/out/test/tls-bypass.test.js +0 -90
- package/out/test/toolPath.test.js +0 -120
- package/out/test/utils.test.js +0 -308
- package/out/test/viewsConfigMerge.test.js +0 -180
- package/out/test/warrant.test.js +0 -138
- package/out/test/windows-command-line.test.js +0 -75
- package/out/utils/agentEnvFile.js +0 -131
- package/out/utils/binary.js +0 -175
- package/out/utils/index.js +0 -37
- package/out/utils/network.js +0 -74
- package/out/utils/paths.js +0 -116
- package/out/utils/pid.js +0 -180
- package/out/utils/resolveNodeBinary.js +0 -168
- package/out/utils/windowsCommandLine.js +0 -29
- package/out/utils.js +0 -968
package/out/analytics/service.js
CHANGED
|
@@ -1,1277 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
/*---------------------------------------------------------------------------------------------
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
-
}
|
|
11
|
-
Object.defineProperty(o, k2, desc);
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
-
}) : function(o, v) {
|
|
19
|
-
o["default"] = v;
|
|
20
|
-
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
-
var ownKeys = function(o) {
|
|
23
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
-
var ar = [];
|
|
25
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
-
return ar;
|
|
27
|
-
};
|
|
28
|
-
return ownKeys(o);
|
|
29
|
-
};
|
|
30
|
-
return function (mod) {
|
|
31
|
-
if (mod && mod.__esModule) return mod;
|
|
32
|
-
var result = {};
|
|
33
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
-
__setModuleDefault(result, mod);
|
|
35
|
-
return result;
|
|
36
|
-
};
|
|
37
|
-
})();
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.AnalyticsService = void 0;
|
|
40
|
-
const vscode = __importStar(require("vscode"));
|
|
41
|
-
const path = __importStar(require("path"));
|
|
42
|
-
const fsSync = __importStar(require("fs"));
|
|
43
|
-
const fs_1 = require("fs");
|
|
44
|
-
const child_process_1 = require("child_process");
|
|
45
|
-
const branding_1 = require("../branding");
|
|
46
|
-
const indexingService_1 = require("./dashboard/indexingService");
|
|
47
|
-
const performanceMonitor_1 = require("./dashboard/performanceMonitor");
|
|
48
|
-
const lifecycle_1 = require("./lifecycle");
|
|
49
|
-
const index_1 = require("../utils/index");
|
|
50
|
-
const windowsCommandLine_1 = require("../utils/windowsCommandLine");
|
|
51
|
-
/**
|
|
52
|
-
* Resolve the preferred PowerShell host on Windows. PowerShell 7 (`pwsh.exe`)
|
|
53
|
-
* fixed native-command argument quoting bugs that affect inline `bash -c`
|
|
54
|
-
* scripts containing embedded double quotes. We prefer it when present and
|
|
55
|
-
* fall back to the always-present Windows PowerShell 5.1 (`powershell.exe`).
|
|
56
|
-
*
|
|
57
|
-
* Cached for the lifetime of the extension host — pwsh install state is not
|
|
58
|
-
* expected to change mid-session, and the lookup hits the filesystem.
|
|
59
|
-
*/
|
|
60
|
-
let cachedWindowsPwshPath;
|
|
61
|
-
function getWindowsPwshOrPowerShell() {
|
|
62
|
-
if (process.platform !== 'win32') {
|
|
63
|
-
return 'powershell.exe';
|
|
64
|
-
}
|
|
65
|
-
if (cachedWindowsPwshPath === undefined) {
|
|
66
|
-
cachedWindowsPwshPath = resolvePwshExecutable();
|
|
67
|
-
}
|
|
68
|
-
return cachedWindowsPwshPath ?? 'powershell.exe';
|
|
69
|
-
}
|
|
70
|
-
function resolvePwshExecutable() {
|
|
71
|
-
const candidates = [];
|
|
72
|
-
const pathDirs = (process.env.PATH ?? '').split(path.delimiter).filter(Boolean);
|
|
73
|
-
for (const dir of pathDirs) {
|
|
74
|
-
candidates.push(path.join(dir, 'pwsh.exe'));
|
|
75
|
-
}
|
|
76
|
-
const programFiles = process.env.ProgramFiles ?? 'C:\\Program Files';
|
|
77
|
-
const programFilesX86 = process.env['ProgramFiles(x86)'] ?? 'C:\\Program Files (x86)';
|
|
78
|
-
const localAppData = process.env.LOCALAPPDATA;
|
|
79
|
-
for (const major of ['7', '8']) {
|
|
80
|
-
candidates.push(path.join(programFiles, 'PowerShell', major, 'pwsh.exe'));
|
|
81
|
-
candidates.push(path.join(programFilesX86, 'PowerShell', major, 'pwsh.exe'));
|
|
82
|
-
}
|
|
83
|
-
if (localAppData) {
|
|
84
|
-
candidates.push(path.join(localAppData, 'Microsoft', 'PowerShell', 'pwsh.exe'));
|
|
85
|
-
}
|
|
86
|
-
for (const candidate of candidates) {
|
|
87
|
-
try {
|
|
88
|
-
if (fsSync.statSync(candidate).isFile()) {
|
|
89
|
-
return candidate;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
catch {
|
|
93
|
-
// not present; continue
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return null;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Manages LiteLLM Spotlight (OTEL Collector + DuckDB analytics).
|
|
100
|
-
* Provides status bar indicator and commands for managing the analytics stack.
|
|
101
|
-
*/
|
|
102
|
-
class AnalyticsService {
|
|
103
|
-
statusBarItem;
|
|
104
|
-
outputChannel;
|
|
105
|
-
extensionContext;
|
|
106
|
-
_status = 'stopped';
|
|
107
|
-
_lastStackStatus = { otelRunning: false, litellmRunning: false, litellmWithOtel: false };
|
|
108
|
-
indexProgress = { status: 'idle', percent: 0 };
|
|
109
|
-
indexingService;
|
|
110
|
-
performanceMonitor;
|
|
111
|
-
disposables = [];
|
|
112
|
-
lifecycleInProgress = false;
|
|
113
|
-
/**
|
|
114
|
-
* Get the current status of the analytics stack.
|
|
115
|
-
*/
|
|
116
|
-
get status() {
|
|
117
|
-
return this._status;
|
|
118
|
-
}
|
|
119
|
-
healthCheckTimer = null;
|
|
120
|
-
static HEALTH_CHECK_INTERVAL = 30000; // 30 seconds
|
|
121
|
-
constructor(extensionContext, outputChannel) {
|
|
122
|
-
this.extensionContext = extensionContext;
|
|
123
|
-
this.outputChannel = outputChannel;
|
|
124
|
-
this.performanceMonitor = new performanceMonitor_1.PerformanceMonitor(outputChannel);
|
|
125
|
-
// Create status bar item
|
|
126
|
-
this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 99);
|
|
127
|
-
this.statusBarItem.command = 'agentide.analytics.toggle';
|
|
128
|
-
// Register commands
|
|
129
|
-
this.registerCommands();
|
|
130
|
-
// Check if analytics has ever been configured before starting heartbeat
|
|
131
|
-
void this.initializeWithLazyHeartbeat();
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Initialize with lazy heartbeat - only start periodic checks if analytics is configured.
|
|
135
|
-
* This avoids unnecessary process spawning (pgrep) when user hasn't set up analytics.
|
|
136
|
-
*/
|
|
137
|
-
async initializeWithLazyHeartbeat() {
|
|
138
|
-
const isConfigured = await this.isAnalyticsConfigured();
|
|
139
|
-
if (isConfigured) {
|
|
140
|
-
// Analytics was set up - do full check and start heartbeat
|
|
141
|
-
this.updateStatusBar('checking');
|
|
142
|
-
await this.checkStatus();
|
|
143
|
-
this.startHeartbeat();
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
// Not configured - show stopped, no heartbeat needed
|
|
147
|
-
this.updateStatusBar('stopped');
|
|
148
|
-
this.statusBarItem.show();
|
|
149
|
-
// Still check for standalone LiteLLM (not tied to analytics)
|
|
150
|
-
// This allows Language Models table to populate even without analytics setup
|
|
151
|
-
await this.detectStandaloneLiteLLM();
|
|
152
|
-
}
|
|
153
|
-
// Initialize background indexing service for dashboard
|
|
154
|
-
await this.initializeIndexingService();
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Initialize background indexing service.
|
|
158
|
-
*/
|
|
159
|
-
async initializeIndexingService() {
|
|
160
|
-
try {
|
|
161
|
-
const analyticsDir = this.getAnalyticsDir();
|
|
162
|
-
const tracesDir = path.join(analyticsDir, 'traces');
|
|
163
|
-
this.indexingService = new indexingService_1.IndexingService(tracesDir, this.outputChannel, this.performanceMonitor);
|
|
164
|
-
// Subscribe to indexing progress updates
|
|
165
|
-
this.disposables.push(this.indexingService.onProgressChange((progress) => {
|
|
166
|
-
this.indexProgress = progress;
|
|
167
|
-
this.updateStatusBar(this._status); // Refresh status bar with new progress
|
|
168
|
-
}));
|
|
169
|
-
// Initialize indexing service (starts file watcher, checks if re-indexing needed)
|
|
170
|
-
await this.indexingService.initialize();
|
|
171
|
-
}
|
|
172
|
-
catch (error) {
|
|
173
|
-
this.outputChannel.appendLine(`[Analytics] Failed to initialize indexing service: ${error}`);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Get IndexingService instance (for provider integration).
|
|
178
|
-
*/
|
|
179
|
-
getIndexingService() {
|
|
180
|
-
return this.indexingService;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Detect standalone LiteLLM (running without analytics) and update base URL setting.
|
|
184
|
-
* This is a one-time check on startup to enable model discovery even when analytics
|
|
185
|
-
* is not configured.
|
|
186
|
-
*/
|
|
187
|
-
async detectStandaloneLiteLLM() {
|
|
188
|
-
try {
|
|
189
|
-
const status = await this.getLiteLLMStatus();
|
|
190
|
-
if (status.running) {
|
|
191
|
-
this.outputChannel.appendLine('[Analytics] Detected standalone LiteLLM running');
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
catch {
|
|
195
|
-
// Best-effort only - don't block startup
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Check if analytics has been configured (config files exist).
|
|
200
|
-
* This is a fast check that doesn't spawn any processes.
|
|
201
|
-
*/
|
|
202
|
-
async isAnalyticsConfigured() {
|
|
203
|
-
const analyticsDir = this.getAnalyticsDir();
|
|
204
|
-
const configPath = path.join(analyticsDir, 'config', 'otel-collector.yaml');
|
|
205
|
-
try {
|
|
206
|
-
await fs_1.promises.access(configPath);
|
|
207
|
-
return true;
|
|
208
|
-
}
|
|
209
|
-
catch {
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Start the periodic heartbeat timer.
|
|
215
|
-
*/
|
|
216
|
-
startHeartbeat() {
|
|
217
|
-
if (this.healthCheckTimer) {
|
|
218
|
-
return; // Already running
|
|
219
|
-
}
|
|
220
|
-
this.healthCheckTimer = setInterval(() => {
|
|
221
|
-
void this.checkStatus();
|
|
222
|
-
}, AnalyticsService.HEALTH_CHECK_INTERVAL);
|
|
223
|
-
}
|
|
224
|
-
registerCommands() {
|
|
225
|
-
this.disposables.push(vscode.commands.registerCommand('agentide.analytics.toggle', () => this.toggle()), vscode.commands.registerCommand('agentide.analytics.restart', () => this.restart()), vscode.commands.registerCommand('agentide.analytics.start', () => this.start()), vscode.commands.registerCommand('agentide.analytics.stop', () => this.stop()), vscode.commands.registerCommand('agentide.analytics.status', () => this.showStatus()), vscode.commands.registerCommand('agentide.analytics.query', () => this.openQueryTerminal()), vscode.commands.registerCommand('agentide.analytics.openLiteLLMConfig', () => this.openLiteLLMConfig()),
|
|
226
|
-
// Returns true if the full analytics stack is running (used by core to skip redundant setup prompts)
|
|
227
|
-
vscode.commands.registerCommand('agentide.analytics.isRunning', () => this.checkStatus()));
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Get the analytics home directory.
|
|
231
|
-
* Uses shared path utility for consistency.
|
|
232
|
-
*/
|
|
233
|
-
getAnalyticsDir() {
|
|
234
|
-
return index_1.DIRS.analytics();
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Get the PID file path for OTEL Collector.
|
|
238
|
-
* Uses shared PID_FILES constant for consistency.
|
|
239
|
-
*/
|
|
240
|
-
getOtelPidFile() {
|
|
241
|
-
return index_1.PID_FILES.otelcol();
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Get the PID file path for LiteLLM.
|
|
245
|
-
* Uses shared PID_FILES constant for consistency.
|
|
246
|
-
*/
|
|
247
|
-
getLiteLLMPidFile() {
|
|
248
|
-
return index_1.PID_FILES.litellm();
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Check full analytics stack status (OTEL Collector + LiteLLM).
|
|
252
|
-
* Returns true only if both services are properly configured.
|
|
253
|
-
*/
|
|
254
|
-
async checkStatus() {
|
|
255
|
-
try {
|
|
256
|
-
const stackStatus = await this.getStackStatus();
|
|
257
|
-
this._lastStackStatus = stackStatus;
|
|
258
|
-
if (stackStatus.otelRunning && stackStatus.litellmWithOtel) {
|
|
259
|
-
// Full stack running properly
|
|
260
|
-
this.updateStatusBar('running');
|
|
261
|
-
return true;
|
|
262
|
-
}
|
|
263
|
-
else if (this.lifecycleInProgress) {
|
|
264
|
-
// During an explicit start/setup/restart, OTEL commonly becomes visible
|
|
265
|
-
// before LiteLLM has written its PID metadata. Keep the UI in a
|
|
266
|
-
// starting state until readiness monitoring completes.
|
|
267
|
-
this.updateStatusBar('checking');
|
|
268
|
-
return false;
|
|
269
|
-
}
|
|
270
|
-
else if (stackStatus.otelRunning || stackStatus.litellmRunning) {
|
|
271
|
-
// Partial - something is running but not fully configured
|
|
272
|
-
this.updateStatusBar('partial');
|
|
273
|
-
return false;
|
|
274
|
-
}
|
|
275
|
-
else {
|
|
276
|
-
// Nothing running
|
|
277
|
-
this.updateStatusBar('stopped');
|
|
278
|
-
return false;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
catch {
|
|
282
|
-
this.updateStatusBar('error');
|
|
283
|
-
return false;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Get detailed status of each analytics component.
|
|
288
|
-
*/
|
|
289
|
-
async getStackStatus() {
|
|
290
|
-
const otelRunning = await this.isOtelRunning();
|
|
291
|
-
const litellmStatus = await this.getLiteLLMStatus();
|
|
292
|
-
return {
|
|
293
|
-
otelRunning,
|
|
294
|
-
litellmRunning: litellmStatus.running,
|
|
295
|
-
litellmWithOtel: litellmStatus.withOtel,
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Check if OTEL Collector is running via PID file.
|
|
300
|
-
* Cost: ~1-2ms (file read + signal check, no process spawn)
|
|
301
|
-
* Also cleans up stale PID files per ARCHITECTURE.md pattern.
|
|
302
|
-
*/
|
|
303
|
-
async isOtelRunning() {
|
|
304
|
-
const result = await (0, index_1.checkPidFileWithCleanup)(this.getOtelPidFile());
|
|
305
|
-
return result !== null;
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Check LiteLLM status via the canonical PID file written by agentide-litellm.{sh,ps1}.
|
|
309
|
-
* Cost: ~1-2ms (file read + signal check, no process spawn).
|
|
310
|
-
*
|
|
311
|
-
* PID file format: "PID\n[otel]\n[url=...]". Process detection / killing across
|
|
312
|
-
* platforms (incl. winpid) is handled inside the launcher script — this code only
|
|
313
|
-
* trusts what the launcher wrote.
|
|
314
|
-
*/
|
|
315
|
-
async getLiteLLMStatus() {
|
|
316
|
-
const pidData = await (0, index_1.checkPidFileWithCleanup)(this.getLiteLLMPidFile());
|
|
317
|
-
if (!pidData) {
|
|
318
|
-
return { running: false, withOtel: false };
|
|
319
|
-
}
|
|
320
|
-
const metadata = pidData.metadata ?? [];
|
|
321
|
-
const withOtel = metadata.some(line => line.trim().toLowerCase() === 'otel');
|
|
322
|
-
const urlLine = metadata.find(line => line.startsWith('url='));
|
|
323
|
-
if (urlLine) {
|
|
324
|
-
await this.maybeUpdateLiteLLMBaseUrlValue(urlLine.slice('url='.length).trim());
|
|
325
|
-
}
|
|
326
|
-
return { running: true, withOtel };
|
|
327
|
-
}
|
|
328
|
-
async maybeUpdateLiteLLMBaseUrlValue(baseUrl) {
|
|
329
|
-
const config = vscode.workspace.getConfiguration('agentide.providers.litellm');
|
|
330
|
-
if (config.get('baseUrl')?.trim()) {
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
const trimmed = baseUrl.trim();
|
|
334
|
-
if (!trimmed) {
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
await config.update('baseUrl', trimmed, vscode.ConfigurationTarget.Global);
|
|
338
|
-
this.outputChannel.appendLine(`[Analytics] Auto-detected LiteLLM base URL: ${trimmed}`);
|
|
339
|
-
}
|
|
340
|
-
async waitForStackReady(timeoutMs = 30_000, intervalMs = 1_000) {
|
|
341
|
-
const deadline = Date.now() + timeoutMs;
|
|
342
|
-
let lastStatus = await this.getStackStatus();
|
|
343
|
-
while (Date.now() < deadline) {
|
|
344
|
-
lastStatus = await this.getStackStatus();
|
|
345
|
-
this._lastStackStatus = lastStatus;
|
|
346
|
-
if (lastStatus.otelRunning && lastStatus.litellmWithOtel) {
|
|
347
|
-
return lastStatus;
|
|
348
|
-
}
|
|
349
|
-
await new Promise(resolve => setTimeout(resolve, intervalMs));
|
|
350
|
-
}
|
|
351
|
-
return lastStatus;
|
|
352
|
-
}
|
|
353
|
-
async waitForStackStopped(timeoutMs = 15_000, intervalMs = 500) {
|
|
354
|
-
const deadline = Date.now() + timeoutMs;
|
|
355
|
-
let lastStatus = await this.getStackStatus();
|
|
356
|
-
while (Date.now() < deadline) {
|
|
357
|
-
lastStatus = await this.getStackStatus();
|
|
358
|
-
this._lastStackStatus = lastStatus;
|
|
359
|
-
if (!lastStatus.otelRunning && !lastStatus.litellmRunning) {
|
|
360
|
-
return lastStatus;
|
|
361
|
-
}
|
|
362
|
-
await new Promise(resolve => setTimeout(resolve, intervalMs));
|
|
363
|
-
}
|
|
364
|
-
return lastStatus;
|
|
365
|
-
}
|
|
366
|
-
async monitorStartupReadiness(reason) {
|
|
367
|
-
const stackStatus = await this.waitForStackReady();
|
|
368
|
-
this._lastStackStatus = stackStatus;
|
|
369
|
-
const status = this.deriveStatusFrom(stackStatus);
|
|
370
|
-
this.lifecycleInProgress = false;
|
|
371
|
-
this.updateStatusBar(status);
|
|
372
|
-
if (status === 'running') {
|
|
373
|
-
this.log(`Analytics stack ready after ${reason}.`);
|
|
374
|
-
vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight ${reason === 'restart' ? 'restarted' : 'started'}.`);
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
this.log(`Analytics stack not fully ready after ${reason} ` +
|
|
378
|
-
`(otel=${stackStatus.otelRunning}, litellm=${stackStatus.litellmRunning}, litellmWithOtel=${stackStatus.litellmWithOtel})`);
|
|
379
|
-
const choice = await vscode.window.showWarningMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight ${reason === 'restart' ? 'restart' : 'start'} is not fully ready yet.`, 'Show Status');
|
|
380
|
-
if (choice === 'Show Status') {
|
|
381
|
-
await this.showStatus();
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
async monitorStopReadiness() {
|
|
385
|
-
const stackStatus = await this.waitForStackStopped();
|
|
386
|
-
this._lastStackStatus = stackStatus;
|
|
387
|
-
const status = this.deriveStatusFrom(stackStatus);
|
|
388
|
-
this.lifecycleInProgress = false;
|
|
389
|
-
this.updateStatusBar(status);
|
|
390
|
-
if (status === 'stopped') {
|
|
391
|
-
this.log('Analytics stack stopped.');
|
|
392
|
-
vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight stopped.`);
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
this.log(`Analytics stack not fully stopped ` +
|
|
396
|
-
`(otel=${stackStatus.otelRunning}, litellm=${stackStatus.litellmRunning}, litellmWithOtel=${stackStatus.litellmWithOtel})`);
|
|
397
|
-
const choice = await vscode.window.showWarningMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight stop is not fully complete yet.`, 'Show Status');
|
|
398
|
-
if (choice === 'Show Status') {
|
|
399
|
-
await this.showStatus();
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Handle status bar click.
|
|
404
|
-
* Always open a menu instantly from cached state.
|
|
405
|
-
* Heavy checks/actions run only after explicit user choice.
|
|
406
|
-
*/
|
|
407
|
-
async toggle() {
|
|
408
|
-
// Don't block the click on a foreground check; act on the cached snapshot.
|
|
409
|
-
const status = this._status === 'checking'
|
|
410
|
-
? this.deriveStatusFrom(this._lastStackStatus)
|
|
411
|
-
: this._status;
|
|
412
|
-
if (status === 'running') {
|
|
413
|
-
await this.showStatusWithRestartOption();
|
|
414
|
-
}
|
|
415
|
-
else if (status === 'partial') {
|
|
416
|
-
await this.showPartialStatusOption();
|
|
417
|
-
}
|
|
418
|
-
else {
|
|
419
|
-
await this.showStoppedStatusOption(status);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
queueBackgroundStatusRefresh(reason) {
|
|
423
|
-
if (this.lifecycleInProgress) {
|
|
424
|
-
return;
|
|
425
|
-
}
|
|
426
|
-
setTimeout(() => {
|
|
427
|
-
if (this.lifecycleInProgress) {
|
|
428
|
-
return;
|
|
429
|
-
}
|
|
430
|
-
void this.checkStatus().catch((err) => {
|
|
431
|
-
this.log(`Background status refresh failed after ${reason}: ${err instanceof Error ? err.message : String(err)}`);
|
|
432
|
-
});
|
|
433
|
-
}, 100);
|
|
434
|
-
}
|
|
435
|
-
deriveStatusFrom(s) {
|
|
436
|
-
return (0, lifecycle_1.deriveAnalyticsStatus)(s);
|
|
437
|
-
}
|
|
438
|
-
/**
|
|
439
|
-
* Show options when in partial state (something running but not fully configured).
|
|
440
|
-
*/
|
|
441
|
-
async showPartialStatusOption() {
|
|
442
|
-
const stackStatus = this._lastStackStatus;
|
|
443
|
-
const message = (0, lifecycle_1.getPartialSpotlightMessage)(stackStatus);
|
|
444
|
-
const choicePromise = vscode.window.showWarningMessage(`${branding_1.AGENTIDE_BRAND_NAME}: ${message}`, 'Install', 'Restart All', 'Show Status');
|
|
445
|
-
this.queueBackgroundStatusRefresh('opening partial menu');
|
|
446
|
-
const choice = await choicePromise;
|
|
447
|
-
switch (choice) {
|
|
448
|
-
case 'Install':
|
|
449
|
-
await vscode.commands.executeCommand('agentide.setupAnalytics');
|
|
450
|
-
break;
|
|
451
|
-
case 'Restart All':
|
|
452
|
-
await this.restart();
|
|
453
|
-
break;
|
|
454
|
-
case 'Show Status':
|
|
455
|
-
await this.showStatus();
|
|
456
|
-
break;
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
/**
|
|
460
|
-
* Show status summary and offer to restart.
|
|
461
|
-
*/
|
|
462
|
-
async showStatusWithRestartOption() {
|
|
463
|
-
const choicePromise = vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME} Spotlight is running.`, 'See Spotlight', 'Restart All', 'Stop', 'Indexing', 'Show Status');
|
|
464
|
-
this.queueBackgroundStatusRefresh('opening running menu');
|
|
465
|
-
const choice = await choicePromise;
|
|
466
|
-
switch (choice) {
|
|
467
|
-
case 'See Spotlight':
|
|
468
|
-
await vscode.commands.executeCommand('agentide.analytics.openDashboard');
|
|
469
|
-
break;
|
|
470
|
-
case 'Restart All':
|
|
471
|
-
await this.restart();
|
|
472
|
-
break;
|
|
473
|
-
case 'Stop':
|
|
474
|
-
await this.stop();
|
|
475
|
-
break;
|
|
476
|
-
case 'Indexing':
|
|
477
|
-
await this.triggerIndexing();
|
|
478
|
-
break;
|
|
479
|
-
case 'Show Status':
|
|
480
|
-
await this.showStatus();
|
|
481
|
-
break;
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
/**
|
|
485
|
-
* Restart the analytics stack: stop LiteLLM, restart OTEL via terminal, start LiteLLM detached.
|
|
486
|
-
*/
|
|
487
|
-
async restart() {
|
|
488
|
-
this.log('Restarting analytics stack...');
|
|
489
|
-
this.lifecycleInProgress = true;
|
|
490
|
-
this.updateStatusBar('checking');
|
|
491
|
-
if (!(await this.isAnalyticsConfigured())) {
|
|
492
|
-
await this.start();
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
const isWindows = process.platform === 'win32';
|
|
496
|
-
const startScript = await this.findScript(isWindows ? 'start-analytics.ps1' : 'start-analytics.sh');
|
|
497
|
-
if (!startScript) {
|
|
498
|
-
this.lifecycleInProgress = false;
|
|
499
|
-
this.updateStatusBar('error');
|
|
500
|
-
vscode.window.showErrorMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight scripts not found. Run Install first.`);
|
|
501
|
-
return;
|
|
502
|
-
}
|
|
503
|
-
const terminal = await this.createSpotlightLifecycleTerminal('Spotlight Restart', 'restart', startScript);
|
|
504
|
-
terminal.show();
|
|
505
|
-
this.updateStatusBar('checking');
|
|
506
|
-
this.startHeartbeat();
|
|
507
|
-
void this.monitorStartupReadiness('restart');
|
|
508
|
-
}
|
|
509
|
-
/**
|
|
510
|
-
* Run Windows setup end-to-end from the extension, then start LiteLLM via
|
|
511
|
-
* the existing launcher path. Unix setup remains script-owned for now.
|
|
512
|
-
*/
|
|
513
|
-
async setupWindowsSpotlight(options = {}) {
|
|
514
|
-
if (process.platform !== 'win32') {
|
|
515
|
-
return { success: false, error: 'Windows-only setup flow invoked on a non-Windows platform.' };
|
|
516
|
-
}
|
|
517
|
-
const setupScript = await this.findScript('setup-analytics.ps1');
|
|
518
|
-
if (!setupScript) {
|
|
519
|
-
const message = `${branding_1.AGENTIDE_BRAND_NAME}: Spotlight install script not found.`;
|
|
520
|
-
vscode.window.showErrorMessage(message);
|
|
521
|
-
return { success: false, error: message };
|
|
522
|
-
}
|
|
523
|
-
this.lifecycleInProgress = true;
|
|
524
|
-
this.updateStatusBar('checking');
|
|
525
|
-
this.outputChannel.show(true);
|
|
526
|
-
this.log(`${options.reinstall ? 'Reinstalling' : 'Installing/repairing'} Spotlight on Windows...`);
|
|
527
|
-
vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: ${options.reinstall ? 'Reinstalling' : 'Installing'} Spotlight...`);
|
|
528
|
-
try {
|
|
529
|
-
if (options.reinstall) {
|
|
530
|
-
this.log('Stopping LiteLLM before reinstall...');
|
|
531
|
-
await this.stopLiteLLMDirectly();
|
|
532
|
-
}
|
|
533
|
-
const setupOk = await this.runWindowsSetupScript(setupScript);
|
|
534
|
-
if (!setupOk) {
|
|
535
|
-
throw new Error('setup-analytics.ps1 failed');
|
|
536
|
-
}
|
|
537
|
-
const litellmStatus = await this.getLiteLLMStatus();
|
|
538
|
-
if (litellmStatus.running) {
|
|
539
|
-
this.log('Restarting LiteLLM to apply Spotlight config...');
|
|
540
|
-
await this.stopLiteLLMDirectly();
|
|
541
|
-
}
|
|
542
|
-
this.log('Starting LiteLLM proxy via IDE-managed launcher...');
|
|
543
|
-
const litellmStarted = await this.startLiteLLMDirectly();
|
|
544
|
-
if (!litellmStarted) {
|
|
545
|
-
throw new Error('LiteLLM launcher did not start');
|
|
546
|
-
}
|
|
547
|
-
const analyticsDir = this.getAnalyticsDir();
|
|
548
|
-
this.log(`LiteLLM logs: ${path.join(analyticsDir, 'litellm.log')}`);
|
|
549
|
-
this.log(`LiteLLM errors: ${path.join(analyticsDir, 'litellm.error.log')}`);
|
|
550
|
-
this.startHeartbeat();
|
|
551
|
-
void this.monitorStartupReadiness(options.reinstall ? 'restart' : 'start');
|
|
552
|
-
return { success: true };
|
|
553
|
-
}
|
|
554
|
-
catch (error) {
|
|
555
|
-
this.lifecycleInProgress = false;
|
|
556
|
-
this.updateStatusBar('error');
|
|
557
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
558
|
-
this.log(`Windows Spotlight install failed: ${message}`);
|
|
559
|
-
vscode.window.showErrorMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight install failed. ${message}`);
|
|
560
|
-
return { success: false, error: message };
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
/**
|
|
564
|
-
* Show options when Spotlight is stopped/unknown.
|
|
565
|
-
*/
|
|
566
|
-
async showStoppedStatusOption(status) {
|
|
567
|
-
const message = status === 'error'
|
|
568
|
-
? `${branding_1.AGENTIDE_BRAND_NAME}: Spotlight status is unavailable.`
|
|
569
|
-
: `${branding_1.AGENTIDE_BRAND_NAME}: Spotlight is stopped.`;
|
|
570
|
-
const choicePromise = vscode.window.showInformationMessage(message, 'Start', 'Install', 'See Spotlight', 'Show Status');
|
|
571
|
-
this.queueBackgroundStatusRefresh('opening stopped menu');
|
|
572
|
-
const choice = await choicePromise;
|
|
573
|
-
switch (choice) {
|
|
574
|
-
case 'Start':
|
|
575
|
-
await this.start();
|
|
576
|
-
break;
|
|
577
|
-
case 'Install':
|
|
578
|
-
await vscode.commands.executeCommand('agentide.setupAnalytics');
|
|
579
|
-
break;
|
|
580
|
-
case 'See Spotlight':
|
|
581
|
-
await vscode.commands.executeCommand('agentide.analytics.openDashboard');
|
|
582
|
-
break;
|
|
583
|
-
case 'Show Status':
|
|
584
|
-
await this.showStatus();
|
|
585
|
-
break;
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
async runWindowsSetupScript(scriptPath) {
|
|
589
|
-
const agentHomeDir = (0, index_1.getAgentideHome)();
|
|
590
|
-
const args = [
|
|
591
|
-
'-NoProfile',
|
|
592
|
-
'-NonInteractive',
|
|
593
|
-
'-ExecutionPolicy',
|
|
594
|
-
'Bypass',
|
|
595
|
-
'-File',
|
|
596
|
-
scriptPath,
|
|
597
|
-
'-Yes',
|
|
598
|
-
];
|
|
599
|
-
this.log(`Running ${path.basename(scriptPath)} -Yes...`);
|
|
600
|
-
return new Promise((resolve) => {
|
|
601
|
-
let settled = false;
|
|
602
|
-
const finish = (ok) => {
|
|
603
|
-
if (settled) {
|
|
604
|
-
return;
|
|
605
|
-
}
|
|
606
|
-
settled = true;
|
|
607
|
-
resolve(ok);
|
|
608
|
-
};
|
|
609
|
-
const child = (0, child_process_1.spawn)(getWindowsPwshOrPowerShell(), args, {
|
|
610
|
-
cwd: path.dirname(scriptPath),
|
|
611
|
-
env: { ...process.env, AGENT_HOME_DIR: agentHomeDir },
|
|
612
|
-
windowsHide: true,
|
|
613
|
-
});
|
|
614
|
-
child.stdout?.on('data', data => {
|
|
615
|
-
this.outputChannel.append(data.toString());
|
|
616
|
-
});
|
|
617
|
-
child.stderr?.on('data', data => {
|
|
618
|
-
this.outputChannel.append(data.toString());
|
|
619
|
-
});
|
|
620
|
-
child.once('error', err => {
|
|
621
|
-
this.log(`Windows setup script failed to spawn: ${err.message}`);
|
|
622
|
-
finish(false);
|
|
623
|
-
});
|
|
624
|
-
child.once('exit', code => {
|
|
625
|
-
if (code === 0) {
|
|
626
|
-
this.log('Windows Spotlight install script completed.');
|
|
627
|
-
finish(true);
|
|
628
|
-
}
|
|
629
|
-
else {
|
|
630
|
-
this.log(`Windows Spotlight install script exited with code ${code ?? 'unknown'}.`);
|
|
631
|
-
finish(false);
|
|
632
|
-
}
|
|
633
|
-
});
|
|
634
|
-
});
|
|
635
|
-
}
|
|
636
|
-
/**
|
|
637
|
-
* Start the OTEL Collector.
|
|
638
|
-
*/
|
|
639
|
-
async start() {
|
|
640
|
-
const isRunning = await this.checkStatus();
|
|
641
|
-
if (isRunning) {
|
|
642
|
-
vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight is already running.`);
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
// Find the start script (platform-specific)
|
|
646
|
-
const isWindows = process.platform === 'win32';
|
|
647
|
-
const scriptPath = await this.findScript(isWindows ? 'start-analytics.ps1' : 'start-analytics.sh');
|
|
648
|
-
if (!scriptPath) {
|
|
649
|
-
this.lifecycleInProgress = false;
|
|
650
|
-
vscode.window.showErrorMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight scripts not found. Run Install first.`);
|
|
651
|
-
return;
|
|
652
|
-
}
|
|
653
|
-
this.lifecycleInProgress = true;
|
|
654
|
-
this.updateStatusBar('checking');
|
|
655
|
-
const terminal = await this.createSpotlightLifecycleTerminal('Spotlight Start', 'start', scriptPath);
|
|
656
|
-
terminal.show();
|
|
657
|
-
this.log('Starting Spotlight (OTEL Collector + LiteLLM)...');
|
|
658
|
-
vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Starting Spotlight...`);
|
|
659
|
-
this.updateStatusBar('checking');
|
|
660
|
-
// Start heartbeat if not already running (user just set up analytics)
|
|
661
|
-
this.startHeartbeat();
|
|
662
|
-
void this.monitorStartupReadiness('start');
|
|
663
|
-
}
|
|
664
|
-
/**
|
|
665
|
-
* Stop the OTEL Collector.
|
|
666
|
-
*/
|
|
667
|
-
async stop() {
|
|
668
|
-
this.lifecycleInProgress = true;
|
|
669
|
-
this.updateStatusBar('checking');
|
|
670
|
-
// Find the start script (which also handles stopping)
|
|
671
|
-
const isWindows = process.platform === 'win32';
|
|
672
|
-
const scriptPath = await this.findScript(isWindows ? 'start-analytics.ps1' : 'start-analytics.sh');
|
|
673
|
-
if (!scriptPath) {
|
|
674
|
-
// Try to stop directly via PID
|
|
675
|
-
await this.stopDirectly();
|
|
676
|
-
this.lifecycleInProgress = false;
|
|
677
|
-
return;
|
|
678
|
-
}
|
|
679
|
-
// Run the stop command with visible output
|
|
680
|
-
const terminal = await this.createSpotlightLifecycleTerminal('Spotlight Stop', 'stop', scriptPath);
|
|
681
|
-
terminal.show();
|
|
682
|
-
this.log('Stopping Spotlight (OTEL Collector + LiteLLM)...');
|
|
683
|
-
this.updateStatusBar('checking');
|
|
684
|
-
void this.monitorStopReadiness();
|
|
685
|
-
}
|
|
686
|
-
/**
|
|
687
|
-
* Stop OTEL Collector directly via PID file.
|
|
688
|
-
*/
|
|
689
|
-
async stopDirectly() {
|
|
690
|
-
try {
|
|
691
|
-
const pidFile = this.getOtelPidFile();
|
|
692
|
-
const pidContent = await fs_1.promises.readFile(pidFile, 'utf8');
|
|
693
|
-
const pid = parseInt(pidContent.trim(), 10);
|
|
694
|
-
if (!isNaN(pid)) {
|
|
695
|
-
process.kill(pid, 'SIGTERM');
|
|
696
|
-
await fs_1.promises.unlink(pidFile).catch(() => { });
|
|
697
|
-
this.log(`Stopped OTEL Collector (PID: ${pid})`);
|
|
698
|
-
}
|
|
699
|
-
await this.stopLiteLLMDirectly();
|
|
700
|
-
this.updateStatusBar('stopped');
|
|
701
|
-
}
|
|
702
|
-
catch (error) {
|
|
703
|
-
this.log(`Failed to stop directly: ${error}`);
|
|
704
|
-
this.updateStatusBar('error');
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
async createSpotlightLifecycleTerminal(name, action, startScript) {
|
|
708
|
-
const agentHomeDir = (0, index_1.getAgentideHome)();
|
|
709
|
-
const analyticsDir = path.join(agentHomeDir, 'analytics');
|
|
710
|
-
fsSync.mkdirSync(analyticsDir, { recursive: true });
|
|
711
|
-
const litellmScript = await this.findLiteLLMScript();
|
|
712
|
-
const configPath = path.join(agentHomeDir, 'litellm-otel.yaml');
|
|
713
|
-
const stdoutPath = path.join(analyticsDir, 'litellm.log');
|
|
714
|
-
const stderrPath = path.join(analyticsDir, 'litellm.error.log');
|
|
715
|
-
if (process.platform === 'win32') {
|
|
716
|
-
return vscode.window.createTerminal({
|
|
717
|
-
name,
|
|
718
|
-
cwd: path.dirname(startScript),
|
|
719
|
-
env: { AGENT_HOME_DIR: agentHomeDir },
|
|
720
|
-
shellPath: getWindowsPwshOrPowerShell(),
|
|
721
|
-
shellArgs: [
|
|
722
|
-
'-NoProfile',
|
|
723
|
-
'-NoExit',
|
|
724
|
-
'-ExecutionPolicy',
|
|
725
|
-
'Bypass',
|
|
726
|
-
'-Command',
|
|
727
|
-
this.buildWindowsSpotlightLifecycleCommand({
|
|
728
|
-
action,
|
|
729
|
-
startScript,
|
|
730
|
-
litellmScript,
|
|
731
|
-
agentHomeDir,
|
|
732
|
-
configPath,
|
|
733
|
-
stdoutPath,
|
|
734
|
-
stderrPath,
|
|
735
|
-
}),
|
|
736
|
-
],
|
|
737
|
-
});
|
|
738
|
-
}
|
|
739
|
-
return vscode.window.createTerminal({
|
|
740
|
-
name,
|
|
741
|
-
cwd: path.dirname(startScript),
|
|
742
|
-
env: { AGENT_HOME_DIR: agentHomeDir },
|
|
743
|
-
shellPath: '/bin/bash',
|
|
744
|
-
shellArgs: [
|
|
745
|
-
'-c',
|
|
746
|
-
this.buildUnixSpotlightLifecycleCommand({
|
|
747
|
-
action,
|
|
748
|
-
startScript,
|
|
749
|
-
litellmScript,
|
|
750
|
-
agentHomeDir,
|
|
751
|
-
configPath,
|
|
752
|
-
stdoutPath,
|
|
753
|
-
stderrPath,
|
|
754
|
-
}),
|
|
755
|
-
],
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
buildWindowsSpotlightLifecycleCommand(options) {
|
|
759
|
-
const q = (value) => `'${this.escapePowerShellSingleQuotedString(value)}'`;
|
|
760
|
-
const lines = [
|
|
761
|
-
'$ErrorActionPreference = \'Continue\'',
|
|
762
|
-
`$env:AGENT_HOME_DIR = ${q(options.agentHomeDir)}`,
|
|
763
|
-
`Write-Host ${q(this.getLifecycleTerminalIntro(options.action))}`,
|
|
764
|
-
];
|
|
765
|
-
if (options.action === 'stop' || options.action === 'restart') {
|
|
766
|
-
lines.push('Write-Host ""', 'Write-Host "Stopping LiteLLM proxy..."', ...this.buildWindowsLiteLLMStopCommands(options.litellmScript, q));
|
|
767
|
-
}
|
|
768
|
-
if (options.action === 'stop') {
|
|
769
|
-
lines.push('Write-Host ""', 'Write-Host "Stopping OTEL Collector..."', `& ${q(options.startScript)} -Stop`);
|
|
770
|
-
}
|
|
771
|
-
else if (options.action === 'restart') {
|
|
772
|
-
lines.push('Write-Host ""', 'Write-Host "Restarting OTEL Collector..."', `& ${q(options.startScript)} -Stop`, 'Start-Sleep 1', `& ${q(options.startScript)} -ForceDaemon`);
|
|
773
|
-
}
|
|
774
|
-
else {
|
|
775
|
-
lines.push('Write-Host ""', 'Write-Host "Starting OTEL Collector..."', `& ${q(options.startScript)} -ForceDaemon`);
|
|
776
|
-
}
|
|
777
|
-
if (options.action === 'start' || options.action === 'restart') {
|
|
778
|
-
lines.push('Write-Host ""', ...this.buildWindowsLiteLLMStartCommands(options, q));
|
|
779
|
-
}
|
|
780
|
-
lines.push('Write-Host ""', 'Write-Host "You can close this window."');
|
|
781
|
-
return lines.join('\r\n');
|
|
782
|
-
}
|
|
783
|
-
buildWindowsLiteLLMStopCommands(litellmScript, q) {
|
|
784
|
-
if (!litellmScript) {
|
|
785
|
-
return ['Write-Host "[WARN] LiteLLM launcher script not found. Skipping LiteLLM stop." -ForegroundColor Yellow'];
|
|
786
|
-
}
|
|
787
|
-
return [`& ${q(litellmScript)} -Stop`];
|
|
788
|
-
}
|
|
789
|
-
buildWindowsLiteLLMStartCommands(options, q) {
|
|
790
|
-
if (!options.litellmScript) {
|
|
791
|
-
return ['Write-Host "[WARN] LiteLLM launcher script not found. Skipping LiteLLM start." -ForegroundColor Yellow'];
|
|
792
|
-
}
|
|
793
|
-
const launcherArgumentLine = (0, windowsCommandLine_1.buildWindowsArgumentLine)([
|
|
794
|
-
'-NoProfile',
|
|
795
|
-
'-NoLogo',
|
|
796
|
-
'-ExecutionPolicy',
|
|
797
|
-
'Bypass',
|
|
798
|
-
'-File',
|
|
799
|
-
options.litellmScript,
|
|
800
|
-
'-ConfigPath',
|
|
801
|
-
options.configPath,
|
|
802
|
-
]);
|
|
803
|
-
// A missing config is not fatal: the launcher re-seeds the managed default
|
|
804
|
-
// (~/.agent-hippo/litellm-otel.yaml) from its bundled template before starting.
|
|
805
|
-
return [
|
|
806
|
-
'Write-Host "Starting LiteLLM proxy..."',
|
|
807
|
-
`if (-not (Test-Path ${q(options.configPath)})) {`,
|
|
808
|
-
` Write-Host ${q(`[INFO] LiteLLM config missing: ${options.configPath} — launcher will re-create it from the bundled template.`)}`,
|
|
809
|
-
'}',
|
|
810
|
-
`$env:LITELLM_CONFIG_PATH = ${q(options.configPath)}`,
|
|
811
|
-
'try {',
|
|
812
|
-
` $proc = Start-Process -FilePath ${q(getWindowsPwshOrPowerShell())} -WindowStyle Hidden -WorkingDirectory ${q(path.dirname(options.litellmScript))} -ArgumentList ${q(launcherArgumentLine)} -RedirectStandardOutput ${q(options.stdoutPath)} -RedirectStandardError ${q(options.stderrPath)} -PassThru -ErrorAction Stop`,
|
|
813
|
-
' Write-Host "[OK] LiteLLM launcher started (PID: $($proc.Id))"',
|
|
814
|
-
` Write-Host ${q(` Logs: ${options.stdoutPath}`)}`,
|
|
815
|
-
` Write-Host ${q(` Errors: ${options.stderrPath}`)}`,
|
|
816
|
-
'} catch {',
|
|
817
|
-
' Write-Host "[ERROR] Failed to start LiteLLM launcher." -ForegroundColor Red',
|
|
818
|
-
' Write-Host $_.Exception.Message -ForegroundColor Red',
|
|
819
|
-
'}',
|
|
820
|
-
];
|
|
821
|
-
}
|
|
822
|
-
buildUnixSpotlightLifecycleCommand(options) {
|
|
823
|
-
const q = (value) => this.quoteBash(value);
|
|
824
|
-
const lines = [
|
|
825
|
-
'set +e',
|
|
826
|
-
`export AGENT_HOME_DIR=${q(options.agentHomeDir)}`,
|
|
827
|
-
`mkdir -p ${q(path.dirname(options.stdoutPath))}`,
|
|
828
|
-
`echo ${q(this.getLifecycleTerminalIntro(options.action))}`,
|
|
829
|
-
];
|
|
830
|
-
if (options.action === 'stop' || options.action === 'restart') {
|
|
831
|
-
lines.push('echo ""', 'echo "Stopping LiteLLM proxy..."', ...this.buildUnixLiteLLMStopCommands(options.litellmScript, q));
|
|
832
|
-
}
|
|
833
|
-
if (options.action === 'stop') {
|
|
834
|
-
lines.push('echo ""', 'echo "Stopping OTEL Collector..."', `${q(options.startScript)} --stop`);
|
|
835
|
-
}
|
|
836
|
-
else if (options.action === 'restart') {
|
|
837
|
-
lines.push('echo ""', 'echo "Restarting OTEL Collector..."', `${q(options.startScript)} --stop`, 'sleep 1', `${q(options.startScript)} --force-daemon`);
|
|
838
|
-
}
|
|
839
|
-
else {
|
|
840
|
-
lines.push('echo ""', 'echo "Starting OTEL Collector..."', `${q(options.startScript)} --force-daemon`);
|
|
841
|
-
}
|
|
842
|
-
if (options.action === 'start' || options.action === 'restart') {
|
|
843
|
-
lines.push('echo ""', ...this.buildUnixLiteLLMStartCommands(options, q));
|
|
844
|
-
}
|
|
845
|
-
lines.push('echo ""', 'echo "Press any key to close..."', 'read -n 1');
|
|
846
|
-
return lines.join('\n');
|
|
847
|
-
}
|
|
848
|
-
buildUnixLiteLLMStopCommands(litellmScript, q) {
|
|
849
|
-
if (!litellmScript) {
|
|
850
|
-
return ['echo "[WARN] LiteLLM launcher script not found. Skipping LiteLLM stop." >&2'];
|
|
851
|
-
}
|
|
852
|
-
return [`${q(litellmScript)} --stop`];
|
|
853
|
-
}
|
|
854
|
-
buildUnixLiteLLMStartCommands(options, q) {
|
|
855
|
-
if (!options.litellmScript) {
|
|
856
|
-
return ['echo "[WARN] LiteLLM launcher script not found. Skipping LiteLLM start." >&2'];
|
|
857
|
-
}
|
|
858
|
-
// A missing config is not fatal: the launcher re-seeds the managed default
|
|
859
|
-
// (~/.agent-hippo/litellm-otel.yaml) from its bundled template before starting.
|
|
860
|
-
return [
|
|
861
|
-
'echo "Starting LiteLLM proxy..."',
|
|
862
|
-
`if [ ! -f ${q(options.configPath)} ]; then`,
|
|
863
|
-
` echo ${q(`[INFO] LiteLLM config missing: ${options.configPath} — launcher will re-create it from the bundled template.`)}`,
|
|
864
|
-
'fi',
|
|
865
|
-
`export LITELLM_CONFIG_PATH=${q(options.configPath)}`,
|
|
866
|
-
`nohup ${q(options.litellmScript)} --config ${q(options.configPath)} >> ${q(options.stdoutPath)} 2>> ${q(options.stderrPath)} &`,
|
|
867
|
-
'echo "[OK] LiteLLM launcher started (PID: $!)"',
|
|
868
|
-
`echo ${q(` Logs: ${options.stdoutPath}`)}`,
|
|
869
|
-
`echo ${q(` Errors: ${options.stderrPath}`)}`,
|
|
870
|
-
];
|
|
871
|
-
}
|
|
872
|
-
getLifecycleTerminalIntro(action) {
|
|
873
|
-
switch (action) {
|
|
874
|
-
case 'start':
|
|
875
|
-
return 'Starting Spotlight (OTEL Collector + LiteLLM)...';
|
|
876
|
-
case 'stop':
|
|
877
|
-
return 'Stopping Spotlight (LiteLLM + OTEL Collector)...';
|
|
878
|
-
case 'restart':
|
|
879
|
-
return 'Restarting Spotlight (LiteLLM + OTEL Collector)...';
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
quoteBash(value) {
|
|
883
|
-
return `'${value.replace(/'/g, '\'\\\'\'')}'`;
|
|
884
|
-
}
|
|
885
|
-
/**
|
|
886
|
-
* Stop LiteLLM by invoking the launcher script with --stop / -Stop.
|
|
887
|
-
* The script reads the canonical PID file and handles winpid/taskkill on Windows.
|
|
888
|
-
*/
|
|
889
|
-
async stopLiteLLMDirectly() {
|
|
890
|
-
const isWindows = process.platform === 'win32';
|
|
891
|
-
const args = isWindows ? ['-Stop'] : ['--stop'];
|
|
892
|
-
return this.runLauncher(args, { detached: false });
|
|
893
|
-
}
|
|
894
|
-
/**
|
|
895
|
-
* Start LiteLLM in a detached background process. Logs go to .agent-hippo/analytics/litellm.{log,error.log}.
|
|
896
|
-
*/
|
|
897
|
-
async startLiteLLMDirectly() {
|
|
898
|
-
// No existence check: a missing managed config is re-seeded from the bundled
|
|
899
|
-
// template by the launcher itself (deleting it is a "reset to defaults" gesture).
|
|
900
|
-
const configPath = path.join((0, index_1.getAgentideHome)(), 'litellm-otel.yaml');
|
|
901
|
-
const isWindows = process.platform === 'win32';
|
|
902
|
-
const args = isWindows
|
|
903
|
-
? ['-ConfigPath', configPath]
|
|
904
|
-
: ['--config', configPath];
|
|
905
|
-
return this.runLauncher(args, { detached: true, configPath });
|
|
906
|
-
}
|
|
907
|
-
/**
|
|
908
|
-
* Spawn the agentide-litellm launcher with the given args.
|
|
909
|
-
* `detached: true` returns immediately and pipes child stdout/stderr to log files.
|
|
910
|
-
* `detached: false` resolves when the process exits (used for --stop).
|
|
911
|
-
*/
|
|
912
|
-
async runLauncher(args, opts) {
|
|
913
|
-
const scriptPath = await this.findLiteLLMScript();
|
|
914
|
-
if (!scriptPath) {
|
|
915
|
-
return false;
|
|
916
|
-
}
|
|
917
|
-
const isWindows = process.platform === 'win32';
|
|
918
|
-
const shellPath = isWindows ? getWindowsPwshOrPowerShell() : '/bin/bash';
|
|
919
|
-
const shellArgs = isWindows
|
|
920
|
-
? ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', scriptPath, ...args]
|
|
921
|
-
: [scriptPath, ...args];
|
|
922
|
-
const env = { ...process.env, AGENT_HOME_DIR: (0, index_1.getAgentideHome)() };
|
|
923
|
-
if (opts.configPath) {
|
|
924
|
-
env.LITELLM_CONFIG_PATH = opts.configPath;
|
|
925
|
-
}
|
|
926
|
-
if (isWindows && opts.detached) {
|
|
927
|
-
return this.startLiteLLMViaHiddenWindowsProcess(scriptPath, args, env);
|
|
928
|
-
}
|
|
929
|
-
if (opts.detached) {
|
|
930
|
-
// Open log files synchronously so spawn can dup the fds before we close them.
|
|
931
|
-
const analyticsDir = path.join((0, index_1.getAgentideHome)(), 'analytics');
|
|
932
|
-
fsSync.mkdirSync(analyticsDir, { recursive: true });
|
|
933
|
-
const stdoutFd = fsSync.openSync(path.join(analyticsDir, 'litellm.log'), 'a');
|
|
934
|
-
const stderrFd = fsSync.openSync(path.join(analyticsDir, 'litellm.error.log'), 'a');
|
|
935
|
-
try {
|
|
936
|
-
const child = (0, child_process_1.spawn)(shellPath, shellArgs, {
|
|
937
|
-
detached: true,
|
|
938
|
-
stdio: ['ignore', stdoutFd, stderrFd],
|
|
939
|
-
windowsHide: true,
|
|
940
|
-
env,
|
|
941
|
-
cwd: path.dirname(scriptPath),
|
|
942
|
-
});
|
|
943
|
-
child.unref();
|
|
944
|
-
this.log(`LiteLLM launcher started (PID: ${child.pid})`);
|
|
945
|
-
return true;
|
|
946
|
-
}
|
|
947
|
-
catch (error) {
|
|
948
|
-
this.log(`Failed to start LiteLLM: ${error}`);
|
|
949
|
-
return false;
|
|
950
|
-
}
|
|
951
|
-
finally {
|
|
952
|
-
fsSync.closeSync(stdoutFd);
|
|
953
|
-
fsSync.closeSync(stderrFd);
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
return new Promise((resolve) => {
|
|
957
|
-
const child = (0, child_process_1.spawn)(shellPath, shellArgs, {
|
|
958
|
-
windowsHide: true,
|
|
959
|
-
env,
|
|
960
|
-
cwd: path.dirname(scriptPath),
|
|
961
|
-
});
|
|
962
|
-
child.once('error', (err) => {
|
|
963
|
-
this.log(`LiteLLM launcher failed to spawn: ${err}`);
|
|
964
|
-
resolve(false);
|
|
965
|
-
});
|
|
966
|
-
child.once('exit', (code) => resolve(code === 0));
|
|
967
|
-
});
|
|
968
|
-
}
|
|
969
|
-
async startLiteLLMViaHiddenWindowsProcess(scriptPath, args, env) {
|
|
970
|
-
const analyticsDir = path.join((0, index_1.getAgentideHome)(), 'analytics');
|
|
971
|
-
fsSync.mkdirSync(analyticsDir, { recursive: true });
|
|
972
|
-
const stdoutPath = path.join(analyticsDir, 'litellm.log');
|
|
973
|
-
const stderrPath = path.join(analyticsDir, 'litellm.error.log');
|
|
974
|
-
const launcherArgumentLine = (0, windowsCommandLine_1.buildWindowsArgumentLine)([
|
|
975
|
-
'-NoProfile',
|
|
976
|
-
'-NoLogo',
|
|
977
|
-
'-ExecutionPolicy',
|
|
978
|
-
'Bypass',
|
|
979
|
-
'-File',
|
|
980
|
-
scriptPath,
|
|
981
|
-
...args,
|
|
982
|
-
]);
|
|
983
|
-
const psCommand = [
|
|
984
|
-
`$env:AGENT_HOME_DIR = '${this.escapePowerShellSingleQuotedString(env.AGENT_HOME_DIR ?? (0, index_1.getAgentideHome)())}'`,
|
|
985
|
-
env.LITELLM_CONFIG_PATH
|
|
986
|
-
? `$env:LITELLM_CONFIG_PATH = '${this.escapePowerShellSingleQuotedString(env.LITELLM_CONFIG_PATH)}'`
|
|
987
|
-
: '',
|
|
988
|
-
`$proc = Start-Process -FilePath '${this.escapePowerShellSingleQuotedString(getWindowsPwshOrPowerShell())}' -WindowStyle Hidden -WorkingDirectory '${this.escapePowerShellSingleQuotedString(path.dirname(scriptPath))}' -ArgumentList '${this.escapePowerShellSingleQuotedString(launcherArgumentLine)}' -RedirectStandardOutput '${this.escapePowerShellSingleQuotedString(stdoutPath)}' -RedirectStandardError '${this.escapePowerShellSingleQuotedString(stderrPath)}' -PassThru`,
|
|
989
|
-
'Write-Output $proc.Id',
|
|
990
|
-
].filter(Boolean).join('; ');
|
|
991
|
-
return new Promise((resolve) => {
|
|
992
|
-
let stdout = '';
|
|
993
|
-
let stderr = '';
|
|
994
|
-
const child = (0, child_process_1.spawn)(getWindowsPwshOrPowerShell(), [
|
|
995
|
-
'-NoProfile',
|
|
996
|
-
'-ExecutionPolicy',
|
|
997
|
-
'Bypass',
|
|
998
|
-
'-Command',
|
|
999
|
-
psCommand,
|
|
1000
|
-
], {
|
|
1001
|
-
windowsHide: true,
|
|
1002
|
-
env,
|
|
1003
|
-
cwd: path.dirname(scriptPath),
|
|
1004
|
-
});
|
|
1005
|
-
child.stdout.on('data', data => {
|
|
1006
|
-
stdout += data.toString();
|
|
1007
|
-
});
|
|
1008
|
-
child.stderr.on('data', data => {
|
|
1009
|
-
stderr += data.toString();
|
|
1010
|
-
});
|
|
1011
|
-
child.once('error', (err) => {
|
|
1012
|
-
this.log(`LiteLLM launcher failed to spawn hidden Windows process: ${err}`);
|
|
1013
|
-
resolve(false);
|
|
1014
|
-
});
|
|
1015
|
-
child.once('exit', (code) => {
|
|
1016
|
-
if (code !== 0) {
|
|
1017
|
-
const detail = stderr.trim() || stdout.trim();
|
|
1018
|
-
this.log(`LiteLLM hidden Windows launcher exited with code ${code}${detail ? `: ${detail}` : ''}`);
|
|
1019
|
-
resolve(false);
|
|
1020
|
-
return;
|
|
1021
|
-
}
|
|
1022
|
-
const startedPid = parseInt(stdout.trim(), 10);
|
|
1023
|
-
if (!Number.isNaN(startedPid)) {
|
|
1024
|
-
this.log(`LiteLLM hidden Windows process started (PID: ${startedPid})`);
|
|
1025
|
-
}
|
|
1026
|
-
resolve(true);
|
|
1027
|
-
});
|
|
1028
|
-
});
|
|
1029
|
-
}
|
|
1030
|
-
escapePowerShellSingleQuotedString(value) {
|
|
1031
|
-
return value.replace(/'/g, '\'\'');
|
|
1032
|
-
}
|
|
1033
|
-
async findLiteLLMScript() {
|
|
1034
|
-
const extensionPath = this.extensionContext.extensionPath;
|
|
1035
|
-
const isWindows = process.platform === 'win32';
|
|
1036
|
-
const scriptName = isWindows ? 'agentide-litellm.ps1' : 'agentide-litellm.sh';
|
|
1037
|
-
const candidates = [
|
|
1038
|
-
path.join(extensionPath, 'out', 'scripts', scriptName),
|
|
1039
|
-
path.join(extensionPath, 'scripts', scriptName),
|
|
1040
|
-
path.join(extensionPath, '..', '..', 'scripts', scriptName),
|
|
1041
|
-
];
|
|
1042
|
-
for (const candidate of candidates) {
|
|
1043
|
-
try {
|
|
1044
|
-
await fs_1.promises.access(candidate);
|
|
1045
|
-
return candidate;
|
|
1046
|
-
}
|
|
1047
|
-
catch {
|
|
1048
|
-
// ignore
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
return null;
|
|
1052
|
-
}
|
|
1053
|
-
/**
|
|
1054
|
-
* Run DuckDB re-indexing from trace JSONL (dashboard).
|
|
1055
|
-
*/
|
|
1056
|
-
async triggerIndexing() {
|
|
1057
|
-
if (!this.indexingService) {
|
|
1058
|
-
vscode.window.showWarningMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Indexing service is not available.`);
|
|
1059
|
-
return;
|
|
1060
|
-
}
|
|
1061
|
-
if (this.indexingService.isIndexing()) {
|
|
1062
|
-
vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Indexing is already in progress.`);
|
|
1063
|
-
return;
|
|
1064
|
-
}
|
|
1065
|
-
this.indexingService.scheduleIndexing(true);
|
|
1066
|
-
vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Triggered indexing.`);
|
|
1067
|
-
}
|
|
1068
|
-
/**
|
|
1069
|
-
* Show analytics status in a notification.
|
|
1070
|
-
*/
|
|
1071
|
-
async showStatus() {
|
|
1072
|
-
const stackStatus = await this.getStackStatus();
|
|
1073
|
-
const litellmBaseUrl = vscode.workspace
|
|
1074
|
-
.getConfiguration('agentide.providers.litellm')
|
|
1075
|
-
.get('baseUrl')
|
|
1076
|
-
?.trim();
|
|
1077
|
-
// Build status lines
|
|
1078
|
-
// allow-any-unicode-next-line
|
|
1079
|
-
const otelStatus = stackStatus.otelRunning ? '🟢 127.0.0.1:4318' : '⚫ Not running';
|
|
1080
|
-
let litellmStatus;
|
|
1081
|
-
if (stackStatus.litellmRunning && litellmBaseUrl) {
|
|
1082
|
-
// allow-any-unicode-next-line
|
|
1083
|
-
litellmStatus = `🟢 ${litellmBaseUrl}`;
|
|
1084
|
-
}
|
|
1085
|
-
else if (stackStatus.litellmRunning) {
|
|
1086
|
-
// allow-any-unicode-next-line
|
|
1087
|
-
litellmStatus = '🟢 Set URL in Settings or Stop External LiteLLM';
|
|
1088
|
-
}
|
|
1089
|
-
else {
|
|
1090
|
-
// allow-any-unicode-next-line
|
|
1091
|
-
litellmStatus = '⚫ Not running';
|
|
1092
|
-
}
|
|
1093
|
-
const message = [
|
|
1094
|
-
`LiteLLM: ${litellmStatus}`,
|
|
1095
|
-
`OTEL: ${otelStatus}`,
|
|
1096
|
-
].join('\n\n');
|
|
1097
|
-
const lifecycleAction = (0, lifecycle_1.getSpotlightLifecycleAction)(stackStatus);
|
|
1098
|
-
const installAction = (0, lifecycle_1.getSpotlightInstallAction)(await this.isAnalyticsConfigured());
|
|
1099
|
-
const action = await vscode.window.showInformationMessage(`${message}`, 'Config', installAction, lifecycleAction);
|
|
1100
|
-
switch (action) {
|
|
1101
|
-
case 'Start':
|
|
1102
|
-
await this.start();
|
|
1103
|
-
break;
|
|
1104
|
-
case 'Stop':
|
|
1105
|
-
await this.stop();
|
|
1106
|
-
break;
|
|
1107
|
-
case 'Config':
|
|
1108
|
-
await this.openLiteLLMConfig();
|
|
1109
|
-
break;
|
|
1110
|
-
case 'Restart All':
|
|
1111
|
-
await this.restart();
|
|
1112
|
-
break;
|
|
1113
|
-
case 'Install':
|
|
1114
|
-
if (process.platform === 'win32') {
|
|
1115
|
-
await this.setupWindowsSpotlight({ reinstall: false });
|
|
1116
|
-
}
|
|
1117
|
-
else {
|
|
1118
|
-
await vscode.commands.executeCommand('agentide.setupAnalytics');
|
|
1119
|
-
}
|
|
1120
|
-
break;
|
|
1121
|
-
case 'Reinstall':
|
|
1122
|
-
if (process.platform === 'win32') {
|
|
1123
|
-
await this.setupWindowsSpotlight({ reinstall: true });
|
|
1124
|
-
}
|
|
1125
|
-
else {
|
|
1126
|
-
await vscode.commands.executeCommand('agentide.setupAnalytics');
|
|
1127
|
-
}
|
|
1128
|
-
break;
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
async openLiteLLMConfig() {
|
|
1132
|
-
const configPath = path.join((0, index_1.getAgentideHome)(), 'litellm-otel.yaml');
|
|
1133
|
-
try {
|
|
1134
|
-
await fs_1.promises.access(configPath);
|
|
1135
|
-
}
|
|
1136
|
-
catch {
|
|
1137
|
-
const choice = await vscode.window.showWarningMessage(`${branding_1.AGENTIDE_BRAND_NAME}: LiteLLM OTEL config not found.`, 'Install');
|
|
1138
|
-
if (choice === 'Install') {
|
|
1139
|
-
await vscode.commands.executeCommand('agentide.setupAnalytics');
|
|
1140
|
-
}
|
|
1141
|
-
return;
|
|
1142
|
-
}
|
|
1143
|
-
const doc = await vscode.workspace.openTextDocument(configPath);
|
|
1144
|
-
await vscode.window.showTextDocument(doc);
|
|
1145
|
-
}
|
|
1146
|
-
/**
|
|
1147
|
-
* Open a terminal with analytics query commands.
|
|
1148
|
-
* Shows the latest session info by default.
|
|
1149
|
-
*/
|
|
1150
|
-
async openQueryTerminal() {
|
|
1151
|
-
const scriptPath = await this.findScript('query-analytics.sh');
|
|
1152
|
-
if (!scriptPath) {
|
|
1153
|
-
vscode.window.showErrorMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Query script not found. Run 'Setup Analytics' first.`);
|
|
1154
|
-
return;
|
|
1155
|
-
}
|
|
1156
|
-
// Show latest session info by default - includes chat history and costs
|
|
1157
|
-
// Keep terminal open so user can see the output
|
|
1158
|
-
const terminal = this.createScriptTerminal('Spotlight Query', scriptPath, '--latest-session', true);
|
|
1159
|
-
terminal.show();
|
|
1160
|
-
}
|
|
1161
|
-
/**
|
|
1162
|
-
* Find a script in the extension bundle or source directory.
|
|
1163
|
-
*/
|
|
1164
|
-
async findScript(scriptName) {
|
|
1165
|
-
const extensionPath = this.extensionContext.extensionPath;
|
|
1166
|
-
// Try bundled location first
|
|
1167
|
-
const bundledPath = path.join(extensionPath, 'out', 'scripts', 'analytics', scriptName);
|
|
1168
|
-
try {
|
|
1169
|
-
await fs_1.promises.access(bundledPath);
|
|
1170
|
-
return bundledPath;
|
|
1171
|
-
}
|
|
1172
|
-
catch {
|
|
1173
|
-
// Not in bundled location
|
|
1174
|
-
}
|
|
1175
|
-
// Try development location
|
|
1176
|
-
const devPath = path.join(extensionPath, 'scripts', 'analytics', scriptName);
|
|
1177
|
-
try {
|
|
1178
|
-
await fs_1.promises.access(devPath);
|
|
1179
|
-
return devPath;
|
|
1180
|
-
}
|
|
1181
|
-
catch {
|
|
1182
|
-
// Not in dev location
|
|
1183
|
-
}
|
|
1184
|
-
return null;
|
|
1185
|
-
}
|
|
1186
|
-
/**
|
|
1187
|
-
* Update the status bar item.
|
|
1188
|
-
*/
|
|
1189
|
-
updateStatusBar(status) {
|
|
1190
|
-
this._status = status;
|
|
1191
|
-
let tooltip;
|
|
1192
|
-
// Use different icons and colors based on status
|
|
1193
|
-
switch (status) {
|
|
1194
|
-
case 'running':
|
|
1195
|
-
this.statusBarItem.text = '$(pulse) Spotlight';
|
|
1196
|
-
tooltip = 'Spotlight: Running (OTEL + LiteLLM configured)';
|
|
1197
|
-
this.statusBarItem.color = new vscode.ThemeColor('testing.iconPassed'); // Green
|
|
1198
|
-
this.statusBarItem.backgroundColor = undefined;
|
|
1199
|
-
break;
|
|
1200
|
-
case 'partial':
|
|
1201
|
-
this.statusBarItem.text = '$(pulse) Spotlight';
|
|
1202
|
-
tooltip = 'Spotlight: Partial (click to configure)';
|
|
1203
|
-
this.statusBarItem.color = new vscode.ThemeColor('editorWarning.foreground'); // Yellow
|
|
1204
|
-
this.statusBarItem.backgroundColor = undefined;
|
|
1205
|
-
break;
|
|
1206
|
-
case 'stopped':
|
|
1207
|
-
this.statusBarItem.text = '$(pulse) Spotlight';
|
|
1208
|
-
tooltip = 'Spotlight: Stopped (click to start)';
|
|
1209
|
-
this.statusBarItem.color = undefined;
|
|
1210
|
-
this.statusBarItem.backgroundColor = undefined;
|
|
1211
|
-
break;
|
|
1212
|
-
case 'checking':
|
|
1213
|
-
this.statusBarItem.text = '$(sync~spin) Spotlight';
|
|
1214
|
-
tooltip = 'Spotlight: Checking...';
|
|
1215
|
-
this.statusBarItem.color = undefined;
|
|
1216
|
-
this.statusBarItem.backgroundColor = undefined;
|
|
1217
|
-
break;
|
|
1218
|
-
case 'error':
|
|
1219
|
-
this.statusBarItem.text = '$(warning) Spotlight';
|
|
1220
|
-
tooltip = 'Spotlight: Error (click to retry)';
|
|
1221
|
-
this.statusBarItem.color = new vscode.ThemeColor('errorForeground');
|
|
1222
|
-
this.statusBarItem.backgroundColor = undefined;
|
|
1223
|
-
break;
|
|
1224
|
-
}
|
|
1225
|
-
if (this.indexProgress.status === 'indexing') {
|
|
1226
|
-
tooltip += `\n\nBackground analytics indexing is running (${this.indexProgress.percent}% complete). Charts may use JSONL fallback until indexing finishes.`;
|
|
1227
|
-
}
|
|
1228
|
-
this.statusBarItem.tooltip = tooltip;
|
|
1229
|
-
this.statusBarItem.show();
|
|
1230
|
-
}
|
|
1231
|
-
log(message) {
|
|
1232
|
-
this.outputChannel.appendLine(`[Analytics] ${message}`);
|
|
1233
|
-
}
|
|
1234
|
-
/**
|
|
1235
|
-
* Create a terminal that runs a command directly via shellArgs.
|
|
1236
|
-
* This avoids the sendText character-dropping issue.
|
|
1237
|
-
*/
|
|
1238
|
-
createScriptTerminal(name, scriptPath, args, keepOpen = false) {
|
|
1239
|
-
const agentHomeDir = (0, index_1.getAgentideHome)();
|
|
1240
|
-
if (keepOpen) {
|
|
1241
|
-
// Run the script, then drop into an interactive shell
|
|
1242
|
-
// Uses the same shellPath/shellArgs approach as Setup Analytics to avoid sendText issues
|
|
1243
|
-
// Echo the command first so user can see what's running
|
|
1244
|
-
const cmd = `"${scriptPath}" ${args}`;
|
|
1245
|
-
return vscode.window.createTerminal({
|
|
1246
|
-
name,
|
|
1247
|
-
cwd: path.dirname(scriptPath),
|
|
1248
|
-
env: {
|
|
1249
|
-
AGENT_HOME_DIR: agentHomeDir,
|
|
1250
|
-
},
|
|
1251
|
-
shellPath: '/bin/bash',
|
|
1252
|
-
shellArgs: ['-c', `echo '$ ${cmd}'; echo ''; ${cmd}; echo ''; exec bash -l`],
|
|
1253
|
-
});
|
|
1254
|
-
}
|
|
1255
|
-
// For non-keepOpen, use bash -c for a one-shot command
|
|
1256
|
-
return vscode.window.createTerminal({
|
|
1257
|
-
name,
|
|
1258
|
-
cwd: path.dirname(scriptPath),
|
|
1259
|
-
env: {
|
|
1260
|
-
AGENT_HOME_DIR: agentHomeDir,
|
|
1261
|
-
},
|
|
1262
|
-
shellPath: '/bin/bash',
|
|
1263
|
-
shellArgs: ['-c', `"${scriptPath}" ${args}`],
|
|
1264
|
-
});
|
|
1265
|
-
}
|
|
1266
|
-
dispose() {
|
|
1267
|
-
if (this.healthCheckTimer) {
|
|
1268
|
-
clearInterval(this.healthCheckTimer);
|
|
1269
|
-
this.healthCheckTimer = null;
|
|
1270
|
-
}
|
|
1271
|
-
this.statusBarItem.dispose();
|
|
1272
|
-
for (const d of this.disposables) {
|
|
1273
|
-
d.dispose();
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
|
-
exports.AnalyticsService = AnalyticsService;
|
|
1
|
+
/*! Copyright (c) 2026 AgentHippo.ai. All rights reserved. Proprietary; see LICENSE. */
|
|
2
|
+
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(l,t,e,i){i===void 0&&(i=e);var s=Object.getOwnPropertyDescriptor(t,e);(!s||("get"in s?!t.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return t[e]}}),Object.defineProperty(l,i,s)}):(function(l,t,e,i){i===void 0&&(i=e),l[i]=t[e]})),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(l,t){Object.defineProperty(l,"default",{enumerable:!0,value:t})}):function(l,t){l.default=t}),__importStar=this&&this.__importStar||(function(){var l=function(t){return l=Object.getOwnPropertyNames||function(e){var i=[];for(var s in e)Object.prototype.hasOwnProperty.call(e,s)&&(i[i.length]=s);return i},l(t)};return function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var i=l(t),s=0;s<i.length;s++)i[s]!=="default"&&__createBinding(e,t,i[s]);return __setModuleDefault(e,t),e}})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.AnalyticsService=void 0;const vscode=__importStar(require("vscode")),path=__importStar(require("path")),fsSync=__importStar(require("fs")),fs_1=require("fs"),child_process_1=require("child_process"),branding_1=require("../branding"),indexingService_1=require("./dashboard/indexingService"),performanceMonitor_1=require("./dashboard/performanceMonitor"),lifecycle_1=require("./lifecycle"),index_1=require("../utils/index"),windowsCommandLine_1=require("../utils/windowsCommandLine");let cachedWindowsPwshPath;function getWindowsPwshOrPowerShell(){return process.platform!=="win32"?"powershell.exe":(cachedWindowsPwshPath===void 0&&(cachedWindowsPwshPath=resolvePwshExecutable()),cachedWindowsPwshPath??"powershell.exe")}function resolvePwshExecutable(){const l=[],t=(process.env.PATH??"").split(path.delimiter).filter(Boolean);for(const a of t)l.push(path.join(a,"pwsh.exe"));const e=process.env.ProgramFiles??"C:\\Program Files",i=process.env["ProgramFiles(x86)"]??"C:\\Program Files (x86)",s=process.env.LOCALAPPDATA;for(const a of["7","8"])l.push(path.join(e,"PowerShell",a,"pwsh.exe")),l.push(path.join(i,"PowerShell",a,"pwsh.exe"));s&&l.push(path.join(s,"Microsoft","PowerShell","pwsh.exe"));for(const a of l)try{if(fsSync.statSync(a).isFile())return a}catch{}return null}class AnalyticsService{statusBarItem;outputChannel;extensionContext;_status="stopped";_lastStackStatus={otelRunning:!1,litellmRunning:!1,litellmWithOtel:!1};indexProgress={status:"idle",percent:0};indexingService;performanceMonitor;disposables=[];lifecycleInProgress=!1;get status(){return this._status}healthCheckTimer=null;static HEALTH_CHECK_INTERVAL=3e4;constructor(t,e){this.extensionContext=t,this.outputChannel=e,this.performanceMonitor=new performanceMonitor_1.PerformanceMonitor(e),this.statusBarItem=vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right,99),this.statusBarItem.command="agentide.analytics.toggle",this.registerCommands(),this.initializeWithLazyHeartbeat()}async initializeWithLazyHeartbeat(){await this.isAnalyticsConfigured()?(this.updateStatusBar("checking"),await this.checkStatus(),this.startHeartbeat()):(this.updateStatusBar("stopped"),this.statusBarItem.show(),await this.detectStandaloneLiteLLM()),await this.initializeIndexingService()}async initializeIndexingService(){try{const t=this.getAnalyticsDir(),e=path.join(t,"traces");this.indexingService=new indexingService_1.IndexingService(e,this.outputChannel,this.performanceMonitor),this.disposables.push(this.indexingService.onProgressChange(i=>{this.indexProgress=i,this.updateStatusBar(this._status)})),await this.indexingService.initialize()}catch(t){this.outputChannel.appendLine(`[Analytics] Failed to initialize indexing service: ${t}`)}}getIndexingService(){return this.indexingService}async detectStandaloneLiteLLM(){try{(await this.getLiteLLMStatus()).running&&this.outputChannel.appendLine("[Analytics] Detected standalone LiteLLM running")}catch{}}async isAnalyticsConfigured(){const t=this.getAnalyticsDir(),e=path.join(t,"config","otel-collector.yaml");try{return await fs_1.promises.access(e),!0}catch{return!1}}startHeartbeat(){this.healthCheckTimer||(this.healthCheckTimer=setInterval(()=>{this.checkStatus()},AnalyticsService.HEALTH_CHECK_INTERVAL))}registerCommands(){this.disposables.push(vscode.commands.registerCommand("agentide.analytics.toggle",()=>this.toggle()),vscode.commands.registerCommand("agentide.analytics.restart",()=>this.restart()),vscode.commands.registerCommand("agentide.analytics.start",()=>this.start()),vscode.commands.registerCommand("agentide.analytics.stop",()=>this.stop()),vscode.commands.registerCommand("agentide.analytics.status",()=>this.showStatus()),vscode.commands.registerCommand("agentide.analytics.query",()=>this.openQueryTerminal()),vscode.commands.registerCommand("agentide.analytics.openLiteLLMConfig",()=>this.openLiteLLMConfig()),vscode.commands.registerCommand("agentide.analytics.isRunning",()=>this.checkStatus()))}getAnalyticsDir(){return index_1.DIRS.analytics()}getOtelPidFile(){return index_1.PID_FILES.otelcol()}getLiteLLMPidFile(){return index_1.PID_FILES.litellm()}async checkStatus(){try{const t=await this.getStackStatus();return this._lastStackStatus=t,t.otelRunning&&t.litellmWithOtel?(this.updateStatusBar("running"),!0):this.lifecycleInProgress?(this.updateStatusBar("checking"),!1):t.otelRunning||t.litellmRunning?(this.updateStatusBar("partial"),!1):(this.updateStatusBar("stopped"),!1)}catch{return this.updateStatusBar("error"),!1}}async getStackStatus(){const t=await this.isOtelRunning(),e=await this.getLiteLLMStatus();return{otelRunning:t,litellmRunning:e.running,litellmWithOtel:e.withOtel}}async isOtelRunning(){return await(0,index_1.checkPidFileWithCleanup)(this.getOtelPidFile())!==null}async getLiteLLMStatus(){const t=await(0,index_1.checkPidFileWithCleanup)(this.getLiteLLMPidFile());if(!t)return{running:!1,withOtel:!1};const e=t.metadata??[],i=e.some(a=>a.trim().toLowerCase()==="otel"),s=e.find(a=>a.startsWith("url="));return s&&await this.maybeUpdateLiteLLMBaseUrlValue(s.slice(4).trim()),{running:!0,withOtel:i}}async maybeUpdateLiteLLMBaseUrlValue(t){const e=vscode.workspace.getConfiguration("agentide.providers.litellm");if(e.get("baseUrl")?.trim())return;const i=t.trim();i&&(await e.update("baseUrl",i,vscode.ConfigurationTarget.Global),this.outputChannel.appendLine(`[Analytics] Auto-detected LiteLLM base URL: ${i}`))}async waitForStackReady(t=3e4,e=1e3){const i=Date.now()+t;let s=await this.getStackStatus();for(;Date.now()<i;){if(s=await this.getStackStatus(),this._lastStackStatus=s,s.otelRunning&&s.litellmWithOtel)return s;await new Promise(a=>setTimeout(a,e))}return s}async waitForStackStopped(t=15e3,e=500){const i=Date.now()+t;let s=await this.getStackStatus();for(;Date.now()<i;){if(s=await this.getStackStatus(),this._lastStackStatus=s,!s.otelRunning&&!s.litellmRunning)return s;await new Promise(a=>setTimeout(a,e))}return s}async monitorStartupReadiness(t){const e=await this.waitForStackReady();this._lastStackStatus=e;const i=this.deriveStatusFrom(e);if(this.lifecycleInProgress=!1,this.updateStatusBar(i),i==="running"){this.log(`Analytics stack ready after ${t}.`),vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight ${t==="restart"?"restarted":"started"}.`);return}this.log(`Analytics stack not fully ready after ${t} (otel=${e.otelRunning}, litellm=${e.litellmRunning}, litellmWithOtel=${e.litellmWithOtel})`),await vscode.window.showWarningMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight ${t==="restart"?"restart":"start"} is not fully ready yet.`,"Show Status")==="Show Status"&&await this.showStatus()}async monitorStopReadiness(){const t=await this.waitForStackStopped();this._lastStackStatus=t;const e=this.deriveStatusFrom(t);if(this.lifecycleInProgress=!1,this.updateStatusBar(e),e==="stopped"){this.log("Analytics stack stopped."),vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight stopped.`);return}this.log(`Analytics stack not fully stopped (otel=${t.otelRunning}, litellm=${t.litellmRunning}, litellmWithOtel=${t.litellmWithOtel})`),await vscode.window.showWarningMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight stop is not fully complete yet.`,"Show Status")==="Show Status"&&await this.showStatus()}async toggle(){const t=this._status==="checking"?this.deriveStatusFrom(this._lastStackStatus):this._status;t==="running"?await this.showStatusWithRestartOption():t==="partial"?await this.showPartialStatusOption():await this.showStoppedStatusOption(t)}queueBackgroundStatusRefresh(t){this.lifecycleInProgress||setTimeout(()=>{this.lifecycleInProgress||this.checkStatus().catch(e=>{this.log(`Background status refresh failed after ${t}: ${e instanceof Error?e.message:String(e)}`)})},100)}deriveStatusFrom(t){return(0,lifecycle_1.deriveAnalyticsStatus)(t)}async showPartialStatusOption(){const t=this._lastStackStatus,e=(0,lifecycle_1.getPartialSpotlightMessage)(t),i=vscode.window.showWarningMessage(`${branding_1.AGENTIDE_BRAND_NAME}: ${e}`,"Install","Restart All","Show Status");switch(this.queueBackgroundStatusRefresh("opening partial menu"),await i){case"Install":await vscode.commands.executeCommand("agentide.setupAnalytics");break;case"Restart All":await this.restart();break;case"Show Status":await this.showStatus();break}}async showStatusWithRestartOption(){const t=vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME} Spotlight is running.`,"See Spotlight","Restart All","Stop","Indexing","Show Status");switch(this.queueBackgroundStatusRefresh("opening running menu"),await t){case"See Spotlight":await vscode.commands.executeCommand("agentide.analytics.openDashboard");break;case"Restart All":await this.restart();break;case"Stop":await this.stop();break;case"Indexing":await this.triggerIndexing();break;case"Show Status":await this.showStatus();break}}async restart(){if(this.log("Restarting analytics stack..."),this.lifecycleInProgress=!0,this.updateStatusBar("checking"),!await this.isAnalyticsConfigured()){await this.start();return}const t=process.platform==="win32",e=await this.findScript(t?"start-analytics.ps1":"start-analytics.sh");if(!e){this.lifecycleInProgress=!1,this.updateStatusBar("error"),vscode.window.showErrorMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight scripts not found. Run Install first.`);return}(await this.createSpotlightLifecycleTerminal("Spotlight Restart","restart",e)).show(),this.updateStatusBar("checking"),this.startHeartbeat(),this.monitorStartupReadiness("restart")}async setupWindowsSpotlight(t={}){if(process.platform!=="win32")return{success:!1,error:"Windows-only setup flow invoked on a non-Windows platform."};const e=await this.findScript("setup-analytics.ps1");if(!e){const i=`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight install script not found.`;return vscode.window.showErrorMessage(i),{success:!1,error:i}}this.lifecycleInProgress=!0,this.updateStatusBar("checking"),this.outputChannel.show(!0),this.log(`${t.reinstall?"Reinstalling":"Installing/repairing"} Spotlight on Windows...`),vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: ${t.reinstall?"Reinstalling":"Installing"} Spotlight...`);try{if(t.reinstall&&(this.log("Stopping LiteLLM before reinstall..."),await this.stopLiteLLMDirectly()),!await this.runWindowsSetupScript(e))throw new Error("setup-analytics.ps1 failed");if((await this.getLiteLLMStatus()).running&&(this.log("Restarting LiteLLM to apply Spotlight config..."),await this.stopLiteLLMDirectly()),this.log("Starting LiteLLM proxy via IDE-managed launcher..."),!await this.startLiteLLMDirectly())throw new Error("LiteLLM launcher did not start");const r=this.getAnalyticsDir();return this.log(`LiteLLM logs: ${path.join(r,"litellm.log")}`),this.log(`LiteLLM errors: ${path.join(r,"litellm.error.log")}`),this.startHeartbeat(),this.monitorStartupReadiness(t.reinstall?"restart":"start"),{success:!0}}catch(i){this.lifecycleInProgress=!1,this.updateStatusBar("error");const s=i instanceof Error?i.message:String(i);return this.log(`Windows Spotlight install failed: ${s}`),vscode.window.showErrorMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight install failed. ${s}`),{success:!1,error:s}}}async showStoppedStatusOption(t){const e=t==="error"?`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight status is unavailable.`:`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight is stopped.`,i=vscode.window.showInformationMessage(e,"Start","Install","See Spotlight","Show Status");switch(this.queueBackgroundStatusRefresh("opening stopped menu"),await i){case"Start":await this.start();break;case"Install":await vscode.commands.executeCommand("agentide.setupAnalytics");break;case"See Spotlight":await vscode.commands.executeCommand("agentide.analytics.openDashboard");break;case"Show Status":await this.showStatus();break}}async runWindowsSetupScript(t){const e=(0,index_1.getAgentideHome)(),i=["-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-File",t,"-Yes"];return this.log(`Running ${path.basename(t)} -Yes...`),new Promise(s=>{let a=!1;const r=n=>{a||(a=!0,s(n))},o=(0,child_process_1.spawn)(getWindowsPwshOrPowerShell(),i,{cwd:path.dirname(t),env:{...process.env,AGENT_HOME_DIR:e},windowsHide:!0});o.stdout?.on("data",n=>{this.outputChannel.append(n.toString())}),o.stderr?.on("data",n=>{this.outputChannel.append(n.toString())}),o.once("error",n=>{this.log(`Windows setup script failed to spawn: ${n.message}`),r(!1)}),o.once("exit",n=>{n===0?(this.log("Windows Spotlight install script completed."),r(!0)):(this.log(`Windows Spotlight install script exited with code ${n??"unknown"}.`),r(!1))})})}async start(){if(await this.checkStatus()){vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight is already running.`);return}const e=process.platform==="win32",i=await this.findScript(e?"start-analytics.ps1":"start-analytics.sh");if(!i){this.lifecycleInProgress=!1,vscode.window.showErrorMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight scripts not found. Run Install first.`);return}this.lifecycleInProgress=!0,this.updateStatusBar("checking"),(await this.createSpotlightLifecycleTerminal("Spotlight Start","start",i)).show(),this.log("Starting Spotlight (OTEL Collector + LiteLLM)..."),vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Starting Spotlight...`),this.updateStatusBar("checking"),this.startHeartbeat(),this.monitorStartupReadiness("start")}async stop(){this.lifecycleInProgress=!0,this.updateStatusBar("checking");const t=process.platform==="win32",e=await this.findScript(t?"start-analytics.ps1":"start-analytics.sh");if(!e){await this.stopDirectly(),this.lifecycleInProgress=!1;return}(await this.createSpotlightLifecycleTerminal("Spotlight Stop","stop",e)).show(),this.log("Stopping Spotlight (OTEL Collector + LiteLLM)..."),this.updateStatusBar("checking"),this.monitorStopReadiness()}async stopDirectly(){try{const t=this.getOtelPidFile(),e=await fs_1.promises.readFile(t,"utf8"),i=parseInt(e.trim(),10);isNaN(i)||(process.kill(i,"SIGTERM"),await fs_1.promises.unlink(t).catch(()=>{}),this.log(`Stopped OTEL Collector (PID: ${i})`)),await this.stopLiteLLMDirectly(),this.updateStatusBar("stopped")}catch(t){this.log(`Failed to stop directly: ${t}`),this.updateStatusBar("error")}}async createSpotlightLifecycleTerminal(t,e,i){const s=(0,index_1.getAgentideHome)(),a=path.join(s,"analytics");fsSync.mkdirSync(a,{recursive:!0});const r=await this.findLiteLLMScript(),o=path.join(s,"litellm-otel.yaml"),n=path.join(a,"litellm.log"),c=path.join(a,"litellm.error.log");return process.platform==="win32"?vscode.window.createTerminal({name:t,cwd:path.dirname(i),env:{AGENT_HOME_DIR:s},shellPath:getWindowsPwshOrPowerShell(),shellArgs:["-NoProfile","-NoExit","-ExecutionPolicy","Bypass","-Command",this.buildWindowsSpotlightLifecycleCommand({action:e,startScript:i,litellmScript:r,agentHomeDir:s,configPath:o,stdoutPath:n,stderrPath:c})]}):vscode.window.createTerminal({name:t,cwd:path.dirname(i),env:{AGENT_HOME_DIR:s},shellPath:"/bin/bash",shellArgs:["-c",this.buildUnixSpotlightLifecycleCommand({action:e,startScript:i,litellmScript:r,agentHomeDir:s,configPath:o,stdoutPath:n,stderrPath:c})]})}buildWindowsSpotlightLifecycleCommand(t){const e=s=>`'${this.escapePowerShellSingleQuotedString(s)}'`,i=["$ErrorActionPreference = 'Continue'",`$env:AGENT_HOME_DIR = ${e(t.agentHomeDir)}`,`Write-Host ${e(this.getLifecycleTerminalIntro(t.action))}`];return(t.action==="stop"||t.action==="restart")&&i.push('Write-Host ""','Write-Host "Stopping LiteLLM proxy..."',...this.buildWindowsLiteLLMStopCommands(t.litellmScript,e)),t.action==="stop"?i.push('Write-Host ""','Write-Host "Stopping OTEL Collector..."',`& ${e(t.startScript)} -Stop`):t.action==="restart"?i.push('Write-Host ""','Write-Host "Restarting OTEL Collector..."',`& ${e(t.startScript)} -Stop`,"Start-Sleep 1",`& ${e(t.startScript)} -ForceDaemon`):i.push('Write-Host ""','Write-Host "Starting OTEL Collector..."',`& ${e(t.startScript)} -ForceDaemon`),(t.action==="start"||t.action==="restart")&&i.push('Write-Host ""',...this.buildWindowsLiteLLMStartCommands(t,e)),i.push('Write-Host ""','Write-Host "You can close this window."'),i.join(`\r
|
|
3
|
+
`)}buildWindowsLiteLLMStopCommands(t,e){return t?[`& ${e(t)} -Stop`]:['Write-Host "[WARN] LiteLLM launcher script not found. Skipping LiteLLM stop." -ForegroundColor Yellow']}buildWindowsLiteLLMStartCommands(t,e){if(!t.litellmScript)return['Write-Host "[WARN] LiteLLM launcher script not found. Skipping LiteLLM start." -ForegroundColor Yellow'];const i=(0,windowsCommandLine_1.buildWindowsArgumentLine)(["-NoProfile","-NoLogo","-ExecutionPolicy","Bypass","-File",t.litellmScript,"-ConfigPath",t.configPath]);return['Write-Host "Starting LiteLLM proxy..."',`if (-not (Test-Path ${e(t.configPath)})) {`,` Write-Host ${e(`[INFO] LiteLLM config missing: ${t.configPath} \u2014 launcher will re-create it from the bundled template.`)}`,"}",`$env:LITELLM_CONFIG_PATH = ${e(t.configPath)}`,"try {",` $proc = Start-Process -FilePath ${e(getWindowsPwshOrPowerShell())} -WindowStyle Hidden -WorkingDirectory ${e(path.dirname(t.litellmScript))} -ArgumentList ${e(i)} -RedirectStandardOutput ${e(t.stdoutPath)} -RedirectStandardError ${e(t.stderrPath)} -PassThru -ErrorAction Stop`,' Write-Host "[OK] LiteLLM launcher started (PID: $($proc.Id))"',` Write-Host ${e(` Logs: ${t.stdoutPath}`)}`,` Write-Host ${e(` Errors: ${t.stderrPath}`)}`,"} catch {",' Write-Host "[ERROR] Failed to start LiteLLM launcher." -ForegroundColor Red'," Write-Host $_.Exception.Message -ForegroundColor Red","}"]}buildUnixSpotlightLifecycleCommand(t){const e=s=>this.quoteBash(s),i=["set +e",`export AGENT_HOME_DIR=${e(t.agentHomeDir)}`,`mkdir -p ${e(path.dirname(t.stdoutPath))}`,`echo ${e(this.getLifecycleTerminalIntro(t.action))}`];return(t.action==="stop"||t.action==="restart")&&i.push('echo ""','echo "Stopping LiteLLM proxy..."',...this.buildUnixLiteLLMStopCommands(t.litellmScript,e)),t.action==="stop"?i.push('echo ""','echo "Stopping OTEL Collector..."',`${e(t.startScript)} --stop`):t.action==="restart"?i.push('echo ""','echo "Restarting OTEL Collector..."',`${e(t.startScript)} --stop`,"sleep 1",`${e(t.startScript)} --force-daemon`):i.push('echo ""','echo "Starting OTEL Collector..."',`${e(t.startScript)} --force-daemon`),(t.action==="start"||t.action==="restart")&&i.push('echo ""',...this.buildUnixLiteLLMStartCommands(t,e)),i.push('echo ""','echo "Press any key to close..."',"read -n 1"),i.join(`
|
|
4
|
+
`)}buildUnixLiteLLMStopCommands(t,e){return t?[`${e(t)} --stop`]:['echo "[WARN] LiteLLM launcher script not found. Skipping LiteLLM stop." >&2']}buildUnixLiteLLMStartCommands(t,e){return t.litellmScript?['echo "Starting LiteLLM proxy..."',`if [ ! -f ${e(t.configPath)} ]; then`,` echo ${e(`[INFO] LiteLLM config missing: ${t.configPath} \u2014 launcher will re-create it from the bundled template.`)}`,"fi",`export LITELLM_CONFIG_PATH=${e(t.configPath)}`,`nohup ${e(t.litellmScript)} --config ${e(t.configPath)} >> ${e(t.stdoutPath)} 2>> ${e(t.stderrPath)} &`,'echo "[OK] LiteLLM launcher started (PID: $!)"',`echo ${e(` Logs: ${t.stdoutPath}`)}`,`echo ${e(` Errors: ${t.stderrPath}`)}`]:['echo "[WARN] LiteLLM launcher script not found. Skipping LiteLLM start." >&2']}getLifecycleTerminalIntro(t){switch(t){case"start":return"Starting Spotlight (OTEL Collector + LiteLLM)...";case"stop":return"Stopping Spotlight (LiteLLM + OTEL Collector)...";case"restart":return"Restarting Spotlight (LiteLLM + OTEL Collector)..."}}quoteBash(t){return`'${t.replace(/'/g,"'\\''")}'`}async stopLiteLLMDirectly(){const e=process.platform==="win32"?["-Stop"]:["--stop"];return this.runLauncher(e,{detached:!1})}async startLiteLLMDirectly(){const t=path.join((0,index_1.getAgentideHome)(),"litellm-otel.yaml"),i=process.platform==="win32"?["-ConfigPath",t]:["--config",t];return this.runLauncher(i,{detached:!0,configPath:t})}async runLauncher(t,e){const i=await this.findLiteLLMScript();if(!i)return!1;const s=process.platform==="win32",a=s?getWindowsPwshOrPowerShell():"/bin/bash",r=s?["-NoProfile","-ExecutionPolicy","Bypass","-File",i,...t]:[i,...t],o={...process.env,AGENT_HOME_DIR:(0,index_1.getAgentideHome)()};if(o.AGENTHIPPO_EVIDENCE_CONTENT_CAPTURE||(o.AGENTHIPPO_EVIDENCE_CONTENT_CAPTURE="1"),e.configPath&&(o.LITELLM_CONFIG_PATH=e.configPath),s&&e.detached)return this.startLiteLLMViaHiddenWindowsProcess(i,t,o);if(e.detached){const n=path.join((0,index_1.getAgentideHome)(),"analytics");fsSync.mkdirSync(n,{recursive:!0});const c=fsSync.openSync(path.join(n,"litellm.log"),"a"),h=fsSync.openSync(path.join(n,"litellm.error.log"),"a");try{const d=(0,child_process_1.spawn)(a,r,{detached:!0,stdio:["ignore",c,h],windowsHide:!0,env:o,cwd:path.dirname(i)});return d.unref(),this.log(`LiteLLM launcher started (PID: ${d.pid})`),!0}catch(d){return this.log(`Failed to start LiteLLM: ${d}`),!1}finally{fsSync.closeSync(c),fsSync.closeSync(h)}}return new Promise(n=>{const c=(0,child_process_1.spawn)(a,r,{windowsHide:!0,env:o,cwd:path.dirname(i)});c.once("error",h=>{this.log(`LiteLLM launcher failed to spawn: ${h}`),n(!1)}),c.once("exit",h=>n(h===0))})}async startLiteLLMViaHiddenWindowsProcess(t,e,i){const s=path.join((0,index_1.getAgentideHome)(),"analytics");fsSync.mkdirSync(s,{recursive:!0});const a=path.join(s,"litellm.log"),r=path.join(s,"litellm.error.log"),o=(0,windowsCommandLine_1.buildWindowsArgumentLine)(["-NoProfile","-NoLogo","-ExecutionPolicy","Bypass","-File",t,...e]),n=[`$env:AGENT_HOME_DIR = '${this.escapePowerShellSingleQuotedString(i.AGENT_HOME_DIR??(0,index_1.getAgentideHome)())}'`,i.LITELLM_CONFIG_PATH?`$env:LITELLM_CONFIG_PATH = '${this.escapePowerShellSingleQuotedString(i.LITELLM_CONFIG_PATH)}'`:"",`$proc = Start-Process -FilePath '${this.escapePowerShellSingleQuotedString(getWindowsPwshOrPowerShell())}' -WindowStyle Hidden -WorkingDirectory '${this.escapePowerShellSingleQuotedString(path.dirname(t))}' -ArgumentList '${this.escapePowerShellSingleQuotedString(o)}' -RedirectStandardOutput '${this.escapePowerShellSingleQuotedString(a)}' -RedirectStandardError '${this.escapePowerShellSingleQuotedString(r)}' -PassThru`,"Write-Output $proc.Id"].filter(Boolean).join("; ");return new Promise(c=>{let h="",d="";const g=(0,child_process_1.spawn)(getWindowsPwshOrPowerShell(),["-NoProfile","-ExecutionPolicy","Bypass","-Command",n],{windowsHide:!0,env:i,cwd:path.dirname(t)});g.stdout.on("data",u=>{h+=u.toString()}),g.stderr.on("data",u=>{d+=u.toString()}),g.once("error",u=>{this.log(`LiteLLM launcher failed to spawn hidden Windows process: ${u}`),c(!1)}),g.once("exit",u=>{if(u!==0){const m=d.trim()||h.trim();this.log(`LiteLLM hidden Windows launcher exited with code ${u}${m?`: ${m}`:""}`),c(!1);return}const p=parseInt(h.trim(),10);Number.isNaN(p)||this.log(`LiteLLM hidden Windows process started (PID: ${p})`),c(!0)})})}escapePowerShellSingleQuotedString(t){return t.replace(/'/g,"''")}async findLiteLLMScript(){const t=this.extensionContext.extensionPath,i=process.platform==="win32"?"agentide-litellm.ps1":"agentide-litellm.sh",s=[path.join(t,"out","scripts",i),path.join(t,"scripts",i),path.join(t,"..","..","scripts",i)];for(const a of s)try{return await fs_1.promises.access(a),a}catch{}return null}async triggerIndexing(){if(!this.indexingService){vscode.window.showWarningMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Indexing service is not available.`);return}if(this.indexingService.isIndexing()){vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Indexing is already in progress.`);return}this.indexingService.scheduleIndexing(!0),vscode.window.showInformationMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Triggered indexing.`)}async showStatus(){const t=await this.getStackStatus(),e=vscode.workspace.getConfiguration("agentide.providers.litellm").get("baseUrl")?.trim(),i=t.otelRunning?"\u{1F7E2} 127.0.0.1:4318":"\u26AB Not running";let s;t.litellmRunning&&e?s=`\u{1F7E2} ${e}`:t.litellmRunning?s="\u{1F7E2} Set URL in Settings or Stop External LiteLLM":s="\u26AB Not running";const a=[`LiteLLM: ${s}`,`OTEL: ${i}`].join(`
|
|
5
|
+
|
|
6
|
+
`),r=(0,lifecycle_1.getSpotlightLifecycleAction)(t),o=(0,lifecycle_1.getSpotlightInstallAction)(await this.isAnalyticsConfigured());switch(await vscode.window.showInformationMessage(`${a}`,"Config",o,r)){case"Start":await this.start();break;case"Stop":await this.stop();break;case"Config":await this.openLiteLLMConfig();break;case"Restart All":await this.restart();break;case"Install":process.platform==="win32"?await this.setupWindowsSpotlight({reinstall:!1}):await vscode.commands.executeCommand("agentide.setupAnalytics");break;case"Reinstall":process.platform==="win32"?await this.setupWindowsSpotlight({reinstall:!0}):await vscode.commands.executeCommand("agentide.setupAnalytics");break}}async openLiteLLMConfig(){const t=path.join((0,index_1.getAgentideHome)(),"litellm-otel.yaml");try{await fs_1.promises.access(t)}catch{await vscode.window.showWarningMessage(`${branding_1.AGENTIDE_BRAND_NAME}: LiteLLM OTEL config not found.`,"Install")==="Install"&&await vscode.commands.executeCommand("agentide.setupAnalytics");return}const e=await vscode.workspace.openTextDocument(t);await vscode.window.showTextDocument(e)}async openQueryTerminal(){const t=await this.findScript("query-analytics.sh");if(!t){vscode.window.showErrorMessage(`${branding_1.AGENTIDE_BRAND_NAME}: Query script not found. Run 'Setup Analytics' first.`);return}this.createScriptTerminal("Spotlight Query",t,"--latest-session",!0).show()}async findScript(t){const e=this.extensionContext.extensionPath,i=path.join(e,"out","scripts","analytics",t);try{return await fs_1.promises.access(i),i}catch{}const s=path.join(e,"scripts","analytics",t);try{return await fs_1.promises.access(s),s}catch{}return null}updateStatusBar(t){this._status=t;let e;switch(t){case"running":this.statusBarItem.text="$(pulse) Spotlight",e="Spotlight: Running (OTEL + LiteLLM configured)",this.statusBarItem.color=new vscode.ThemeColor("testing.iconPassed"),this.statusBarItem.backgroundColor=void 0;break;case"partial":this.statusBarItem.text="$(pulse) Spotlight",e="Spotlight: Partial (click to configure)",this.statusBarItem.color=new vscode.ThemeColor("editorWarning.foreground"),this.statusBarItem.backgroundColor=void 0;break;case"stopped":this.statusBarItem.text="$(pulse) Spotlight",e="Spotlight: Stopped (click to start)",this.statusBarItem.color=void 0,this.statusBarItem.backgroundColor=void 0;break;case"checking":this.statusBarItem.text="$(sync~spin) Spotlight",e="Spotlight: Checking...",this.statusBarItem.color=void 0,this.statusBarItem.backgroundColor=void 0;break;case"error":this.statusBarItem.text="$(warning) Spotlight",e="Spotlight: Error (click to retry)",this.statusBarItem.color=new vscode.ThemeColor("errorForeground"),this.statusBarItem.backgroundColor=void 0;break}this.indexProgress.status==="indexing"&&(e+=`
|
|
7
|
+
|
|
8
|
+
Background analytics indexing is running (${this.indexProgress.percent}% complete). Charts may use JSONL fallback until indexing finishes.`),this.statusBarItem.tooltip=e,this.statusBarItem.show()}log(t){this.outputChannel.appendLine(`[Analytics] ${t}`)}createScriptTerminal(t,e,i,s=!1){const a=(0,index_1.getAgentideHome)();if(s){const r=`"${e}" ${i}`;return vscode.window.createTerminal({name:t,cwd:path.dirname(e),env:{AGENT_HOME_DIR:a},shellPath:"/bin/bash",shellArgs:["-c",`echo '$ ${r}'; echo ''; ${r}; echo ''; exec bash -l`]})}return vscode.window.createTerminal({name:t,cwd:path.dirname(e),env:{AGENT_HOME_DIR:a},shellPath:"/bin/bash",shellArgs:["-c",`"${e}" ${i}`]})}dispose(){this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=null),this.statusBarItem.dispose();for(const t of this.disposables)t.dispose()}}exports.AnalyticsService=AnalyticsService;
|