@agenthippo-ai/agenthippo 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/bin/agenthippo.js +2 -0
- package/out/agentpack/github.js +547 -0
- package/out/agentpack/index.js +66 -0
- package/out/agentpack/install.js +297 -0
- package/out/agentpack/manager.js +441 -0
- package/out/agentpack/manifest.js +135 -0
- package/out/agentpack/paths.js +475 -0
- package/out/agentpack/publish.js +248 -0
- package/out/agentpack/stores.js +554 -0
- package/out/agentpack/types.js +5 -0
- package/out/analytics/dashboard/artifactManager.js +439 -0
- package/out/analytics/dashboard/fleetDisplayUtils.js +159 -0
- package/out/analytics/dashboard/fleetOrchestrator.js +142 -0
- package/out/analytics/dashboard/fleetRegistry.js +79 -0
- package/out/analytics/dashboard/fleetRowDefaults.js +87 -0
- package/out/analytics/dashboard/fleetScriptAdapter.js +146 -0
- package/out/analytics/dashboard/fleetStatusUtils.js +30 -0
- package/out/analytics/dashboard/fleetTitleUtils.js +68 -0
- package/out/analytics/dashboard/fleetTypes.js +29 -0
- package/out/analytics/dashboard/index.js +17 -0
- package/out/analytics/dashboard/indexingService.js +422 -0
- package/out/analytics/dashboard/localFleetAdapter.js +222 -0
- package/out/analytics/dashboard/performanceMonitor.js +76 -0
- package/out/analytics/dashboard/processManager.js +209 -0
- package/out/analytics/dashboard/provider.js +3885 -0
- package/out/analytics/dashboard/queryRunner.js +994 -0
- package/out/analytics/dashboard/refreshPolicy.js +16 -0
- package/out/analytics/dashboard/scheduledFleetFingerprint.js +22 -0
- package/out/analytics/dashboard/scheduledFleetStorage.js +241 -0
- package/out/analytics/dashboard/scheduledFleetUtils.js +22 -0
- package/out/analytics/dashboard/sessionEventFleetStats.js +118 -0
- package/out/analytics/dashboard/sessionJsonlFleet.js +204 -0
- package/out/analytics/dashboard/teamViewDiscovery.js +106 -0
- package/out/analytics/dashboard/viewsConfigMerge.js +221 -0
- package/out/analytics/dashboard/webview/analytics-panel.html +155 -0
- package/out/analytics/dashboard/webview/codicon.ttf +0 -0
- package/out/analytics/dashboard/webview/index.html +78 -0
- package/out/analytics/dashboard/webview/panel.js +2295 -0
- package/out/analytics/dashboard/webview/runtime-bridge.js +82 -0
- package/out/analytics/dashboard/webview/styles.css +1009 -0
- package/out/analytics/lifecycle.js +43 -0
- package/out/analytics/service.js +1279 -0
- package/out/analytics/sessionEvents.js +231 -0
- package/out/auth/bootstrapApply.js +72 -0
- package/out/auth/brokerClient.js +126 -0
- package/out/auth/callbackUri.js +59 -0
- package/out/auth/callbackUriParse.js +59 -0
- package/out/auth/githubStoreGate.js +70 -0
- package/out/auth/loopbackAuthServer.js +165 -0
- package/out/auth/pkce.js +9 -0
- package/out/auth/provider.js +239 -0
- package/out/auth/sessionStore.js +193 -0
- package/out/auth/signInFlow.js +182 -0
- package/out/auth/types.js +12 -0
- package/out/auth-broker/config.js +62 -0
- package/out/auth-broker/jwt.js +105 -0
- package/out/auth-broker/pkce.js +57 -0
- package/out/auth-broker/server.js +539 -0
- package/out/auth-broker/store.js +273 -0
- package/out/base-prompts/gateway/openclaw-starter.json5 +144 -0
- package/out/base-prompts/gateway/slack-socket-mode-minimal.manifest.json +44 -0
- package/out/base-prompts/mcp-servers/.mcp.json +13 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/README.md +142 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/mcp.json +13 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/package-lock.json +1192 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/package.json +23 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/run-with-env.sh +12 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/sdk-test.js +102 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/simple-test.js +137 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-client.js +118 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-server.js +209 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/src/client.ts +431 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/src/index.ts +270 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/tsconfig.json +18 -0
- package/out/base-prompts/rules/AGENTS.md +204 -0
- package/out/base-prompts/skills/agent-browser/SKILL.md +102 -0
- package/out/base-prompts/skills/agent-builder/SKILL.md +73 -0
- package/out/base-prompts/skills/agent-builder/references/agent-pack.md +63 -0
- package/out/base-prompts/skills/agent-builder/references/crewai.md +66 -0
- package/out/base-prompts/skills/agent-builder/references/langchain.md +60 -0
- package/out/base-prompts/skills/agent-builder/references/raw-sdk.md +73 -0
- package/out/base-prompts/skills/agent-engine-creator/SKILL.md +586 -0
- package/out/base-prompts/skills/agent-engine-installer/SKILL.md +106 -0
- package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.mjs +259 -0
- package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.ps1 +189 -0
- package/out/base-prompts/skills/agenthippo-cli/SKILL.md +69 -0
- package/out/base-prompts/skills/agenthippo-cli/scripts/install.sh +63 -0
- package/out/base-prompts/skills/agentpack-creator/SKILL.md +375 -0
- package/out/base-prompts/skills/agentpack-creator/references/agent-templates.md +261 -0
- package/out/base-prompts/skills/agentpack-creator/references/agents-md-guide.md +195 -0
- package/out/base-prompts/skills/agentpack-creator/scripts/init_pack.py +391 -0
- package/out/base-prompts/skills/agentpack-creator/scripts/init_pack_test.py +294 -0
- package/out/base-prompts/skills/agentpack-testbench/SKILL.md +135 -0
- package/out/base-prompts/skills/algorithmic-art/LICENSE.txt +202 -0
- package/out/base-prompts/skills/algorithmic-art/SKILL.md +405 -0
- package/out/base-prompts/skills/algorithmic-art/templates/generator_template.js +223 -0
- package/out/base-prompts/skills/algorithmic-art/templates/viewer.html +599 -0
- package/out/base-prompts/skills/debug-agent/SKILL.md +83 -0
- package/out/base-prompts/skills/desktop-automation/SKILL.md +166 -0
- package/out/base-prompts/skills/desktop-automation/references/agenthippo-ui-recipes.md +441 -0
- package/out/base-prompts/skills/desktop-automation/scripts/windows-desktop-uia.psm1 +280 -0
- package/out/base-prompts/skills/docx/LICENSE.txt +30 -0
- package/out/base-prompts/skills/docx/SKILL.md +197 -0
- package/out/base-prompts/skills/docx/docx-js.md +350 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/pack.py +159 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/unpack.py +29 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/validate.py +69 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/base.py +951 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/docx.py +274 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
- package/out/base-prompts/skills/docx/ooxml.md +610 -0
- package/out/base-prompts/skills/docx/scripts/__init__.py +1 -0
- package/out/base-prompts/skills/docx/scripts/document.py +1276 -0
- package/out/base-prompts/skills/docx/scripts/templates/comments.xml +3 -0
- package/out/base-prompts/skills/docx/scripts/templates/commentsExtended.xml +3 -0
- package/out/base-prompts/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/out/base-prompts/skills/docx/scripts/templates/commentsIds.xml +3 -0
- package/out/base-prompts/skills/docx/scripts/templates/people.xml +3 -0
- package/out/base-prompts/skills/docx/scripts/utilities.py +374 -0
- package/out/base-prompts/skills/gateway-outbound/SKILL.md +136 -0
- package/out/base-prompts/skills/mcp-builder/LICENSE.txt +202 -0
- package/out/base-prompts/skills/mcp-builder/SKILL.md +328 -0
- package/out/base-prompts/skills/mcp-builder/reference/evaluation.md +602 -0
- package/out/base-prompts/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/out/base-prompts/skills/mcp-builder/reference/node_mcp_server.md +970 -0
- package/out/base-prompts/skills/mcp-builder/reference/python_mcp_server.md +719 -0
- package/out/base-prompts/skills/mcp-builder/scripts/connections.py +151 -0
- package/out/base-prompts/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/out/base-prompts/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/out/base-prompts/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/out/base-prompts/skills/openclaw/SKILL.md +406 -0
- package/out/base-prompts/skills/openclaw/scripts/run-smoke.sh +61 -0
- package/out/base-prompts/skills/pdf/LICENSE.txt +30 -0
- package/out/base-prompts/skills/pdf/SKILL.md +294 -0
- package/out/base-prompts/skills/pdf/forms.md +205 -0
- package/out/base-prompts/skills/pdf/reference.md +612 -0
- package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes.py +70 -0
- package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/out/base-prompts/skills/pdf/scripts/check_fillable_fields.py +12 -0
- package/out/base-prompts/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
- package/out/base-prompts/skills/pdf/scripts/create_validation_image.py +41 -0
- package/out/base-prompts/skills/pdf/scripts/extract_form_field_info.py +152 -0
- package/out/base-prompts/skills/pdf/scripts/fill_fillable_fields.py +114 -0
- package/out/base-prompts/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/out/base-prompts/skills/pptx/LICENSE.txt +30 -0
- package/out/base-prompts/skills/pptx/SKILL.md +484 -0
- package/out/base-prompts/skills/pptx/html2pptx.md +625 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/pack.py +159 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/unpack.py +29 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/validate.py +69 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/base.py +951 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/out/base-prompts/skills/pptx/ooxml.md +427 -0
- package/out/base-prompts/skills/pptx/scripts/html2pptx.js +984 -0
- package/out/base-prompts/skills/pptx/scripts/inventory.py +1020 -0
- package/out/base-prompts/skills/pptx/scripts/rearrange.py +231 -0
- package/out/base-prompts/skills/pptx/scripts/replace.py +385 -0
- package/out/base-prompts/skills/pptx/scripts/thumbnail.py +450 -0
- package/out/base-prompts/skills/prompt-lab/SKILL.md +149 -0
- package/out/base-prompts/skills/prompt-lab/scripts/query-analytics.sh +2551 -0
- package/out/base-prompts/skills/skill-creator/LICENSE.txt +202 -0
- package/out/base-prompts/skills/skill-creator/SKILL.md +371 -0
- package/out/base-prompts/skills/skill-creator/references/output-patterns.md +82 -0
- package/out/base-prompts/skills/skill-creator/references/workflows.md +28 -0
- package/out/base-prompts/skills/skill-creator/scripts/init_skill.py +303 -0
- package/out/base-prompts/skills/skill-creator/scripts/package_skill.py +110 -0
- package/out/base-prompts/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/out/base-prompts/skills/skill-installer/SKILL.md +251 -0
- package/out/base-prompts/skills/skill-installer/references/store-api.md +219 -0
- package/out/base-prompts/skills/spotlight-dashboard/SKILL.md +83 -0
- package/out/base-prompts/skills/spotlight-insights/SKILL.md +101 -0
- package/out/base-prompts/skills/spotlight-optimize/SKILL.md +93 -0
- package/out/base-prompts/skills/spotlight-optimize/scripts/query-analytics.sh +2551 -0
- package/out/base-prompts/skills/spotlight-query/SKILL.md +314 -0
- package/out/base-prompts/skills/spotlight-query/references/otel-schema.md +163 -0
- package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.sh +2551 -0
- package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.test.sh +744 -0
- package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/sessions/sess-test-1.jsonl +14 -0
- package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/.duckdb-index.json +7 -0
- package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/sample.jsonl +5 -0
- package/out/base-prompts/skills/spotlight-report/SKILL.md +86 -0
- package/out/base-prompts/skills/spotlight-visualize/SKILL.md +92 -0
- package/out/base-prompts/skills/spotlight-visualize/scripts/query-analytics.sh +2551 -0
- package/out/base-prompts/skills/xlsx/LICENSE.txt +30 -0
- package/out/base-prompts/skills/xlsx/SKILL.md +289 -0
- package/out/base-prompts/skills/xlsx/recalc.py +178 -0
- package/out/branding.js +23 -0
- package/out/cli/commands/anywhere.js +66 -0
- package/out/cli/commands/ask.js +243 -0
- package/out/cli/commands/auth-broker.js +24 -0
- package/out/cli/commands/auth.js +219 -0
- package/out/cli/commands/chat.js +354 -0
- package/out/cli/commands/deploy.js +223 -0
- package/out/cli/commands/gateway.js +160 -0
- package/out/cli/commands/pack.js +220 -0
- package/out/cli/commands/probe-custom-engine.js +82 -0
- package/out/cli/commands/serve.js +583 -0
- package/out/cli/commands/store.js +919 -0
- package/out/cli/credential-context.js +113 -0
- package/out/cli/deploy-init.js +2087 -0
- package/out/cli/deps.js +238 -0
- package/out/cli/index.js +390 -0
- package/out/cli/pack-loader.js +376 -0
- package/out/cli/run-custom-engine-runner.js +318 -0
- package/out/cli/runtime.js +409 -0
- package/out/cli/serve-hardening.js +325 -0
- package/out/cli/state-sync.js +135 -0
- package/out/cli/utils.js +220 -0
- package/out/cli/vscode-shim.js +86 -0
- package/out/engines/base.js +159 -0
- package/out/engines/claude.js +1215 -0
- package/out/engines/codex.js +759 -0
- package/out/engines/custom.js +632 -0
- package/out/engines/customEngineIpc.js +95 -0
- package/out/engines/customEngineRunnerEmbed.js +107 -0
- package/out/engines/customRegistry.js +274 -0
- package/out/engines/embeddedCustomEngineRunner.generated.js +9 -0
- package/out/engines/engineApiKey.js +138 -0
- package/out/engines/factory.js +45 -0
- package/out/engines/install.js +372 -0
- package/out/engines/persistentEngineWorker.js +320 -0
- package/out/engines/publish.js +341 -0
- package/out/engines/types.js +17 -0
- package/out/examples/run-headless-repl.js +291 -0
- package/out/examples/run-headless.js +187 -0
- package/out/extension.js +4472 -0
- package/out/gateway/bridge.js +805 -0
- package/out/gateway/cli-agent-id.js +36 -0
- package/out/gateway/client.js +303 -0
- package/out/gateway/client.test.js +395 -0
- package/out/gateway/gateway-scope-errors.js +14 -0
- package/out/gateway/gatewayBackup.js +76 -0
- package/out/gateway/gatewayRouteIndex.js +371 -0
- package/out/gateway/gatewaySessionStore.js +243 -0
- package/out/gateway/index.js +31 -0
- package/out/gateway/lifecycle.js +3056 -0
- package/out/gateway/openclaw-channel-routing.js +317 -0
- package/out/gateway/outboundHandles.js +373 -0
- package/out/gateway/outboundPaths.js +72 -0
- package/out/gateway/outboundSend.js +254 -0
- package/out/gateway/protocol.js +48 -0
- package/out/gateway/resetMappings.js +52 -0
- package/out/gateway/service.js +1244 -0
- package/out/gateway/sessionRouting.js +77 -0
- package/out/headless/index.js +505 -0
- package/out/headless/sync.js +473 -0
- package/out/mcp/publish.js +143 -0
- package/out/mcp.js +597 -0
- package/out/permissions.js +108 -0
- package/out/permissions.mapping.yaml +68 -0
- package/out/registry/index.js +332 -0
- package/out/remote/handleRemoteChat.js +122 -0
- package/out/remote/remotePackStatusBar.js +103 -0
- package/out/remote/serveClient.js +216 -0
- package/out/remoteSkills.js +191 -0
- package/out/runtime/index.js +32 -0
- package/out/runtime/interfaces/config-provider.js +32 -0
- package/out/runtime/interfaces/edit-tracker.js +22 -0
- package/out/runtime/interfaces/index.js +29 -0
- package/out/runtime/interfaces/logger.js +40 -0
- package/out/runtime/interfaces/permission-handler.js +66 -0
- package/out/runtime/interfaces/session-store.js +342 -0
- package/out/runtime/vscode/index.js +20 -0
- package/out/runtime/vscode/vscode-config-provider.js +77 -0
- package/out/runtime/vscode/vscode-edit-tracker.js +120 -0
- package/out/runtime/vscode/vscode-logger.js +30 -0
- package/out/runtime/vscode/vscode-permission-handler.js +72 -0
- package/out/runtime/vscode/vscode-session-store.js +22 -0
- package/out/scripts/agentide-litellm.ps1 +501 -0
- package/out/scripts/agentide-litellm.sh +700 -0
- package/out/scripts/agentide_litellm_hooks_v1.py +604 -0
- package/out/scripts/analytics/agent-fleet-widget.js +954 -0
- package/out/scripts/analytics/agentide-litellm-otel.config.yaml +160 -0
- package/out/scripts/analytics/default-seed-scripts.json +12 -0
- package/out/scripts/analytics/duckdbLocator.js +29 -0
- package/out/scripts/analytics/fleet-local-adapter.js +246 -0
- package/out/scripts/analytics/fleet-workflow.sh +263 -0
- package/out/scripts/analytics/generate-default-charts.py +685 -0
- package/out/scripts/analytics/hotspot-analysis-widget.js +909 -0
- package/out/scripts/analytics/index-traces.py +1394 -0
- package/out/scripts/analytics/install-analytics.sh +286 -0
- package/out/scripts/analytics/live-fleet-4-collector.cjs +315 -0
- package/out/scripts/analytics/live-fleet-4-daemon.mjs +134 -0
- package/out/scripts/analytics/live-fleet-4-widget.cjs +433 -0
- package/out/scripts/analytics/otel-collector.yaml +55 -0
- package/out/scripts/analytics/query-analytics.ps1 +396 -0
- package/out/scripts/analytics/query-analytics.sh +2551 -0
- package/out/scripts/analytics/session-comparison-widget.js +1468 -0
- package/out/scripts/analytics/session-timeline-widget.js +2137 -0
- package/out/scripts/analytics/setup-analytics.ps1 +432 -0
- package/out/scripts/analytics/setup-analytics.sh +854 -0
- package/out/scripts/analytics/start-analytics.ps1 +169 -0
- package/out/scripts/analytics/start-analytics.sh +323 -0
- package/out/scripts/analytics/token-cost-flamegraph-widget.js +954 -0
- package/out/scripts/analytics/token-cost-trend-widget.js +1062 -0
- package/out/scripts/analytics/workflows-collector.cjs +315 -0
- package/out/scripts/analytics/workflows-daemon.mjs +186 -0
- package/out/scripts/analytics/workflows-widget.cjs +433 -0
- package/out/scripts/analytics/wow-model-widget.js +191 -0
- package/out/scripts/gateway/Dockerfile.serve +45 -0
- package/out/scripts/gateway/docker-serve.sh +248 -0
- package/out/scripts/gateway/setup-gateway-server.ps1 +953 -0
- package/out/scripts/gateway/setup-gateway-server.sh +935 -0
- package/out/scripts/gateway/setup-gateway.ps1 +1813 -0
- package/out/scripts/gateway/setup-gateway.sh +1541 -0
- package/out/scripts/setup-cli.ps1 +86 -0
- package/out/scripts/setup-cli.sh +117 -0
- package/out/scripts/tools-manifest.json +83 -0
- package/out/scripts/vendor-tools.mjs +234 -0
- package/out/session.js +272 -0
- package/out/shared/agentEngines.js +170 -0
- package/out/shared/index.js +109 -0
- package/out/shared/models.js +235 -0
- package/out/shared/providers.js +202 -0
- package/out/skills/publish.js +178 -0
- package/out/spotlight/install.js +339 -0
- package/out/spotlight/publish.js +544 -0
- package/out/spotlight/yaml.js +31 -0
- package/out/store/github/setup.js +235 -0
- package/out/store/github/templates/build-index.ts +339 -0
- package/out/store/github/templates/build-index.yml +97 -0
- package/out/store/github/templates/package.json +11 -0
- package/out/store/index.js +755 -0
- package/out/store/oramaIndex.js +884 -0
- package/out/store/shared.js +241 -0
- package/out/sync.js +1827 -0
- package/out/terminalLogger.js +358 -0
- package/out/test/agentEnvFile.test.js +97 -0
- package/out/test/agentYaml.test.js +373 -0
- package/out/test/agentpack.test.js +639 -0
- package/out/test/analytics-lifecycle.test.js +174 -0
- package/out/test/analytics.test.js +524 -0
- package/out/test/auth-bootstrapApply.test.js +102 -0
- package/out/test/auth-broker.test.js +434 -0
- package/out/test/auth-callback.test.js +62 -0
- package/out/test/branding.test.js +229 -0
- package/out/test/cli-agent-id.test.js +55 -0
- package/out/test/credential-context.test.js +105 -0
- package/out/test/customEngineInstall.test.js +100 -0
- package/out/test/customRegistry.test.js +122 -0
- package/out/test/deploy-init.test.js +532 -0
- package/out/test/deps-auto-install.test.js +81 -0
- package/out/test/engine-integration.test.js +297 -0
- package/out/test/enginePaths.test.js +195 -0
- package/out/test/enginePublish.test.js +82 -0
- package/out/test/fleetDisplayUtils.test.js +96 -0
- package/out/test/gateway-client.test.js +381 -0
- package/out/test/gateway-lifecycle.test.js +608 -0
- package/out/test/gateway-outbound.test.js +531 -0
- package/out/test/gateway-reset-mappings.test.js +221 -0
- package/out/test/gateway-route-index.test.js +235 -0
- package/out/test/gateway-session-routing.test.js +47 -0
- package/out/test/gateway-session-store.test.js +216 -0
- package/out/test/github.test.js +232 -0
- package/out/test/headless-sync.test.js +279 -0
- package/out/test/helpers/manifest-fixtures.js +27 -0
- package/out/test/mcp-obo.test.js +82 -0
- package/out/test/mcp.test.js +307 -0
- package/out/test/openclaw-channel-routing.test.js +191 -0
- package/out/test/pathSafety.test.js +63 -0
- package/out/test/permissions.test.js +175 -0
- package/out/test/persistent-engine-worker.test.js +220 -0
- package/out/test/refreshPolicy.test.js +60 -0
- package/out/test/registry.test.js +351 -0
- package/out/test/runtime.test.js +349 -0
- package/out/test/scheduledFleetStorage.test.js +72 -0
- package/out/test/serve-hardening.test.js +192 -0
- package/out/test/serveClient.test.js +173 -0
- package/out/test/sessionJsonlFleet.test.js +78 -0
- package/out/test/shared.test.js +173 -0
- package/out/test/skills-mcp.test.js +299 -0
- package/out/test/spotlightPublish.test.js +299 -0
- package/out/test/spotlightYaml.test.js +58 -0
- package/out/test/state-sync-peer.test.js +74 -0
- package/out/test/store.test.js +331 -0
- package/out/test/stores.test.js +504 -0
- package/out/test/sync-switch.test.js +251 -0
- package/out/test/teamViewDiscovery.test.js +90 -0
- package/out/test/toolPath.test.js +120 -0
- package/out/test/utils.test.js +308 -0
- package/out/test/viewsConfigMerge.test.js +180 -0
- package/out/test/windows-command-line.test.js +75 -0
- package/out/utils/agentEnvFile.js +131 -0
- package/out/utils/binary.js +175 -0
- package/out/utils/index.js +37 -0
- package/out/utils/network.js +74 -0
- package/out/utils/pathSafety.js +60 -0
- package/out/utils/paths.js +116 -0
- package/out/utils/pid.js +180 -0
- package/out/utils/pythonRunner.js +258 -0
- package/out/utils/resolveNodeBinary.js +168 -0
- package/out/utils/toolPath.js +83 -0
- package/out/utils/windowsCommandLine.js +29 -0
- package/out/utils.js +915 -0
- package/out/workspaceFolders.js +59 -0
- package/package.json +41 -0
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Deploy Init Test Suite (serve-v3 §A4)
|
|
4
|
+
*
|
|
5
|
+
* Verifies the generator emits well-formed artifacts for every target:
|
|
6
|
+
* YAML/JSON parse, Dockerfile shape, shell scripts pass `bash -n`, and the
|
|
7
|
+
* .env.example scan reflects the pack's ${env:...} references.
|
|
8
|
+
*--------------------------------------------------------------------------------------------*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
require("mocha");
|
|
44
|
+
const assert = __importStar(require("assert"));
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const os = __importStar(require("os"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const child_process_1 = require("child_process");
|
|
49
|
+
const yaml = __importStar(require("js-yaml"));
|
|
50
|
+
const deploy_init_1 = require("../cli/deploy-init");
|
|
51
|
+
const deploy_1 = require("../cli/commands/deploy");
|
|
52
|
+
const CTX = {
|
|
53
|
+
packName: 'databricks-analyst',
|
|
54
|
+
image: 'ghcr.io/agenthippo/runtime:2026.06',
|
|
55
|
+
port: 8080,
|
|
56
|
+
engine: 'claude',
|
|
57
|
+
envVars: ['DATABRICKS_HOST', 'DATABRICKS_HTTP_PATH'],
|
|
58
|
+
publicHostname: deploy_init_1.DEPLOY_PUBLIC_HOSTNAME,
|
|
59
|
+
};
|
|
60
|
+
suite('deploy-init: target registry', () => {
|
|
61
|
+
test('isDeployTarget recognizes known and rejects unknown', () => {
|
|
62
|
+
for (const t of deploy_init_1.DEPLOY_TARGETS) {
|
|
63
|
+
assert.ok((0, deploy_init_1.isDeployTarget)(t));
|
|
64
|
+
}
|
|
65
|
+
assert.strictEqual((0, deploy_init_1.isDeployTarget)('heroku'), false);
|
|
66
|
+
assert.strictEqual((0, deploy_init_1.isDeployTarget)('all'), false); // handled separately by the command
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
suite('deploy-init: scanEnvRefs', () => {
|
|
70
|
+
let dir;
|
|
71
|
+
setup(() => {
|
|
72
|
+
dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ah-scan-'));
|
|
73
|
+
});
|
|
74
|
+
teardown(() => {
|
|
75
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
76
|
+
});
|
|
77
|
+
test('collects ${env:VAR} across files, de-dupes and sorts', () => {
|
|
78
|
+
fs.mkdirSync(path.join(dir, 'mcp'), { recursive: true });
|
|
79
|
+
fs.writeFileSync(path.join(dir, 'mcp', 'databricks.mcp.json'), JSON.stringify({ env: { H: '${env:DATABRICKS_HOST}', T: '${env:DATABRICKS_TOKEN}' } }));
|
|
80
|
+
fs.writeFileSync(path.join(dir, 'agent.yaml'), 'x: ${env:DATABRICKS_HOST}\n'); // dup
|
|
81
|
+
assert.deepStrictEqual((0, deploy_init_1.scanEnvRefs)(dir), ['DATABRICKS_HOST', 'DATABRICKS_TOKEN']);
|
|
82
|
+
});
|
|
83
|
+
test('skips node_modules / deploy / .git', () => {
|
|
84
|
+
fs.mkdirSync(path.join(dir, 'node_modules'), { recursive: true });
|
|
85
|
+
fs.writeFileSync(path.join(dir, 'node_modules', 'x.json'), '${env:SHOULD_NOT_APPEAR}');
|
|
86
|
+
fs.mkdirSync(path.join(dir, 'deploy'), { recursive: true });
|
|
87
|
+
fs.writeFileSync(path.join(dir, 'deploy', 'y.json'), '${env:ALSO_NOT}');
|
|
88
|
+
fs.writeFileSync(path.join(dir, 'agent.yaml'), 'name: ${env:REAL_ONE}');
|
|
89
|
+
assert.deepStrictEqual((0, deploy_init_1.scanEnvRefs)(dir), ['REAL_ONE']);
|
|
90
|
+
});
|
|
91
|
+
test('empty pack → no vars', () => {
|
|
92
|
+
fs.writeFileSync(path.join(dir, 'agent.yaml'), 'metadata:\n name: x\n');
|
|
93
|
+
assert.deepStrictEqual((0, deploy_init_1.scanEnvRefs)(dir), []);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
suite('deploy-init: renderEnvExample', () => {
|
|
97
|
+
test('lists scanned vars and model credential', () => {
|
|
98
|
+
const out = (0, deploy_init_1.renderEnvExample)(['FOO', 'BAR']);
|
|
99
|
+
assert.ok(!out.includes('AGENTHIPPO_SERVE_API_KEY='), 'serve bearer key must not appear — auth is the deploy layer');
|
|
100
|
+
assert.ok(out.includes('ANTHROPIC_API_KEY='));
|
|
101
|
+
assert.ok(out.includes('FOO='));
|
|
102
|
+
assert.ok(out.includes('BAR='));
|
|
103
|
+
});
|
|
104
|
+
test('edge .env keeps only the public hostname; auth secrets live in .env.auth', () => {
|
|
105
|
+
const out = (0, deploy_init_1.renderEnvExample)([], { edge: true });
|
|
106
|
+
assert.ok(out.includes(`AGENTHIPPO_PUBLIC_HOSTNAME=${deploy_init_1.DEPLOY_PUBLIC_HOSTNAME}`));
|
|
107
|
+
// The agent loads .env — the token-signing key and OAuth secrets must not be here.
|
|
108
|
+
assert.ok(!out.includes('AGENTHIPPO_AUTH_JWT_SECRET'), 'JWT secret must not be in the agent-shared .env');
|
|
109
|
+
assert.ok(!out.includes('OAUTH2_PROXY_CLIENT_SECRET'), 'OAuth secret must not be in the agent-shared .env');
|
|
110
|
+
assert.ok(out.includes('.env.auth'), 'edge .env should point operators at .env.auth');
|
|
111
|
+
});
|
|
112
|
+
test('renderAuthEnvExample carries the oauth2-proxy + JWT secrets', () => {
|
|
113
|
+
const out = (0, deploy_init_1.renderAuthEnvExample)();
|
|
114
|
+
assert.ok(out.includes('OAUTH2_PROXY_CLIENT_ID='));
|
|
115
|
+
assert.ok(out.includes('OAUTH2_PROXY_REDIRECT_URL='));
|
|
116
|
+
assert.ok(out.includes('OAUTH2_PROXY_REVERSE_PROXY=true'));
|
|
117
|
+
assert.ok(out.includes('AGENTHIPPO_AUTH_JWT_SECRET='));
|
|
118
|
+
});
|
|
119
|
+
test('renderAuthEnvExample honors custom hostname', () => {
|
|
120
|
+
const out = (0, deploy_init_1.renderAuthEnvExample)({ hostname: 'agents.example.com' });
|
|
121
|
+
assert.ok(out.includes('https://agents.example.com/oauth2/callback'));
|
|
122
|
+
assert.ok(!out.includes('auth.agenthippo.ai'));
|
|
123
|
+
});
|
|
124
|
+
test('vm target embeds custom hostname in cloudflared and README', () => {
|
|
125
|
+
const files = (0, deploy_init_1.renderTarget)('vm', { ...CTX, publicHostname: 'agents.example.com' });
|
|
126
|
+
assert.ok(files['cloudflared.yml'].includes('agents.example.com'));
|
|
127
|
+
assert.ok(files['README.md'].includes('https://agents.example.com'));
|
|
128
|
+
assert.ok(files['run-edge-tunnel.sh'].includes('https://agents.example.com'));
|
|
129
|
+
});
|
|
130
|
+
test('cursor engine seeds CURSOR_API_KEY instead of ANTHROPIC', () => {
|
|
131
|
+
const out = (0, deploy_init_1.renderEnvExample)([], { engine: 'cursor' });
|
|
132
|
+
assert.ok(out.includes('CURSOR_API_KEY='));
|
|
133
|
+
assert.ok(!out.includes('ANTHROPIC_API_KEY='));
|
|
134
|
+
});
|
|
135
|
+
test('serveCmdArgs includes custom engine and model', () => {
|
|
136
|
+
const args = (0, deploy_init_1.serveCmdArgs)({ ...CTX, engine: 'cursor', model: 'auto', image: 'x', envVars: [] });
|
|
137
|
+
assert.ok(args.includes('--engine'));
|
|
138
|
+
assert.ok(args.includes('cursor'));
|
|
139
|
+
assert.ok(args.includes('--model'));
|
|
140
|
+
assert.ok(args.includes('auto'));
|
|
141
|
+
assert.ok(!args.includes('--host'), 'bind address is set via AGENTHIPPO_SERVE_HOST in Dockerfile, not --host');
|
|
142
|
+
});
|
|
143
|
+
test('serveCmdArgs can include www-dir for cloudrun browser UI', () => {
|
|
144
|
+
const args = (0, deploy_init_1.serveCmdArgs)({ ...CTX, image: 'x', envVars: [] }, { wwwDir: '/app/pack/deploy/www' });
|
|
145
|
+
assert.ok(args.includes('--www-dir'));
|
|
146
|
+
assert.ok(args.includes('/app/pack/deploy/www'));
|
|
147
|
+
});
|
|
148
|
+
test('defaultRuntimeImage picks cursor layer for cursor engine', () => {
|
|
149
|
+
assert.ok((0, deploy_init_1.defaultRuntimeImage)('cursor').includes('cursor'));
|
|
150
|
+
assert.ok(!(0, deploy_init_1.defaultRuntimeImage)('claude').includes('cursor'));
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
suite('deploy-init: renderTarget produces well-formed artifacts', () => {
|
|
154
|
+
test('every target includes a scanned .env.example with the pack vars', () => {
|
|
155
|
+
for (const t of deploy_init_1.DEPLOY_TARGETS) {
|
|
156
|
+
const files = (0, deploy_init_1.renderTarget)(t, CTX);
|
|
157
|
+
assert.ok(files['.env.example'], `${t} missing .env.example`);
|
|
158
|
+
assert.ok(files['.env.example'].includes('DATABRICKS_HOST'), `${t} .env.example missing scanned var`);
|
|
159
|
+
assert.ok(files['README.md'], `${t} missing README.md`);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
test('image-based targets emit a valid 5-line-style Dockerfile referencing the runtime image', () => {
|
|
163
|
+
for (const t of ['vm', 'compose', 'cloudrun', 'spcs', 'cloudflare']) {
|
|
164
|
+
const df = (0, deploy_init_1.renderTarget)(t, CTX)['Dockerfile'];
|
|
165
|
+
assert.ok(df, `${t} missing Dockerfile`);
|
|
166
|
+
assert.ok(df.includes('FROM ghcr.io/agenthippo/runtime:2026.06'), `${t} Dockerfile missing FROM`);
|
|
167
|
+
assert.ok(df.includes('COPY . /app/pack/'), `${t} Dockerfile missing COPY`);
|
|
168
|
+
assert.ok(/EXPOSE 8080/.test(df), `${t} Dockerfile missing EXPOSE`);
|
|
169
|
+
assert.ok(df.includes('CMD ["serve"'), `${t} Dockerfile CMD must append to runtime ENTRYPOINT`);
|
|
170
|
+
assert.ok(!df.includes('CMD ["agenthippo"'), `${t} Dockerfile must not duplicate agenthippo in CMD`);
|
|
171
|
+
assert.ok(df.includes('ENV AGENTHIPPO_SERVE_HOST=0.0.0.0'), `${t} Dockerfile must bind on all interfaces in-container`);
|
|
172
|
+
assert.ok(!df.includes('"--host"'), `${t} Dockerfile must not pass unsupported --host to older runtimes`);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
test('image-based targets ship a .dockerignore that keeps skills and drops node_modules', () => {
|
|
176
|
+
for (const t of ['vm', 'compose', 'cloudrun', 'spcs', 'cloudflare']) {
|
|
177
|
+
const di = (0, deploy_init_1.renderTarget)(t, CTX)['.dockerignore'];
|
|
178
|
+
assert.ok(di, `${t} missing .dockerignore`);
|
|
179
|
+
assert.ok(di.includes('**/node_modules'), `${t} .dockerignore should exclude node_modules`);
|
|
180
|
+
assert.ok(di.includes('.git'), `${t} .dockerignore should exclude .git`);
|
|
181
|
+
// Ship only deploy/www/ from deploy/ (drops deploy/.env, credentials, build artifacts).
|
|
182
|
+
assert.ok(di.includes('deploy/*'), `${t} should exclude deploy/*`);
|
|
183
|
+
assert.ok(di.includes('!deploy/www/**'), `${t} should re-include deploy/www/**`);
|
|
184
|
+
// Defensive secret ignores.
|
|
185
|
+
assert.ok(di.includes('**/.env'), `${t} should ignore **/.env`);
|
|
186
|
+
assert.ok(di.includes('**/*credentials*.json'), `${t} should ignore credentials json`);
|
|
187
|
+
// skills/, scripts/, references/ must NOT be ignored lines.
|
|
188
|
+
const ignored = di.split('\n').map((l) => l.trim()).filter((l) => l && !l.startsWith('#'));
|
|
189
|
+
for (const keep of ['skills/', 'scripts/', 'references/', 'skills', 'scripts', 'references']) {
|
|
190
|
+
assert.ok(!ignored.includes(keep), `${t} .dockerignore must not ignore ${keep}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Source-based target ships no Dockerfile and no .dockerignore.
|
|
194
|
+
assert.strictEqual((0, deploy_init_1.renderTarget)('databricks-app', CTX)['.dockerignore'], undefined);
|
|
195
|
+
assert.strictEqual((0, deploy_init_1.renderTarget)('databricks-app', CTX)['Dockerfile'], undefined);
|
|
196
|
+
});
|
|
197
|
+
test('build scripts anchor to the staging root so they run from any cwd', () => {
|
|
198
|
+
// cloudrun + vm run.sh use `docker build -f deploy/Dockerfile .` → must cd to staging root.
|
|
199
|
+
assert.ok((0, deploy_init_1.renderTarget)('cloudrun', CTX)['cloudrun-deploy.sh'].includes('cd "$(dirname "$0")/.."'), 'cloudrun-deploy.sh must anchor to staging root');
|
|
200
|
+
assert.ok((0, deploy_init_1.renderTarget)('vm', CTX)['run.sh'].includes('cd "$(dirname "$0")/.."'), 'vm run.sh must anchor to staging root');
|
|
201
|
+
// edge tunnel uses docker compose (paths resolve relative to the compose file), so it
|
|
202
|
+
// anchors to deploy/ itself, not the staging root.
|
|
203
|
+
assert.ok((0, deploy_init_1.renderTarget)('vm', CTX)['run-edge-tunnel.sh'].includes('cd "$(dirname "$0")"'));
|
|
204
|
+
assert.ok(!(0, deploy_init_1.renderTarget)('vm', CTX)['run-edge-tunnel.sh'].includes('cd "$(dirname "$0")/.."'));
|
|
205
|
+
});
|
|
206
|
+
test('image-based Dockerfiles install skill requirements.txt/package.json deps at build time', () => {
|
|
207
|
+
for (const t of ['vm', 'compose', 'cloudrun', 'spcs', 'cloudflare']) {
|
|
208
|
+
const df = (0, deploy_init_1.renderTarget)(t, CTX)['Dockerfile'];
|
|
209
|
+
assert.ok(df.includes('requirements.txt'), `${t} Dockerfile should install python skill deps`);
|
|
210
|
+
assert.ok(df.includes('package.json'), `${t} Dockerfile should install node skill deps`);
|
|
211
|
+
assert.ok(df.includes('USER root') && df.includes('USER agent'), `${t} skill-deps step must run as root then drop back to agent`);
|
|
212
|
+
// Must not clobber the runtime ENTRYPOINT/CMD.
|
|
213
|
+
assert.ok(df.includes('CMD ["serve"'), `${t} CMD still present after skill-deps step`);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
test('databricks-app is source-based (no Dockerfile) with OBO scopes', () => {
|
|
217
|
+
const files = (0, deploy_init_1.renderTarget)('databricks-app', CTX);
|
|
218
|
+
assert.strictEqual(files['Dockerfile'], undefined);
|
|
219
|
+
const app = yaml.load(files['app.yaml']);
|
|
220
|
+
assert.deepStrictEqual(app.user_authorization?.scopes, ['sql']);
|
|
221
|
+
const pkg = JSON.parse(files['package.json']);
|
|
222
|
+
assert.ok(pkg.dependencies['@anthropic-ai/claude-code']);
|
|
223
|
+
assert.ok(pkg.dependencies['@agenthippo-ai/cli']);
|
|
224
|
+
});
|
|
225
|
+
test('YAML artifacts parse', () => {
|
|
226
|
+
assert.doesNotThrow(() => yaml.load((0, deploy_init_1.renderTarget)('vm', CTX)['docker-compose.yml']));
|
|
227
|
+
assert.doesNotThrow(() => yaml.load((0, deploy_init_1.renderTarget)('compose', CTX)['docker-compose.yml']));
|
|
228
|
+
assert.doesNotThrow(() => yaml.load((0, deploy_init_1.renderTarget)('spcs', CTX)['spec.yaml']));
|
|
229
|
+
assert.doesNotThrow(() => yaml.load((0, deploy_init_1.renderTarget)('databricks-app', CTX)['app.yaml']));
|
|
230
|
+
});
|
|
231
|
+
test('JSON artifacts parse (wrangler, package.json)', () => {
|
|
232
|
+
assert.doesNotThrow(() => JSON.parse((0, deploy_init_1.renderTarget)('cloudflare', CTX)['wrangler.jsonc']));
|
|
233
|
+
assert.doesNotThrow(() => JSON.parse((0, deploy_init_1.renderTarget)('databricks-app', CTX)['package.json']));
|
|
234
|
+
});
|
|
235
|
+
test('shell scripts are syntactically valid (bash -n)', () => {
|
|
236
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'ah-sh-'));
|
|
237
|
+
try {
|
|
238
|
+
const scripts = [
|
|
239
|
+
['run.sh', (0, deploy_init_1.renderTarget)('vm', CTX)['run.sh']],
|
|
240
|
+
['run-edge-tunnel.sh', (0, deploy_init_1.renderTarget)('vm', CTX)['run-edge-tunnel.sh']],
|
|
241
|
+
['cloudrun-deploy.sh', (0, deploy_init_1.renderTarget)('cloudrun', CTX)['cloudrun-deploy.sh']],
|
|
242
|
+
['cloudrun-edge-deploy.sh', (0, deploy_init_1.renderTarget)('cloudrun', { ...CTX, ingress: 'edge' })['cloudrun-deploy.sh']],
|
|
243
|
+
];
|
|
244
|
+
for (const [name, content] of scripts) {
|
|
245
|
+
const p = path.join(tmp, name);
|
|
246
|
+
fs.writeFileSync(p, content);
|
|
247
|
+
assert.doesNotThrow(() => (0, child_process_1.execFileSync)('bash', ['-n', p]), `${name} failed bash -n`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
finally {
|
|
251
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
test('cloudrun IAP is applied on the beta track with IAM bindings (no GA --iap on deploy)', () => {
|
|
255
|
+
const sh = (0, deploy_init_1.renderTarget)('cloudrun', CTX)['cloudrun-deploy.sh'];
|
|
256
|
+
assert.ok(sh.includes('--iap'), 'IAP enablement still referenced');
|
|
257
|
+
// Beta track: gcloud beta run services update --iap (GA `gcloud run ... --iap` is unsupported).
|
|
258
|
+
assert.ok(sh.includes('gcloud beta run services update'), 'IAP must be enabled on the beta track');
|
|
259
|
+
// Public access is governed by the run.invoker binding, stripped here; IAP role granted per IAP_MEMBERS.
|
|
260
|
+
assert.ok(sh.includes('remove-iam-policy-binding'), 'must strip allUsers invoker binding to keep service private');
|
|
261
|
+
assert.ok(sh.includes('roles/iap.httpsResourceAccessor'), 'must grant IAP-secured Web User role');
|
|
262
|
+
assert.ok(sh.includes('IAP_MEMBERS'), 'must surface IAP_MEMBERS for per-principal grants');
|
|
263
|
+
// The old GA `services update --no-allow-unauthenticated` (not a real flag) and inline IAP_FLAG are gone.
|
|
264
|
+
assert.ok(!sh.includes('IAP_FLAG'), 'IAP_FLAG array removed in favor of the beta-track block');
|
|
265
|
+
assert.ok(!sh.includes('--no-allow-unauthenticated "${IAP_FLAG[@]}"'), 'old GA IAP update line removed');
|
|
266
|
+
assert.ok(!sh.includes('AGENTHIPPO_SERVE_API_KEY'), 'serve bearer key must not appear — auth is IAP');
|
|
267
|
+
assert.ok(sh.includes('docker build'));
|
|
268
|
+
assert.ok(sh.includes('deploy/Dockerfile'));
|
|
269
|
+
});
|
|
270
|
+
test('cloudrun --ingress edge (Option B) fronts the agent with the AgentHippo edge, no IAP', () => {
|
|
271
|
+
const files = (0, deploy_init_1.renderTarget)('cloudrun', { ...CTX, ingress: 'edge' });
|
|
272
|
+
const svc = files['service.yaml'];
|
|
273
|
+
const caddy = files['Caddyfile'];
|
|
274
|
+
const sh = files['cloudrun-deploy.sh'];
|
|
275
|
+
// Edge artifacts present; IAP artifacts absent.
|
|
276
|
+
assert.ok(caddy, 'Caddyfile present');
|
|
277
|
+
assert.ok(svc.includes('name: caddy') && svc.includes('name: auth-broker') && svc.includes('name: oauth2-proxy'));
|
|
278
|
+
assert.ok(svc.includes('name: agent') && svc.includes('name: litellm') && svc.includes('name: otel-collector'), 'Spotlight sidecars still present behind the edge');
|
|
279
|
+
// Caddy is the ONLY ingress (one port); the agent is no longer ingress.
|
|
280
|
+
assert.strictEqual((svc.match(/containerPort:/g) || []).length, 1);
|
|
281
|
+
assert.ok(/- name: caddy\n image: caddy:/.test(svc), 'caddy is the first/ingress container');
|
|
282
|
+
// Agent listens on the internal edge port (not $PORT), so it doesn't clash with Caddy.
|
|
283
|
+
assert.ok(svc.includes('"--port", "8090"'), 'agent args override the port to the internal edge port');
|
|
284
|
+
assert.ok(svc.includes('"--www-dir", "/app/pack/deploy/www"'), 'agent still serves the www landing page');
|
|
285
|
+
// Sidecars share the pod's localhost (Cloud Run multi-container), not docker-DNS names.
|
|
286
|
+
assert.ok(!caddy.includes('oauth2-proxy:4180') && !caddy.includes('auth-broker:9780') && !caddy.includes('agent:8080'), 'edge Caddyfile must use localhost upstreams, not docker-DNS names');
|
|
287
|
+
assert.ok(caddy.includes('localhost:4180') && caddy.includes('localhost:9780') && caddy.includes('localhost:8090'), 'edge Caddyfile routes to oauth2-proxy / auth-broker / agent on localhost');
|
|
288
|
+
assert.ok(caddy.includes(':{$PORT}') && caddy.includes('auto_https off'), 'Caddy listens on HTTP :$PORT (Cloud Run terminates TLS)');
|
|
289
|
+
// Caddyfile is mounted from a Secret (the deploy script upserts it).
|
|
290
|
+
assert.ok(svc.includes('${SERVICE}-caddyfile'), 'Caddyfile mounted from a secret');
|
|
291
|
+
// auth-broker reuses the agent image (CLI ships `auth-broker`).
|
|
292
|
+
assert.ok(/- name: auth-broker\n image: \$\{IMAGE\}/.test(svc) && svc.includes('args: ["auth-broker"]'), 'auth-broker reuses the agent image with `auth-broker` args');
|
|
293
|
+
// No IAP anywhere in the edge path.
|
|
294
|
+
assert.ok(!sh.includes('--iap') && !sh.includes('iap.httpsResourceAccessor') && !sh.includes('IAP_MEMBERS'), 'edge deploy must not enable IAP');
|
|
295
|
+
// Cloud Run is public (allUsers invoker) so traffic can reach Caddy to be authed.
|
|
296
|
+
assert.ok(sh.includes('add-iam-policy-binding') && sh.includes('allUsers') && sh.includes('roles/run.invoker'), 'edge deploy grants allUsers invoker (Caddy is the gate, not Cloud Run)');
|
|
297
|
+
// Edge secrets upserted.
|
|
298
|
+
assert.ok(sh.includes('${SERVICE}-caddyfile') && sh.includes('${SERVICE}-auth-jwt-secret')
|
|
299
|
+
&& sh.includes('${SERVICE}-oauth-client-id') && sh.includes('${SERVICE}-oauth-cookie-secret'), 'edge deploy upserts Caddyfile + JWT + OAuth secrets');
|
|
300
|
+
// Render includes the edge placeholders.
|
|
301
|
+
assert.ok(sh.includes('${PUBLIC_HOSTNAME}') && sh.includes('${ALLOWED_DOMAINS}'), 'deploy renders edge hostname/domain placeholders');
|
|
302
|
+
// The edge split auth env is shipped (so the agent container never loads the JWT/OAuth secrets).
|
|
303
|
+
assert.ok(files['.env.auth.example'], 'edge ships .env.auth.example (split auth secrets)');
|
|
304
|
+
assert.ok(files['.env.auth.example'].includes('OAUTH2_PROXY_CLIENT_ID') && files['.env.auth.example'].includes('AGENTHIPPO_AUTH_JWT_SECRET'));
|
|
305
|
+
// Note: service.yaml is a sed-template (${SERVICE}/${IMAGE}/${PUBLIC_HOSTNAME}/…), so it is
|
|
306
|
+
// only valid YAML after the deploy script substitutes placeholders — same as the IAP template.
|
|
307
|
+
});
|
|
308
|
+
test('cloudrun --ingress edge-fed (A′) verifies the shared JWT — no oauth2-proxy, no per-service OAuth', () => {
|
|
309
|
+
const files = (0, deploy_init_1.renderTarget)('cloudrun', {
|
|
310
|
+
...CTX, ingress: 'edge-fed', idpUrl: 'https://auth.agenthippo.ai', cookieDomain: '.agenthippo.ai',
|
|
311
|
+
});
|
|
312
|
+
const svc = files['service.yaml'];
|
|
313
|
+
const caddy = files['Caddyfile'];
|
|
314
|
+
const sh = files['cloudrun-deploy.sh'];
|
|
315
|
+
// Federated artifacts present.
|
|
316
|
+
assert.ok(caddy && svc && sh);
|
|
317
|
+
// Caddy + auth-broker + agent + Spotlight sidecars, but NO oauth2-proxy container.
|
|
318
|
+
assert.ok(svc.includes('name: caddy') && svc.includes('name: auth-broker') && svc.includes('name: agent'));
|
|
319
|
+
assert.ok(svc.includes('name: litellm') && svc.includes('name: otel-collector'), 'Spotlight sidecars present');
|
|
320
|
+
assert.ok(!svc.includes('name: oauth2-proxy'), 'edge-fed must NOT ship an oauth2-proxy container');
|
|
321
|
+
assert.strictEqual((svc.match(/containerPort:/g) || []).length, 1, 'Caddy is the only ingress port');
|
|
322
|
+
// auth-broker carries the federated cookie/IdP config + the shared JWT secret.
|
|
323
|
+
assert.ok(svc.includes('AGENTHIPPO_AUTH_COOKIE_DOMAIN') && svc.includes('AGENTHIPPO_AUTH_IDP_URL'), 'auth-broker gets the federated cookie domain + IdP URL');
|
|
324
|
+
assert.ok(svc.includes('${SERVICE}-auth-jwt-secret'), 'shared JWT secret mounted from a secret');
|
|
325
|
+
assert.ok(svc.includes('AGENTHIPPO_AUTH_COOKIE_NAME'), 'cookie name configured');
|
|
326
|
+
// In-memory state (no GCS bucket → no STATE_BUCKET requirement, no gcsfuse).
|
|
327
|
+
assert.ok(svc.includes('emptyDir') && svc.includes('medium: Memory'), 'state is in-memory emptyDir');
|
|
328
|
+
assert.ok(!svc.includes('gcsfuse') && !svc.includes('${STATE_BUCKET}'), 'no GCS state volume');
|
|
329
|
+
// Caddyfile: forward_auth to auth-broker only; no oauth2-proxy routes; IdP browser-login redirect.
|
|
330
|
+
assert.ok(caddy.includes('forward_auth localhost:9780'), 'Caddy verifies via auth-broker');
|
|
331
|
+
assert.ok(!caddy.includes('localhost:4180') && !caddy.includes('/oauth2/'), 'no oauth2-proxy routes in Caddyfile');
|
|
332
|
+
assert.ok(caddy.includes('https://auth.agenthippo.ai/oauth/browser-login'), 'browser 401 redirects to the central IdP browser-login endpoint');
|
|
333
|
+
assert.ok(caddy.includes('return_to='), 'redirect carries a return_to for the round trip');
|
|
334
|
+
// Deploy script: NO OAuth client/cookie secrets; upserts caddyfile + JWT + provider/litellm;
|
|
335
|
+
// allUsers invoker; domain-mappings create; no IAP; no STATE_BUCKET.
|
|
336
|
+
assert.ok(!sh.includes('OAUTH_CLIENT_ID') && !sh.includes('OAUTH_CLIENT_SECRET') && !sh.includes('OAUTH_COOKIE_SECRET'), 'edge-fed deploy must not reference any Google OAuth client');
|
|
337
|
+
assert.ok(sh.includes('${SERVICE}-caddyfile') && sh.includes('${SERVICE}-auth-jwt-secret')
|
|
338
|
+
&& sh.includes('${SERVICE}-provider-key') && sh.includes('${SERVICE}-litellm-key'), 'edge-fed deploy upserts caddyfile + shared JWT + provider/litellm secrets');
|
|
339
|
+
assert.ok(!sh.includes('STATE_BUCKET'), 'edge-fed has no STATE_BUCKET (in-memory state)');
|
|
340
|
+
assert.ok(sh.includes('allUsers') && sh.includes('roles/run.invoker'), 'allUsers invoker (Caddy is the gate)');
|
|
341
|
+
assert.ok(sh.includes('domain-mappings create'), 'maps the *.agenthippo.ai subdomain');
|
|
342
|
+
assert.ok(!sh.includes('--iap') && !sh.includes('iap.httpsResourceAccessor'), 'no IAP');
|
|
343
|
+
// Split auth env is federated: shared JWT secret + cookie domain + IdP URL, NO Google OAuth client.
|
|
344
|
+
const auth = files['.env.auth.example'];
|
|
345
|
+
assert.ok(auth, 'edge-fed ships .env.auth.example');
|
|
346
|
+
assert.ok(auth.includes('AGENTHIPPO_AUTH_JWT_SECRET') && auth.includes('AGENTHIPPO_AUTH_COOKIE_DOMAIN')
|
|
347
|
+
&& auth.includes('AGENTHIPPO_AUTH_IDP_URL'), 'federated auth env carries the shared JWT + cookie/IdP config');
|
|
348
|
+
assert.ok(!auth.includes('OAUTH2_PROXY_CLIENT_ID'), 'federated auth env has no Google OAuth client');
|
|
349
|
+
// Shell + rendered YAML are well-formed.
|
|
350
|
+
assert.doesNotThrow(() => (0, child_process_1.execFileSync)('bash', ['-n', '-c', sh]));
|
|
351
|
+
const rendered = svc
|
|
352
|
+
.replace(/\$\{SERVICE\}/g, 'customer-service-edge')
|
|
353
|
+
.replace(/\$\{IMAGE\}/g, 'us-docker.pkg.dev/x/y/z:latest')
|
|
354
|
+
.replace(/\$\{LITELLM_IMAGE\}/g, 'ghcr.io/agenthippo/litellm-gateway:2026.06')
|
|
355
|
+
.replace(/\$\{PUBLIC_HOSTNAME\}/g, 'cs.agenthippo.ai')
|
|
356
|
+
.replace(/\$\{ALLOWED_DOMAINS\}/g, 'agenthippo.ai');
|
|
357
|
+
assert.doesNotThrow(() => yaml.load(rendered), 'rendered service.yaml is valid YAML');
|
|
358
|
+
});
|
|
359
|
+
test('renderAuthEnvExample fed variant has no Google OAuth client', () => {
|
|
360
|
+
const out = (0, deploy_init_1.renderAuthEnvExample)({ hostname: 'cs.agenthippo.ai', fed: true, idpUrl: 'https://auth.agenthippo.ai', cookieDomain: '.agenthippo.ai' });
|
|
361
|
+
assert.ok(out.includes('AGENTHIPPO_AUTH_JWT_SECRET'));
|
|
362
|
+
assert.ok(out.includes('AGENTHIPPO_AUTH_COOKIE_DOMAIN=.agenthippo.ai'));
|
|
363
|
+
assert.ok(out.includes('AGENTHIPPO_AUTH_IDP_URL=https://auth.agenthippo.ai'));
|
|
364
|
+
assert.ok(!out.includes('OAUTH2_PROXY_CLIENT_ID'));
|
|
365
|
+
});
|
|
366
|
+
test('cloudrun claude pack ships the Spotlight multi-container stack (litellm + otel sidecars)', () => {
|
|
367
|
+
const files = (0, deploy_init_1.renderTarget)('cloudrun', CTX); // CTX engine = claude → model-routed → Spotlight
|
|
368
|
+
const svc = files['service.yaml'];
|
|
369
|
+
assert.ok(svc, 'service.yaml present');
|
|
370
|
+
assert.ok(svc.includes('name: agent') && svc.includes('name: litellm') && svc.includes('name: otel-collector'));
|
|
371
|
+
// Agent routes through the in-pod LiteLLM; LiteLLM exports to the in-pod collector.
|
|
372
|
+
assert.ok(svc.includes('http://localhost:4443'), 'agent → litellm on localhost');
|
|
373
|
+
assert.ok(svc.includes('http://localhost:4318'), 'litellm → collector on localhost');
|
|
374
|
+
assert.ok(svc.includes('gcsfuse.run.googleapis.com'), 'GCS-backed /state volume');
|
|
375
|
+
assert.ok(files['otel-collector.yaml'].includes('file/jsonl'), 'collector writes JSONL traces');
|
|
376
|
+
// Exactly one container exposes a port (Cloud Run ingress requirement).
|
|
377
|
+
assert.strictEqual((svc.match(/containerPort:/g) || []).length, 1);
|
|
378
|
+
// The CLAUDE_CODE_USE_VERTEX-vs-LiteLLM contradiction is gone from the active deploy.
|
|
379
|
+
assert.ok(!svc.includes('CLAUDE_CODE_USE_VERTEX'));
|
|
380
|
+
assert.ok(!files['cloudrun-deploy.sh'].includes('CLAUDE_CODE_USE_VERTEX'));
|
|
381
|
+
});
|
|
382
|
+
test('cloudrun cursor pack wires CURSOR_API_KEY secret and engine flags', () => {
|
|
383
|
+
const ctx = { ...CTX, packName: 'customer-service', engine: 'cursor', model: 'auto', image: 'ghcr.io/agenthippo/runtime:latest-cursor' };
|
|
384
|
+
const sh = (0, deploy_init_1.renderTarget)('cloudrun', ctx)['cloudrun-deploy.sh'];
|
|
385
|
+
const df = (0, deploy_init_1.renderTarget)('cloudrun', ctx)['Dockerfile'];
|
|
386
|
+
assert.ok(sh.includes('CURSOR_API_KEY=agenthippo-cursor-key:latest'));
|
|
387
|
+
assert.ok(sh.includes('AGENTHIPPO_CUSTOM_ENGINES_DIR=/engines'));
|
|
388
|
+
assert.ok(df.includes('"--engine","cursor"'));
|
|
389
|
+
assert.ok(df.includes('"--model","auto"'));
|
|
390
|
+
assert.ok(df.includes('runtime:latest-cursor'));
|
|
391
|
+
assert.ok(df.includes('"--www-dir","/app/pack/deploy/www"'));
|
|
392
|
+
assert.ok((0, deploy_init_1.renderTarget)('cloudrun', ctx)['www/index.html'].includes('<h1>customer-service</h1>'));
|
|
393
|
+
const env = (0, deploy_init_1.renderTarget)('cloudrun', ctx)['.env.example'];
|
|
394
|
+
assert.ok(env.includes('CURSOR_API_KEY='));
|
|
395
|
+
});
|
|
396
|
+
test('spcs egress is limited to the model API via one EAI', () => {
|
|
397
|
+
const sql = (0, deploy_init_1.renderTarget)('spcs', CTX)['deploy.sql'];
|
|
398
|
+
assert.ok(sql.includes('api.anthropic.com:443'));
|
|
399
|
+
assert.ok(/EXTERNAL ACCESS INTEGRATION/.test(sql));
|
|
400
|
+
});
|
|
401
|
+
test('vm target includes edge compose profile; agent has no SSO-bypass host port', () => {
|
|
402
|
+
const files = (0, deploy_init_1.renderTarget)('vm', CTX);
|
|
403
|
+
const compose = files['docker-compose.yml'];
|
|
404
|
+
assert.ok(compose.includes('profiles: ["edge"]'));
|
|
405
|
+
assert.ok(compose.includes('profiles: ["tunnel"]'));
|
|
406
|
+
assert.ok(compose.includes('cloudflared:'));
|
|
407
|
+
assert.ok(compose.includes('oauth2-proxy'));
|
|
408
|
+
assert.ok(compose.includes('caddy:'));
|
|
409
|
+
assert.ok(!compose.includes('127.0.0.1:8080:8080'), 'agent must not publish host port in compose (SSO bypass)');
|
|
410
|
+
assert.ok(compose.includes('OAUTH2_PROXY_REVERSE_PROXY'));
|
|
411
|
+
assert.ok(compose.includes('./www:/srv/www'));
|
|
412
|
+
assert.ok(files['run.sh'].includes('127.0.0.1:8080'));
|
|
413
|
+
assert.ok(files['run-edge-tunnel.sh'].includes('--profile edge --profile tunnel'));
|
|
414
|
+
assert.ok(files['Caddyfile'].includes('reverse_proxy agent:8080'));
|
|
415
|
+
assert.ok(files['Caddyfile'].includes('{$AGENTHIPPO_PUBLIC_HOSTNAME}'));
|
|
416
|
+
assert.ok(files['Caddyfile'].includes('@health path /health /ready'));
|
|
417
|
+
assert.ok(!files['Caddyfile'].includes('@api path /v1/* /health /ready'));
|
|
418
|
+
assert.ok(files['www/index.html'].includes('<form id="chat">'));
|
|
419
|
+
// In-compose config-file tunnel (the proven-live path): cloudflared container → caddy:80.
|
|
420
|
+
assert.ok(files['cloudflared.yml'].includes('http://caddy:80'), 'in-compose cloudflared reaches Caddy on the docker network');
|
|
421
|
+
assert.ok(!files['cloudflared.yml'].includes('http://127.0.0.1:80'), 'a container cannot reach Caddy via 127.0.0.1');
|
|
422
|
+
assert.ok(!files['cloudflared.yml'].includes('localhost:8080'));
|
|
423
|
+
assert.ok(compose.includes('tunnel --config /etc/cloudflared/config.yml run'), 'config-file mode');
|
|
424
|
+
assert.ok(compose.includes('./cloudflared.yml:/etc/cloudflared/config.yml'), 'mounts the routing config');
|
|
425
|
+
assert.ok(compose.includes('./tunnel-credentials.json:/etc/cloudflared/credentials.json'), 'mounts the creds');
|
|
426
|
+
assert.ok(!compose.includes('TUNNEL_TOKEN'), 'config-file mode does not use a token');
|
|
427
|
+
assert.ok(files['agenthippo-edge.service'].includes('--profile tunnel'));
|
|
428
|
+
assert.ok(files['.env.auth.example'].includes('OAUTH2_PROXY_CLIENT_ID'));
|
|
429
|
+
assert.ok(!files['.env.example'].includes('OAUTH2_PROXY_CLIENT_SECRET'), 'OAuth secret lives in .env.auth, not the agent-shared .env');
|
|
430
|
+
assert.ok(files['.env.example'].includes('tunnel-credentials.json'), 'edge env documents the creds file, not a token');
|
|
431
|
+
assert.ok(!files['.env.example'].includes('CLOUDFLARE_TUNNEL_TOKEN'), 'token mode removed');
|
|
432
|
+
assert.ok(files['.env.example'].includes(`AGENTHIPPO_PUBLIC_HOSTNAME=${deploy_init_1.DEPLOY_PUBLIC_HOSTNAME}`));
|
|
433
|
+
});
|
|
434
|
+
test('compose target includes edge profile and Caddyfile', () => {
|
|
435
|
+
const files = (0, deploy_init_1.renderTarget)('compose', CTX);
|
|
436
|
+
assert.ok(files['docker-compose.yml'].includes('profiles: ["edge"]'));
|
|
437
|
+
assert.ok(files['Caddyfile']);
|
|
438
|
+
assert.ok(files['.env.auth.example'].includes('OAUTH2_PROXY_PROVIDER'));
|
|
439
|
+
});
|
|
440
|
+
test('agent service does not load .env.auth; broker + oauth2-proxy do', () => {
|
|
441
|
+
const compose = (0, deploy_init_1.renderTarget)('compose', CTX)['docker-compose.yml'];
|
|
442
|
+
// The agent runs model-driven tool calls — it must never receive the token-signing key.
|
|
443
|
+
const agentBlock = compose.slice(compose.indexOf(' agent:'), compose.indexOf(' oauth2-proxy:'));
|
|
444
|
+
assert.ok(agentBlock.includes('env_file:'), 'sanity: located the agent service block');
|
|
445
|
+
assert.ok(!agentBlock.includes('.env.auth'), 'agent must not load .env.auth (JWT signing key + OAuth secrets)');
|
|
446
|
+
assert.ok(compose.includes('.env.auth'), 'broker/oauth2-proxy must load .env.auth');
|
|
447
|
+
});
|
|
448
|
+
});
|
|
449
|
+
suite('deploy-init: deployCommand stages a self-contained pack', () => {
|
|
450
|
+
let pack;
|
|
451
|
+
let staging;
|
|
452
|
+
setup(() => {
|
|
453
|
+
pack = fs.mkdtempSync(path.join(os.tmpdir(), 'ah-pack-'));
|
|
454
|
+
staging = fs.mkdtempSync(path.join(os.tmpdir(), 'ah-stage-'));
|
|
455
|
+
fs.writeFileSync(path.join(pack, 'agent.yaml'), 'apiVersion: agenthippo.ai/v1\nkind: Agent\nmetadata:\n name: cs-test\nspec:\n engine: claude\n model: litellm/gpt-5.5\n');
|
|
456
|
+
fs.writeFileSync(path.join(pack, 'AGENTS.md'), '# cs-test\n');
|
|
457
|
+
fs.mkdirSync(path.join(pack, 'skills', 'demo', 'scripts'), { recursive: true });
|
|
458
|
+
fs.writeFileSync(path.join(pack, 'skills', 'demo', 'scripts', 'run.sh'), 'echo hi\n');
|
|
459
|
+
fs.writeFileSync(path.join(pack, 'skills', 'demo', 'scripts', 'requirements.txt'), 'requests\n');
|
|
460
|
+
// Ignored by the copy filter: dev cache, secrets, source deploy/.
|
|
461
|
+
fs.mkdirSync(path.join(pack, 'node_modules', 'foo'), { recursive: true });
|
|
462
|
+
fs.writeFileSync(path.join(pack, 'node_modules', 'foo', 'index.js'), 'x');
|
|
463
|
+
fs.writeFileSync(path.join(pack, '.env'), 'SECRET=1\n');
|
|
464
|
+
fs.writeFileSync(path.join(pack, 'my-credentials.json'), '{}\n');
|
|
465
|
+
fs.mkdirSync(path.join(pack, 'deploy'), { recursive: true });
|
|
466
|
+
fs.writeFileSync(path.join(pack, 'deploy', 'leftover.yaml'), 'stale\n');
|
|
467
|
+
});
|
|
468
|
+
teardown(() => {
|
|
469
|
+
fs.rmSync(pack, { recursive: true, force: true });
|
|
470
|
+
fs.rmSync(staging, { recursive: true, force: true });
|
|
471
|
+
});
|
|
472
|
+
test('copies pack into staging root, drops node_modules/.env/credentials, writes deploy/ + root .dockerignore', async () => {
|
|
473
|
+
await (0, deploy_1.deployCommand)('init', pack, { target: 'cloudrun', out: staging, port: 8080, force: true });
|
|
474
|
+
// Pack content at the staging root.
|
|
475
|
+
assert.ok(fs.existsSync(path.join(staging, 'agent.yaml')), 'agent.yaml copied to staging root');
|
|
476
|
+
assert.ok(fs.existsSync(path.join(staging, 'AGENTS.md')), 'AGENTS.md copied to staging root');
|
|
477
|
+
assert.ok(fs.existsSync(path.join(staging, 'skills', 'demo', 'scripts', 'requirements.txt')), 'skill requirements.txt copied (needed by the build-time install step)');
|
|
478
|
+
// Filtered out (mirrors .dockerignore): no dev caches, no secrets.
|
|
479
|
+
assert.ok(!fs.existsSync(path.join(staging, 'node_modules')), 'node_modules must not be copied into staging');
|
|
480
|
+
assert.ok(!fs.existsSync(path.join(staging, '.env')), '.env must not be copied into staging');
|
|
481
|
+
assert.ok(!fs.existsSync(path.join(staging, 'my-credentials.json')), 'credentials json must not be copied');
|
|
482
|
+
// The source pack's own deploy/ is not copied (the generator owns staging/deploy/).
|
|
483
|
+
assert.ok(!fs.existsSync(path.join(staging, 'deploy', 'leftover.yaml')), 'source deploy/ must not be copied');
|
|
484
|
+
// Generated artifacts under staging/deploy/.
|
|
485
|
+
assert.ok(fs.existsSync(path.join(staging, 'deploy', 'Dockerfile')), 'Dockerfile at staging/deploy/Dockerfile');
|
|
486
|
+
assert.ok(fs.existsSync(path.join(staging, 'deploy', 'service.yaml')), 'service.yaml at staging/deploy/');
|
|
487
|
+
assert.ok(fs.existsSync(path.join(staging, 'deploy', 'cloudrun-deploy.sh')), 'cloudrun-deploy.sh at staging/deploy/');
|
|
488
|
+
// .dockerignore at the staging root (build-context root), NOT under deploy/.
|
|
489
|
+
assert.ok(fs.existsSync(path.join(staging, '.dockerignore')), '.dockerignore at staging root (context root)');
|
|
490
|
+
assert.ok(!fs.existsSync(path.join(staging, 'deploy', '.dockerignore')), '.dockerignore must not be under deploy/ (Docker would ignore it)');
|
|
491
|
+
// The generated build script self-anchors to the staging root.
|
|
492
|
+
const sh = fs.readFileSync(path.join(staging, 'deploy', 'cloudrun-deploy.sh'), 'utf8');
|
|
493
|
+
assert.ok(sh.includes('cd "$(dirname "$0")/.."'), 'cloudrun-deploy.sh anchors to staging root');
|
|
494
|
+
assert.ok(sh.includes('docker build') && sh.includes('deploy/Dockerfile') && sh.includes('-t "$IMAGE"'), 'build sources deploy/Dockerfile (sed-rewritten to AR base) with the staging root as context');
|
|
495
|
+
});
|
|
496
|
+
test('--packdir flag is honored as an alternative to the positional arg', async () => {
|
|
497
|
+
await (0, deploy_1.deployCommand)('init', undefined, { target: 'cloudrun', out: staging, port: 8080, force: true, packdir: pack });
|
|
498
|
+
assert.ok(fs.existsSync(path.join(staging, 'agent.yaml')), 'packdir flag resolved the pack');
|
|
499
|
+
assert.ok(fs.existsSync(path.join(staging, 'deploy', 'Dockerfile')), 'artifacts generated from packdir pack');
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
suite('deploy-init: copyPackToStaging dereferences symlinks + skips broken ones', () => {
|
|
503
|
+
let pack;
|
|
504
|
+
let staging;
|
|
505
|
+
setup(() => {
|
|
506
|
+
pack = fs.mkdtempSync(path.join(os.tmpdir(), 'ah-pack-'));
|
|
507
|
+
staging = fs.mkdtempSync(path.join(os.tmpdir(), 'ah-stage-'));
|
|
508
|
+
fs.writeFileSync(path.join(pack, 'agent.yaml'), 'apiVersion: agenthippo.ai/v1\nkind: Agent\nmetadata:\n name: link-test\nspec:\n engine: claude\n');
|
|
509
|
+
// Real skill content + a shared file the skill links to (relative symlink → resolved on copy).
|
|
510
|
+
fs.mkdirSync(path.join(pack, 'skills', 'demo'), { recursive: true });
|
|
511
|
+
fs.writeFileSync(path.join(pack, 'skills', 'demo', 'REAL.md'), '# real content\n');
|
|
512
|
+
fs.symlinkSync('REAL.md', path.join(pack, 'skills', 'demo', 'SKILL.md')); // valid relative symlink
|
|
513
|
+
// Broken symlink: target does not exist (the data-analyst hydration bug pattern).
|
|
514
|
+
fs.mkdirSync(path.join(pack, 'skills', 'broken'), { recursive: true });
|
|
515
|
+
fs.symlinkSync('/nonexistent/abs/path/SKILL.md', path.join(pack, 'skills', 'broken', 'SKILL.md'));
|
|
516
|
+
});
|
|
517
|
+
teardown(() => {
|
|
518
|
+
fs.rmSync(pack, { recursive: true, force: true });
|
|
519
|
+
fs.rmSync(staging, { recursive: true, force: true });
|
|
520
|
+
});
|
|
521
|
+
test('valid symlinks are dereferenced to real files; broken symlinks are skipped + reported', () => {
|
|
522
|
+
const broken = (0, deploy_1.copyPackToStaging)(pack, staging);
|
|
523
|
+
// Valid symlink → real file content in staging (not a symlink). Docker-safe.
|
|
524
|
+
const staged = path.join(staging, 'skills', 'demo', 'SKILL.md');
|
|
525
|
+
assert.ok(fs.existsSync(staged), 'valid symlink content copied to staging');
|
|
526
|
+
assert.ok(!fs.lstatSync(staged).isSymbolicLink(), 'staged entry is a real file, not a symlink');
|
|
527
|
+
assert.strictEqual(fs.readFileSync(staged, 'utf8'), '# real content\n');
|
|
528
|
+
// Broken symlink → not staged, and reported in the broken list.
|
|
529
|
+
assert.ok(!fs.existsSync(path.join(staging, 'skills', 'broken', 'SKILL.md')), 'broken symlink must not be staged');
|
|
530
|
+
assert.ok(broken.includes('skills/broken/SKILL.md'), 'broken symlink reported in returned list');
|
|
531
|
+
});
|
|
532
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Deps auto-install flag (serve-v3 A2 — self-contained image)
|
|
4
|
+
*
|
|
5
|
+
* Verifies AGENTHIPPO_NO_AUTO_INSTALL is actually honored (the runtime-install bug).
|
|
6
|
+
*--------------------------------------------------------------------------------------------*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
require("mocha");
|
|
42
|
+
const assert = __importStar(require("assert"));
|
|
43
|
+
const deps_1 = require("../cli/deps");
|
|
44
|
+
suite('deps: isAutoInstallDisabled', () => {
|
|
45
|
+
const KEYS = ['AGENTHIPPO_NO_AUTO_INSTALL', 'AGENTIDE_NO_AUTO_INSTALL'];
|
|
46
|
+
let saved;
|
|
47
|
+
setup(() => {
|
|
48
|
+
saved = {};
|
|
49
|
+
for (const k of KEYS) {
|
|
50
|
+
saved[k] = process.env[k];
|
|
51
|
+
delete process.env[k];
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
teardown(() => {
|
|
55
|
+
for (const k of KEYS) {
|
|
56
|
+
if (saved[k] === undefined)
|
|
57
|
+
delete process.env[k];
|
|
58
|
+
else
|
|
59
|
+
process.env[k] = saved[k];
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
test('unset → auto-install enabled (false)', () => {
|
|
63
|
+
assert.strictEqual((0, deps_1.isAutoInstallDisabled)(), false);
|
|
64
|
+
});
|
|
65
|
+
test('truthy values disable install', () => {
|
|
66
|
+
for (const v of ['1', 'true', 'TRUE', 'yes', 'on', ' 1 ']) {
|
|
67
|
+
process.env.AGENTHIPPO_NO_AUTO_INSTALL = v;
|
|
68
|
+
assert.strictEqual((0, deps_1.isAutoInstallDisabled)(), true, `value ${JSON.stringify(v)}`);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
test('falsey / empty values keep install enabled', () => {
|
|
72
|
+
for (const v of ['', '0', 'false', 'no']) {
|
|
73
|
+
process.env.AGENTHIPPO_NO_AUTO_INSTALL = v;
|
|
74
|
+
assert.strictEqual((0, deps_1.isAutoInstallDisabled)(), false, `value ${JSON.stringify(v)}`);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
test('legacy AGENTIDE_NO_AUTO_INSTALL is honored', () => {
|
|
78
|
+
process.env.AGENTIDE_NO_AUTO_INSTALL = '1';
|
|
79
|
+
assert.strictEqual((0, deps_1.isAutoInstallDisabled)(), true);
|
|
80
|
+
});
|
|
81
|
+
});
|