@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,1541 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) AgentHippo.ai. All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Agent Anywhere — Gateway Setup
|
|
6
|
+
#
|
|
7
|
+
# Installs OpenClaw Gateway and builds the web UI so users can
|
|
8
|
+
# configure messaging channels (Telegram, WhatsApp, Slack, etc.)
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
# ./setup-gateway.sh # Interactive
|
|
12
|
+
# ./setup-gateway.sh --source openclaw/openclaw#branch # Specify source
|
|
13
|
+
# ./setup-gateway.sh --source github:org/repo # npm git protocol
|
|
14
|
+
# ./setup-gateway.sh --source /path/to/local/openclaw # Local source
|
|
15
|
+
# ./setup-gateway.sh --check # Check status only
|
|
16
|
+
# ./setup-gateway.sh --uninstall # stop gateway + npm uninstall -g (config kept)
|
|
17
|
+
# ./setup-gateway.sh --reinstall --source <src> # uninstall, verify (--check), then install
|
|
18
|
+
# ./setup-gateway.sh --no-modify-path # opt out: skip adding wrapper dir to PATH
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
set -euo pipefail
|
|
22
|
+
|
|
23
|
+
# npm/@npmcli: lifecycle hooks use promise-spawn with shell=true → spawns bare `sh` (not /bin/sh).
|
|
24
|
+
# @npmcli/run-script setPATH() rebuilds PATH from node_modules/.bin walk + parent PATH; if PATH was
|
|
25
|
+
# empty/unset, `sh` is not on PATH → spawn sh ENOENT (baileys preinstall, etc.).
|
|
26
|
+
export PATH="/usr/bin:/bin:/usr/sbin:/sbin${PATH:+:$PATH}"
|
|
27
|
+
export npm_config_script_shell=/bin/sh
|
|
28
|
+
# Corepack should never block Agent Anywhere setup waiting for interactive approval.
|
|
29
|
+
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
|
30
|
+
|
|
31
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
32
|
+
|
|
33
|
+
# Colors
|
|
34
|
+
RED='\033[0;31m'
|
|
35
|
+
GREEN='\033[0;32m'
|
|
36
|
+
YELLOW='\033[1;33m'
|
|
37
|
+
BLUE='\033[0;34m'
|
|
38
|
+
CYAN='\033[0;36m'
|
|
39
|
+
BOLD='\033[1m'
|
|
40
|
+
NC='\033[0m'
|
|
41
|
+
|
|
42
|
+
# Defaults
|
|
43
|
+
INSTALL_SOURCE="${INSTALL_SOURCE:-}"
|
|
44
|
+
CHECK_ONLY=false
|
|
45
|
+
UNINSTALL=false
|
|
46
|
+
REINSTALL=false
|
|
47
|
+
GATEWAY_PORT="${GATEWAY_PORT:-18789}"
|
|
48
|
+
CONFIG_TEMPLATE="${CONFIG_TEMPLATE:-}"
|
|
49
|
+
PORT_FROM_CLI=false
|
|
50
|
+
MODIFY_PATH=true
|
|
51
|
+
|
|
52
|
+
if [[ "${AGENT_ANYWHERE_MODIFY_PATH:-0}" == "0" ]]; then
|
|
53
|
+
MODIFY_PATH=false
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Parse arguments
|
|
57
|
+
while [[ $# -gt 0 ]]; do
|
|
58
|
+
case "$1" in
|
|
59
|
+
--source|-s)
|
|
60
|
+
INSTALL_SOURCE="$2"
|
|
61
|
+
shift 2
|
|
62
|
+
;;
|
|
63
|
+
--uninstall)
|
|
64
|
+
UNINSTALL=true
|
|
65
|
+
shift
|
|
66
|
+
;;
|
|
67
|
+
--reinstall)
|
|
68
|
+
REINSTALL=true
|
|
69
|
+
shift
|
|
70
|
+
;;
|
|
71
|
+
--check|-c)
|
|
72
|
+
CHECK_ONLY=true
|
|
73
|
+
shift
|
|
74
|
+
;;
|
|
75
|
+
--port|-p)
|
|
76
|
+
GATEWAY_PORT="$2"
|
|
77
|
+
PORT_FROM_CLI=true
|
|
78
|
+
shift 2
|
|
79
|
+
;;
|
|
80
|
+
--config-template)
|
|
81
|
+
CONFIG_TEMPLATE="$2"
|
|
82
|
+
shift 2
|
|
83
|
+
;;
|
|
84
|
+
--modify-path)
|
|
85
|
+
MODIFY_PATH=true
|
|
86
|
+
shift
|
|
87
|
+
;;
|
|
88
|
+
--no-modify-path)
|
|
89
|
+
MODIFY_PATH=false
|
|
90
|
+
shift
|
|
91
|
+
;;
|
|
92
|
+
--help|-h)
|
|
93
|
+
echo "Usage: $0 [options]"
|
|
94
|
+
echo ""
|
|
95
|
+
echo "Options:"
|
|
96
|
+
echo " --source, -s <src> npm install source (git repo or local path)"
|
|
97
|
+
echo " --check, -c Check installation status only"
|
|
98
|
+
echo " --uninstall Stop gateway, remove global openclaw (~/.openclaw unchanged)"
|
|
99
|
+
echo " --reinstall With --source: uninstall, run check, then full install"
|
|
100
|
+
echo " --port, -p <port> Gateway port (default: gateway.port in ~/.openclaw/openclaw.json, else 18789)"
|
|
101
|
+
echo " --config-template <f> Path to starter config template"
|
|
102
|
+
echo " --modify-path Persist only the stable wrapper dir to your shell profile (default: on)"
|
|
103
|
+
echo " --no-modify-path Do not write the wrapper-dir PATH block to shell profiles"
|
|
104
|
+
echo " (set AGENT_ANYWHERE_MODIFY_PATH=0 to disable)"
|
|
105
|
+
echo " --help, -h Show this help"
|
|
106
|
+
exit 0
|
|
107
|
+
;;
|
|
108
|
+
*)
|
|
109
|
+
echo "Unknown option: $1"
|
|
110
|
+
exit 1
|
|
111
|
+
;;
|
|
112
|
+
esac
|
|
113
|
+
done
|
|
114
|
+
|
|
115
|
+
# Read gateway.port from ~/.openclaw/openclaw.json (JSON5-ish: strip // comments) for stop/check/start alignment with OpenClaw.
|
|
116
|
+
read_openclaw_config_gateway_port() {
|
|
117
|
+
local f="$HOME/.openclaw/openclaw.json"
|
|
118
|
+
[[ -f "$f" ]] || return 1
|
|
119
|
+
command -v node &>/dev/null || return 1
|
|
120
|
+
node -e '
|
|
121
|
+
const fs = require("fs");
|
|
122
|
+
const path = require("path");
|
|
123
|
+
const os = require("os");
|
|
124
|
+
const fp = path.join(os.homedir(), ".openclaw", "openclaw.json");
|
|
125
|
+
if (!fs.existsSync(fp)) process.exit(1);
|
|
126
|
+
let t = fs.readFileSync(fp, "utf8");
|
|
127
|
+
t = t.replace(/^\s*\/\/.*$/gm, "").replace(/,\s*([\]}])/g, "$1");
|
|
128
|
+
try {
|
|
129
|
+
const j = JSON.parse(t);
|
|
130
|
+
const p = j && j.gateway && j.gateway.port;
|
|
131
|
+
if (typeof p === "number" && p >= 1 && p <= 65535) { process.stdout.write(String(p)); process.exit(0); }
|
|
132
|
+
if (typeof p === "string" && /^[0-9]+$/.test(p)) { process.stdout.write(p); process.exit(0); }
|
|
133
|
+
} catch (e) {}
|
|
134
|
+
process.exit(1);
|
|
135
|
+
' 2>/dev/null
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# When --port is omitted, match the running gateway / OpenClaw config (IDE uses the same file).
|
|
139
|
+
if ! $PORT_FROM_CLI; then
|
|
140
|
+
_cfg_port=""
|
|
141
|
+
_cfg_port=$(read_openclaw_config_gateway_port) || true
|
|
142
|
+
if [[ -n "$_cfg_port" ]]; then
|
|
143
|
+
GATEWAY_PORT="$_cfg_port"
|
|
144
|
+
fi
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
# Logging
|
|
148
|
+
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
149
|
+
log_success() { echo -e "${GREEN} ✓${NC} $1"; }
|
|
150
|
+
log_warn() { echo -e "${YELLOW} ✗${NC} $1"; }
|
|
151
|
+
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
152
|
+
log_step() { echo -e "\n${BOLD}${CYAN}$1${NC}"; }
|
|
153
|
+
|
|
154
|
+
NODE_REQUIRED_VERSION="${NODE_REQUIRED_VERSION:-22.14.0}"
|
|
155
|
+
NODE_BOOTSTRAP_VERSION="${AGENT_ANYWHERE_NODE_VERSION:-22.22.0}"
|
|
156
|
+
NODE_BOOTSTRAP_ROOT="${HOME}/.agenthippo/tools/node"
|
|
157
|
+
NPM_GLOBAL_PREFIX="${HOME}/.npm-global"
|
|
158
|
+
USING_BOOTSTRAP_NODE=false
|
|
159
|
+
MANAGED_GATEWAY_STATE_DIR="${HOME}/.agenthippo/gateway"
|
|
160
|
+
MANAGED_GATEWAY_MANIFEST_PATH="${MANAGED_GATEWAY_STATE_DIR}/install.json"
|
|
161
|
+
MANAGED_GATEWAY_WRAPPER_DIR="${HOME}/.local/bin"
|
|
162
|
+
AGENT_ANYWHERE_PATH_MARKER_BEGIN="# >>> Agent Anywhere PATH >>>"
|
|
163
|
+
AGENT_ANYWHERE_PATH_MARKER_END="# <<< Agent Anywhere PATH <<<"
|
|
164
|
+
MANAGED_GATEWAY_WRAPPER_MARKER="# Managed by Agent Anywhere"
|
|
165
|
+
|
|
166
|
+
add_path_entry() {
|
|
167
|
+
local entry="$1"
|
|
168
|
+
[[ -n "$entry" ]] || return 0
|
|
169
|
+
local p new_path=""
|
|
170
|
+
IFS=':' read -r -a _path_parts <<<"${PATH:-}"
|
|
171
|
+
for p in "${_path_parts[@]}"; do
|
|
172
|
+
[[ -z "$p" || "$p" == "$entry" ]] && continue
|
|
173
|
+
if [[ -z "$new_path" ]]; then
|
|
174
|
+
new_path="$p"
|
|
175
|
+
else
|
|
176
|
+
new_path="$new_path:$p"
|
|
177
|
+
fi
|
|
178
|
+
done
|
|
179
|
+
export PATH="$entry${new_path:+:$new_path}"
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
path_contains_entry() {
|
|
183
|
+
local entry="$1"
|
|
184
|
+
[[ -n "$entry" ]] || return 1
|
|
185
|
+
local part
|
|
186
|
+
IFS=':' read -r -a _path_parts <<<"${PATH:-}"
|
|
187
|
+
for part in "${_path_parts[@]}"; do
|
|
188
|
+
[[ "$part" == "$entry" ]] && return 0
|
|
189
|
+
done
|
|
190
|
+
return 1
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
is_fish_profile() {
|
|
194
|
+
local file="$1"
|
|
195
|
+
[[ "$file" == "$HOME/.config/fish/config.fish" ]]
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
build_agent_anywhere_shell_path_block() {
|
|
199
|
+
local profile_file="${1:-}"
|
|
200
|
+
if is_fish_profile "$profile_file"; then
|
|
201
|
+
cat <<'EOF'
|
|
202
|
+
# >>> Agent Anywhere PATH >>>
|
|
203
|
+
# Added by Agent Anywhere setup: keep the stable wrapper dir on PATH.
|
|
204
|
+
function _agent_anywhere_prepend_path --argument-names entry
|
|
205
|
+
test -n "$entry"; or return 0
|
|
206
|
+
set -l filtered_path
|
|
207
|
+
for p in $PATH
|
|
208
|
+
if test "$p" != "$entry"
|
|
209
|
+
set -a filtered_path "$p"
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
set -gx PATH "$entry" $filtered_path
|
|
213
|
+
end
|
|
214
|
+
EOF
|
|
215
|
+
cat <<'EOF'
|
|
216
|
+
if test -d "$HOME/.local/bin"
|
|
217
|
+
_agent_anywhere_prepend_path "$HOME/.local/bin"
|
|
218
|
+
end
|
|
219
|
+
functions -e _agent_anywhere_prepend_path 2>/dev/null
|
|
220
|
+
# <<< Agent Anywhere PATH <<<
|
|
221
|
+
EOF
|
|
222
|
+
return 0
|
|
223
|
+
fi
|
|
224
|
+
|
|
225
|
+
cat <<'EOF'
|
|
226
|
+
# >>> Agent Anywhere PATH >>>
|
|
227
|
+
# Added by Agent Anywhere setup: keep the stable wrapper dir on PATH.
|
|
228
|
+
_agent_anywhere_prepend_path() {
|
|
229
|
+
[ -n "${1:-}" ] || return 0
|
|
230
|
+
PATH=":${PATH}:"
|
|
231
|
+
PATH="${PATH//:$1:/:}"
|
|
232
|
+
PATH="${PATH#:}"
|
|
233
|
+
PATH="${PATH%:}"
|
|
234
|
+
PATH="$1${PATH:+:$PATH}"
|
|
235
|
+
}
|
|
236
|
+
EOF
|
|
237
|
+
cat <<'EOF'
|
|
238
|
+
if [ -d "$HOME/.local/bin" ]; then
|
|
239
|
+
_agent_anywhere_prepend_path "$HOME/.local/bin"
|
|
240
|
+
fi
|
|
241
|
+
export PATH
|
|
242
|
+
unset -f _agent_anywhere_prepend_path 2>/dev/null || true
|
|
243
|
+
# <<< Agent Anywhere PATH <<<
|
|
244
|
+
EOF
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
upsert_shell_block_in_file() {
|
|
248
|
+
local file="$1"
|
|
249
|
+
local block tmp_file
|
|
250
|
+
block="$(build_agent_anywhere_shell_path_block "$file")"
|
|
251
|
+
if [[ ! -f "$file" ]]; then
|
|
252
|
+
if ! touch "$file" 2>/dev/null; then
|
|
253
|
+
log_warn "Could not update shell profile $file"
|
|
254
|
+
return 1
|
|
255
|
+
fi
|
|
256
|
+
fi
|
|
257
|
+
tmp_file="$(mktemp "${TMPDIR:-/tmp}/agent-anywhere-profile.XXXXXX")"
|
|
258
|
+
awk -v begin="$AGENT_ANYWHERE_PATH_MARKER_BEGIN" -v end="$AGENT_ANYWHERE_PATH_MARKER_END" '
|
|
259
|
+
$0 == begin { skip = 1; next }
|
|
260
|
+
$0 == end { skip = 0; next }
|
|
261
|
+
skip != 1 { print }
|
|
262
|
+
' "$file" > "$tmp_file"
|
|
263
|
+
printf '\n%s\n' "$block" >> "$tmp_file"
|
|
264
|
+
if cmp -s "$file" "$tmp_file"; then
|
|
265
|
+
rm -f "$tmp_file"
|
|
266
|
+
return 1
|
|
267
|
+
fi
|
|
268
|
+
mv "$tmp_file" "$file"
|
|
269
|
+
return 0
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
resolve_active_shell_profile() {
|
|
273
|
+
local shell_name
|
|
274
|
+
shell_name="$(basename "${SHELL:-}")"
|
|
275
|
+
case "$shell_name" in
|
|
276
|
+
zsh)
|
|
277
|
+
printf '%s\n' "$HOME/.zshrc"
|
|
278
|
+
;;
|
|
279
|
+
bash)
|
|
280
|
+
if [[ "$(uname -s 2>/dev/null)" == "Darwin" ]]; then
|
|
281
|
+
printf '%s\n' "$HOME/.bash_profile"
|
|
282
|
+
else
|
|
283
|
+
printf '%s\n' "$HOME/.bashrc"
|
|
284
|
+
fi
|
|
285
|
+
;;
|
|
286
|
+
fish)
|
|
287
|
+
printf '%s\n' "$HOME/.config/fish/config.fish"
|
|
288
|
+
;;
|
|
289
|
+
*)
|
|
290
|
+
printf '%s\n' "$HOME/.profile"
|
|
291
|
+
;;
|
|
292
|
+
esac
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
persist_shell_path_setup() {
|
|
296
|
+
$MODIFY_PATH || return 0
|
|
297
|
+
|
|
298
|
+
local file changed=false
|
|
299
|
+
file="$(resolve_active_shell_profile)"
|
|
300
|
+
if upsert_shell_block_in_file "$file"; then
|
|
301
|
+
changed=true
|
|
302
|
+
fi
|
|
303
|
+
|
|
304
|
+
if $changed; then
|
|
305
|
+
log_info "Persisted PATH for future terminals in $file (open a new terminal window after setup)."
|
|
306
|
+
fi
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
remove_agent_anywhere_shell_block_from_file() {
|
|
310
|
+
local file="$1"
|
|
311
|
+
[[ -f "$file" ]] || return 1
|
|
312
|
+
|
|
313
|
+
local tmp_file
|
|
314
|
+
tmp_file="$(mktemp "${TMPDIR:-/tmp}/agent-anywhere-profile-clean.XXXXXX")"
|
|
315
|
+
awk -v begin="$AGENT_ANYWHERE_PATH_MARKER_BEGIN" -v end="$AGENT_ANYWHERE_PATH_MARKER_END" '
|
|
316
|
+
$0 == begin { skip = 1; next }
|
|
317
|
+
$0 == end { skip = 0; next }
|
|
318
|
+
skip != 1 { print }
|
|
319
|
+
' "$file" > "$tmp_file"
|
|
320
|
+
|
|
321
|
+
if cmp -s "$file" "$tmp_file"; then
|
|
322
|
+
rm -f "$tmp_file"
|
|
323
|
+
return 1
|
|
324
|
+
fi
|
|
325
|
+
|
|
326
|
+
mv "$tmp_file" "$file"
|
|
327
|
+
return 0
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
cleanup_shell_path_setup() {
|
|
331
|
+
local file changed=false
|
|
332
|
+
local -a profile_targets=(
|
|
333
|
+
"$HOME/.zprofile"
|
|
334
|
+
"$HOME/.zshrc"
|
|
335
|
+
"$HOME/.bash_profile"
|
|
336
|
+
"$HOME/.bashrc"
|
|
337
|
+
"$HOME/.profile"
|
|
338
|
+
"$HOME/.config/fish/config.fish"
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
for file in "${profile_targets[@]}"; do
|
|
342
|
+
if remove_agent_anywhere_shell_block_from_file "$file"; then
|
|
343
|
+
changed=true
|
|
344
|
+
fi
|
|
345
|
+
done
|
|
346
|
+
|
|
347
|
+
if $changed; then
|
|
348
|
+
log_info "Removed Agent Anywhere PATH block from shell profiles."
|
|
349
|
+
fi
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
set_npm_user_prefix() {
|
|
353
|
+
mkdir -p "$NPM_GLOBAL_PREFIX/bin" "$NPM_GLOBAL_PREFIX/lib" 2>/dev/null || true
|
|
354
|
+
export npm_config_prefix="$NPM_GLOBAL_PREFIX"
|
|
355
|
+
add_path_entry "$NPM_GLOBAL_PREFIX/bin"
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
npm_global_install_writable() {
|
|
359
|
+
command -v npm &>/dev/null || return 1
|
|
360
|
+
local prefix root root_parent
|
|
361
|
+
prefix="$(npm prefix -g 2>/dev/null || true)"
|
|
362
|
+
[[ -n "$prefix" && -d "$prefix" && -w "$prefix" ]] || return 1
|
|
363
|
+
if [[ -d "$prefix/bin" && ! -w "$prefix/bin" ]]; then
|
|
364
|
+
return 1
|
|
365
|
+
fi
|
|
366
|
+
root="$(npm root -g 2>/dev/null || true)"
|
|
367
|
+
[[ -n "$root" ]] || return 1
|
|
368
|
+
root_parent="$(dirname "$root")"
|
|
369
|
+
[[ -d "$root_parent" && -w "$root_parent" ]]
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
configure_npm_global_context() {
|
|
373
|
+
if [[ "${npm_config_prefix:-}" == "$NPM_GLOBAL_PREFIX" ]]; then
|
|
374
|
+
unset npm_config_prefix
|
|
375
|
+
fi
|
|
376
|
+
if [[ "${NPM_CONFIG_PREFIX:-}" == "$NPM_GLOBAL_PREFIX" ]]; then
|
|
377
|
+
unset NPM_CONFIG_PREFIX
|
|
378
|
+
fi
|
|
379
|
+
|
|
380
|
+
# Default: use npm's normal global prefix (nvm/fnm/homebrew/system).
|
|
381
|
+
# Fallback to ~/.npm-global only when the default prefix is not writable.
|
|
382
|
+
if npm_global_install_writable; then
|
|
383
|
+
return 0
|
|
384
|
+
fi
|
|
385
|
+
set_npm_user_prefix
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
node_version_is_compatible() {
|
|
389
|
+
local version="${1:-}"
|
|
390
|
+
version="${version#v}"
|
|
391
|
+
local required="${NODE_REQUIRED_VERSION#v}"
|
|
392
|
+
local major minor patch_rest patch req_major req_minor req_patch_rest req_patch
|
|
393
|
+
IFS='.' read -r major minor patch_rest <<<"$version"
|
|
394
|
+
IFS='.' read -r req_major req_minor req_patch_rest <<<"$required"
|
|
395
|
+
patch="${patch_rest%%[^0-9]*}"
|
|
396
|
+
req_patch="${req_patch_rest%%[^0-9]*}"
|
|
397
|
+
major="${major:-0}"
|
|
398
|
+
minor="${minor:-0}"
|
|
399
|
+
patch="${patch:-0}"
|
|
400
|
+
req_major="${req_major:-0}"
|
|
401
|
+
req_minor="${req_minor:-0}"
|
|
402
|
+
req_patch="${req_patch:-0}"
|
|
403
|
+
[[ "$major" =~ ^[0-9]+$ && "$minor" =~ ^[0-9]+$ && "$patch" =~ ^[0-9]+$ ]] || return 1
|
|
404
|
+
[[ "$req_major" =~ ^[0-9]+$ && "$req_minor" =~ ^[0-9]+$ && "$req_patch" =~ ^[0-9]+$ ]] || return 1
|
|
405
|
+
if [[ "$major" -gt "$req_major" ]]; then
|
|
406
|
+
return 0
|
|
407
|
+
fi
|
|
408
|
+
if [[ "$major" -lt "$req_major" ]]; then
|
|
409
|
+
return 1
|
|
410
|
+
fi
|
|
411
|
+
if [[ "$minor" -gt "$req_minor" ]]; then
|
|
412
|
+
return 0
|
|
413
|
+
fi
|
|
414
|
+
if [[ "$minor" -lt "$req_minor" ]]; then
|
|
415
|
+
return 1
|
|
416
|
+
fi
|
|
417
|
+
[[ "$patch" -ge "$req_patch" ]]
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
node_is_compatible() {
|
|
421
|
+
if ! command -v node &>/dev/null; then
|
|
422
|
+
return 1
|
|
423
|
+
fi
|
|
424
|
+
local version
|
|
425
|
+
version=$(node -v 2>/dev/null || true)
|
|
426
|
+
node_version_is_compatible "$version"
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
activate_bootstrap_node_if_available() {
|
|
430
|
+
local candidate_dir candidate_node version
|
|
431
|
+
[[ -d "$NODE_BOOTSTRAP_ROOT" ]] || return 1
|
|
432
|
+
while IFS= read -r candidate_node; do
|
|
433
|
+
candidate_dir="${candidate_node%/node}"
|
|
434
|
+
[[ -x "$candidate_node" ]] || continue
|
|
435
|
+
version=$("$candidate_node" -v 2>/dev/null || true)
|
|
436
|
+
if node_version_is_compatible "$version"; then
|
|
437
|
+
add_path_entry "$candidate_dir"
|
|
438
|
+
USING_BOOTSTRAP_NODE=true
|
|
439
|
+
return 0
|
|
440
|
+
fi
|
|
441
|
+
done < <(find "$NODE_BOOTSTRAP_ROOT" -maxdepth 4 -type f -path '*/bin/node' 2>/dev/null | sort -r)
|
|
442
|
+
return 1
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
resolve_gateway_wrapper_path() {
|
|
446
|
+
printf '%s\n' "${MANAGED_GATEWAY_WRAPPER_DIR}/hippoclaw"
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
resolve_openclaw_wrapper_path() {
|
|
450
|
+
printf '%s\n' "${MANAGED_GATEWAY_WRAPPER_DIR}/openclaw"
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
wrapper_is_managed_by_agent_anywhere() {
|
|
454
|
+
local wrapper_path="$1"
|
|
455
|
+
[[ -f "$wrapper_path" ]] || return 1
|
|
456
|
+
grep -Fq "$MANAGED_GATEWAY_WRAPPER_MARKER" "$wrapper_path" 2>/dev/null
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
write_gateway_wrapper() {
|
|
460
|
+
local node_path="$1"
|
|
461
|
+
local entry_script_path="$2"
|
|
462
|
+
local wrapper_path="$3"
|
|
463
|
+
mkdir -p "$(dirname "$wrapper_path")"
|
|
464
|
+
cat > "$wrapper_path" <<EOF
|
|
465
|
+
#!/bin/sh
|
|
466
|
+
$MANAGED_GATEWAY_WRAPPER_MARKER
|
|
467
|
+
exec "$node_path" "$entry_script_path" "\$@"
|
|
468
|
+
EOF
|
|
469
|
+
chmod +x "$wrapper_path"
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
resolve_managed_gateway_install_from_root() {
|
|
473
|
+
local node_path="$1"
|
|
474
|
+
local package_root="$2"
|
|
475
|
+
local bin_dir="$3"
|
|
476
|
+
[[ -x "$node_path" && -d "$package_root" ]] || return 1
|
|
477
|
+
node - "$node_path" "$package_root" "$bin_dir" <<'EOF'
|
|
478
|
+
const fs = require("fs");
|
|
479
|
+
const path = require("path");
|
|
480
|
+
const [nodePath, pkgRoot, binDir] = process.argv.slice(2);
|
|
481
|
+
const pkgJsonPath = path.join(pkgRoot, "package.json");
|
|
482
|
+
if (!fs.existsSync(pkgJsonPath)) {
|
|
483
|
+
process.exit(1);
|
|
484
|
+
}
|
|
485
|
+
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
|
486
|
+
let bins = pkg.bin;
|
|
487
|
+
if (typeof bins === "string") {
|
|
488
|
+
bins = { [pkg.name || "openclaw"]: bins };
|
|
489
|
+
}
|
|
490
|
+
const names = [...new Set(["hippoclaw", "openclaw", ...Object.keys(bins || {})])];
|
|
491
|
+
for (const name of names) {
|
|
492
|
+
const relativeEntry = bins && typeof bins[name] === "string" ? bins[name] : undefined;
|
|
493
|
+
if (!relativeEntry) {
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
496
|
+
const entryScriptPath = path.resolve(pkgRoot, relativeEntry);
|
|
497
|
+
if (!fs.existsSync(entryScriptPath)) {
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
const launcherPath = binDir ? path.join(binDir, name) : "";
|
|
501
|
+
if (!launcherPath || fs.existsSync(launcherPath)) {
|
|
502
|
+
process.stdout.write(`${nodePath}\n${launcherPath}\n${entryScriptPath}\n${pkgRoot}\n`);
|
|
503
|
+
process.exit(0);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
process.exit(1);
|
|
507
|
+
EOF
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
resolve_managed_gateway_install() {
|
|
511
|
+
local current_node npm_root prefix package_root
|
|
512
|
+
current_node="$(command -v node 2>/dev/null || true)"
|
|
513
|
+
|
|
514
|
+
if [[ -n "$current_node" ]]; then
|
|
515
|
+
npm_root="$(npm root -g 2>/dev/null || true)"
|
|
516
|
+
prefix="$(npm prefix -g 2>/dev/null || true)"
|
|
517
|
+
package_root="${npm_root}/openclaw"
|
|
518
|
+
if [[ -n "$npm_root" && -n "$prefix" && -d "$package_root" ]]; then
|
|
519
|
+
resolve_managed_gateway_install_from_root "$current_node" "$package_root" "${prefix}/bin" && return 0
|
|
520
|
+
fi
|
|
521
|
+
|
|
522
|
+
package_root="${NPM_GLOBAL_PREFIX}/lib/node_modules/openclaw"
|
|
523
|
+
if [[ -d "$package_root" ]]; then
|
|
524
|
+
resolve_managed_gateway_install_from_root "$current_node" "$package_root" "${NPM_GLOBAL_PREFIX}/bin" && return 0
|
|
525
|
+
fi
|
|
526
|
+
fi
|
|
527
|
+
|
|
528
|
+
local candidate_node candidate_dir install_dir
|
|
529
|
+
[[ -d "$NODE_BOOTSTRAP_ROOT" ]] || return 1
|
|
530
|
+
while IFS= read -r candidate_node; do
|
|
531
|
+
candidate_dir="${candidate_node%/node}"
|
|
532
|
+
install_dir="$(dirname "$candidate_dir")"
|
|
533
|
+
package_root="${install_dir}/lib/node_modules/openclaw"
|
|
534
|
+
if [[ -d "$package_root" ]]; then
|
|
535
|
+
resolve_managed_gateway_install_from_root "$candidate_node" "$package_root" "$candidate_dir" && return 0
|
|
536
|
+
fi
|
|
537
|
+
done < <(find "$NODE_BOOTSTRAP_ROOT" -maxdepth 4 -type f -path '*/bin/node' 2>/dev/null | sort -r)
|
|
538
|
+
return 1
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
write_managed_gateway_manifest() {
|
|
542
|
+
local node_path="$1"
|
|
543
|
+
local cli_path="$2"
|
|
544
|
+
local entry_script_path="$3"
|
|
545
|
+
local package_root="$4"
|
|
546
|
+
local wrapper_path="$5"
|
|
547
|
+
local openclaw_wrapper_path="${6:-}"
|
|
548
|
+
mkdir -p "$MANAGED_GATEWAY_STATE_DIR"
|
|
549
|
+
node - "$MANAGED_GATEWAY_MANIFEST_PATH" "$node_path" "$cli_path" "$entry_script_path" "$package_root" "$wrapper_path" "$MANAGED_GATEWAY_WRAPPER_DIR" "$openclaw_wrapper_path" <<'EOF'
|
|
550
|
+
const fs = require("fs");
|
|
551
|
+
const path = require("path");
|
|
552
|
+
const [manifestPath, nodePath, cliPath, entryScriptPath, packageRoot, wrapperPath, wrapperDir, openclawWrapperPath] = process.argv.slice(2);
|
|
553
|
+
const record = {
|
|
554
|
+
nodePath,
|
|
555
|
+
cliPath,
|
|
556
|
+
entryScriptPath,
|
|
557
|
+
packageRoot,
|
|
558
|
+
wrapperPath,
|
|
559
|
+
wrapperDir,
|
|
560
|
+
updatedAt: new Date().toISOString(),
|
|
561
|
+
};
|
|
562
|
+
if (openclawWrapperPath) {
|
|
563
|
+
record.openclawWrapperPath = openclawWrapperPath;
|
|
564
|
+
}
|
|
565
|
+
fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
|
|
566
|
+
fs.writeFileSync(manifestPath, JSON.stringify(record, null, 2));
|
|
567
|
+
EOF
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
resolve_gateway_cli_bin_from_manifest() {
|
|
571
|
+
[[ -f "$MANAGED_GATEWAY_MANIFEST_PATH" ]] || return 1
|
|
572
|
+
node - "$MANAGED_GATEWAY_MANIFEST_PATH" <<'EOF'
|
|
573
|
+
const fs = require("fs");
|
|
574
|
+
const manifestPath = process.argv[2];
|
|
575
|
+
try {
|
|
576
|
+
const record = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
577
|
+
for (const candidate of [record.wrapperPath, record.cliPath]) {
|
|
578
|
+
if (candidate && fs.existsSync(candidate)) {
|
|
579
|
+
process.stdout.write(candidate);
|
|
580
|
+
process.exit(0);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
} catch {
|
|
584
|
+
// ignore
|
|
585
|
+
}
|
|
586
|
+
process.exit(1);
|
|
587
|
+
EOF
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
resolve_managed_gateway_package_root_from_manifest() {
|
|
591
|
+
[[ -f "$MANAGED_GATEWAY_MANIFEST_PATH" ]] || return 1
|
|
592
|
+
node - "$MANAGED_GATEWAY_MANIFEST_PATH" <<'EOF'
|
|
593
|
+
const fs = require("fs");
|
|
594
|
+
const manifestPath = process.argv[2];
|
|
595
|
+
try {
|
|
596
|
+
const record = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
597
|
+
if (record.packageRoot && fs.existsSync(record.packageRoot)) {
|
|
598
|
+
process.stdout.write(record.packageRoot);
|
|
599
|
+
process.exit(0);
|
|
600
|
+
}
|
|
601
|
+
} catch {
|
|
602
|
+
// ignore
|
|
603
|
+
}
|
|
604
|
+
process.exit(1);
|
|
605
|
+
EOF
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
ensure_gateway_wrappers() {
|
|
609
|
+
local resolved_output node_path cli_path entry_script_path package_root wrapper_path openclaw_wrapper_path=""
|
|
610
|
+
resolved_output="$(resolve_managed_gateway_install)" || {
|
|
611
|
+
log_warn "Could not resolve managed gateway install location after setup"
|
|
612
|
+
return 1
|
|
613
|
+
}
|
|
614
|
+
node_path="$(printf '%s\n' "$resolved_output" | sed -n '1p')"
|
|
615
|
+
cli_path="$(printf '%s\n' "$resolved_output" | sed -n '2p')"
|
|
616
|
+
entry_script_path="$(printf '%s\n' "$resolved_output" | sed -n '3p')"
|
|
617
|
+
package_root="$(printf '%s\n' "$resolved_output" | sed -n '4p')"
|
|
618
|
+
[[ -n "$node_path" && -n "$entry_script_path" && -n "$package_root" ]] || {
|
|
619
|
+
log_warn "Managed gateway install metadata was incomplete"
|
|
620
|
+
return 1
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
wrapper_path="$(resolve_gateway_wrapper_path)"
|
|
624
|
+
write_gateway_wrapper "$node_path" "$entry_script_path" "$wrapper_path"
|
|
625
|
+
|
|
626
|
+
local existing_openclaw_wrapper
|
|
627
|
+
existing_openclaw_wrapper="$(resolve_openclaw_wrapper_path)"
|
|
628
|
+
if wrapper_is_managed_by_agent_anywhere "$existing_openclaw_wrapper"; then
|
|
629
|
+
write_gateway_wrapper "$node_path" "$entry_script_path" "$existing_openclaw_wrapper"
|
|
630
|
+
openclaw_wrapper_path="$existing_openclaw_wrapper"
|
|
631
|
+
fi
|
|
632
|
+
|
|
633
|
+
write_managed_gateway_manifest "$node_path" "$cli_path" "$entry_script_path" "$package_root" "$wrapper_path" "$openclaw_wrapper_path"
|
|
634
|
+
|
|
635
|
+
if $MODIFY_PATH; then
|
|
636
|
+
persist_shell_path_setup
|
|
637
|
+
fi
|
|
638
|
+
|
|
639
|
+
log_info "Stable CLI wrapper ready: $wrapper_path"
|
|
640
|
+
if ! path_contains_entry "$MANAGED_GATEWAY_WRAPPER_DIR"; then
|
|
641
|
+
if $MODIFY_PATH; then
|
|
642
|
+
log_info "Open a new terminal after setup so $MANAGED_GATEWAY_WRAPPER_DIR is available on PATH."
|
|
643
|
+
else
|
|
644
|
+
log_info "Add $MANAGED_GATEWAY_WRAPPER_DIR to PATH if you want to run hippoclaw directly from new terminals."
|
|
645
|
+
fi
|
|
646
|
+
fi
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
remove_managed_gateway_wrapper_state() {
|
|
650
|
+
local wrapper_path openclaw_wrapper_path
|
|
651
|
+
wrapper_path="$(resolve_gateway_wrapper_path)"
|
|
652
|
+
openclaw_wrapper_path="$(resolve_openclaw_wrapper_path)"
|
|
653
|
+
if wrapper_is_managed_by_agent_anywhere "$wrapper_path"; then
|
|
654
|
+
rm -f "$wrapper_path"
|
|
655
|
+
fi
|
|
656
|
+
if wrapper_is_managed_by_agent_anywhere "$openclaw_wrapper_path"; then
|
|
657
|
+
rm -f "$openclaw_wrapper_path"
|
|
658
|
+
fi
|
|
659
|
+
rm -f "$MANAGED_GATEWAY_MANIFEST_PATH"
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
install_node_runtime() {
|
|
663
|
+
local uname_s uname_m node_os node_arch archive_ext version dist_name url
|
|
664
|
+
uname_s="$(uname -s)"
|
|
665
|
+
uname_m="$(uname -m)"
|
|
666
|
+
|
|
667
|
+
case "$uname_s" in
|
|
668
|
+
Darwin)
|
|
669
|
+
node_os="darwin"
|
|
670
|
+
archive_ext="tar.gz"
|
|
671
|
+
;;
|
|
672
|
+
Linux)
|
|
673
|
+
node_os="linux"
|
|
674
|
+
archive_ext="tar.xz"
|
|
675
|
+
;;
|
|
676
|
+
*)
|
|
677
|
+
log_error "Automatic Node bootstrap unsupported on OS: $uname_s"
|
|
678
|
+
return 1
|
|
679
|
+
;;
|
|
680
|
+
esac
|
|
681
|
+
|
|
682
|
+
case "$uname_m" in
|
|
683
|
+
x86_64|amd64) node_arch="x64" ;;
|
|
684
|
+
arm64|aarch64) node_arch="arm64" ;;
|
|
685
|
+
*)
|
|
686
|
+
log_error "Automatic Node bootstrap unsupported on architecture: $uname_m"
|
|
687
|
+
return 1
|
|
688
|
+
;;
|
|
689
|
+
esac
|
|
690
|
+
|
|
691
|
+
version="${NODE_BOOTSTRAP_VERSION#v}"
|
|
692
|
+
dist_name="node-v${version}-${node_os}-${node_arch}"
|
|
693
|
+
url="https://nodejs.org/dist/v${version}/${dist_name}.${archive_ext}"
|
|
694
|
+
local install_dir="${NODE_BOOTSTRAP_ROOT}/${dist_name}"
|
|
695
|
+
local bin_dir="${install_dir}/bin"
|
|
696
|
+
|
|
697
|
+
if [[ -x "${bin_dir}/node" && -x "${bin_dir}/npm" ]]; then
|
|
698
|
+
add_path_entry "$bin_dir"
|
|
699
|
+
USING_BOOTSTRAP_NODE=true
|
|
700
|
+
return 0
|
|
701
|
+
fi
|
|
702
|
+
|
|
703
|
+
log_info "Installing Node.js v${version} (${node_os}-${node_arch}) to ${NODE_BOOTSTRAP_ROOT}"
|
|
704
|
+
mkdir -p "$NODE_BOOTSTRAP_ROOT"
|
|
705
|
+
|
|
706
|
+
local work_dir archive_path
|
|
707
|
+
work_dir="$(mktemp -d "${TMPDIR:-/tmp}/agent-anywhere-node.XXXXXX")"
|
|
708
|
+
archive_path="${work_dir}/${dist_name}.${archive_ext}"
|
|
709
|
+
|
|
710
|
+
if ! curl -fsSL "$url" -o "$archive_path"; then
|
|
711
|
+
rm -rf "$work_dir"
|
|
712
|
+
log_error "Failed to download Node.js runtime from $url"
|
|
713
|
+
return 1
|
|
714
|
+
fi
|
|
715
|
+
|
|
716
|
+
if [[ "$archive_ext" == "tar.xz" ]]; then
|
|
717
|
+
tar -xJf "$archive_path" -C "$work_dir" || {
|
|
718
|
+
rm -rf "$work_dir"
|
|
719
|
+
log_error "Failed to extract Node.js archive (.tar.xz)"
|
|
720
|
+
return 1
|
|
721
|
+
}
|
|
722
|
+
else
|
|
723
|
+
tar -xzf "$archive_path" -C "$work_dir" || {
|
|
724
|
+
rm -rf "$work_dir"
|
|
725
|
+
log_error "Failed to extract Node.js archive (.tar.gz)"
|
|
726
|
+
return 1
|
|
727
|
+
}
|
|
728
|
+
fi
|
|
729
|
+
|
|
730
|
+
if [[ ! -d "${work_dir}/${dist_name}" ]]; then
|
|
731
|
+
rm -rf "$work_dir"
|
|
732
|
+
log_error "Downloaded Node.js archive did not contain ${dist_name}"
|
|
733
|
+
return 1
|
|
734
|
+
fi
|
|
735
|
+
|
|
736
|
+
rm -rf "$install_dir"
|
|
737
|
+
mv "${work_dir}/${dist_name}" "$install_dir"
|
|
738
|
+
rm -rf "$work_dir"
|
|
739
|
+
|
|
740
|
+
add_path_entry "$bin_dir"
|
|
741
|
+
USING_BOOTSTRAP_NODE=true
|
|
742
|
+
return 0
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
ensure_node_npm() {
|
|
746
|
+
if node_is_compatible && command -v npm &>/dev/null; then
|
|
747
|
+
configure_npm_global_context
|
|
748
|
+
return 0
|
|
749
|
+
fi
|
|
750
|
+
|
|
751
|
+
activate_bootstrap_node_if_available || true
|
|
752
|
+
if node_is_compatible && command -v npm &>/dev/null; then
|
|
753
|
+
configure_npm_global_context
|
|
754
|
+
return 0
|
|
755
|
+
fi
|
|
756
|
+
|
|
757
|
+
install_node_runtime || return 1
|
|
758
|
+
if node_is_compatible && command -v npm &>/dev/null; then
|
|
759
|
+
configure_npm_global_context
|
|
760
|
+
return 0
|
|
761
|
+
fi
|
|
762
|
+
|
|
763
|
+
log_error "Node.js bootstrap finished but node/npm are still unavailable"
|
|
764
|
+
return 1
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
# Git / GitHub-style sources need a local UI build (published tarballs ship dist/).
|
|
768
|
+
needs_source_build() {
|
|
769
|
+
if [[ -z "$INSTALL_SOURCE" ]]; then
|
|
770
|
+
return 1
|
|
771
|
+
fi
|
|
772
|
+
local s="$INSTALL_SOURCE"
|
|
773
|
+
if [[ "$s" == /* || "$s" == ./* ]]; then
|
|
774
|
+
return 0
|
|
775
|
+
fi
|
|
776
|
+
if [[ "$s" == github:* || "$s" == git+http:* || "$s" == git+https:* ]]; then
|
|
777
|
+
return 0
|
|
778
|
+
fi
|
|
779
|
+
if [[ "$s" == *"#"* ]]; then
|
|
780
|
+
return 0
|
|
781
|
+
fi
|
|
782
|
+
# npm GitHub shorthand: owner/repo (not @scope/pkg)
|
|
783
|
+
if [[ "$s" =~ ^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$ ]]; then
|
|
784
|
+
return 0
|
|
785
|
+
fi
|
|
786
|
+
return 1
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
needs_pnpm() {
|
|
790
|
+
needs_source_build
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
# Remote GitHub / git URL: npm install -g github:... can leave a dangling symlink; we clone, npm pack,
|
|
794
|
+
# and npm install -g the .tgz for a real global tree. Git checkouts do not include compiled dist/ (gitignored);
|
|
795
|
+
# we must pnpm build + ui:build in the clone before npm pack so dist/entry.(m)js and dist/control-ui exist.
|
|
796
|
+
install_openclaw_from_remote_git_spec() {
|
|
797
|
+
local spec="$1"
|
|
798
|
+
local s="$spec" ref=""
|
|
799
|
+
if [[ "$s" == *"#"* ]]; then
|
|
800
|
+
ref="${s##*#}"
|
|
801
|
+
s="${s%#*}"
|
|
802
|
+
fi
|
|
803
|
+
|
|
804
|
+
local clone_url=""
|
|
805
|
+
if [[ "$s" == git+https:* || "$s" == git+http:* ]]; then
|
|
806
|
+
clone_url="${s#git+}"
|
|
807
|
+
elif [[ "$s" == github:* ]]; then
|
|
808
|
+
clone_url="https://github.com/${s#github:}.git"
|
|
809
|
+
elif [[ "$s" =~ ^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$ ]]; then
|
|
810
|
+
clone_url="https://github.com/${s}.git"
|
|
811
|
+
else
|
|
812
|
+
log_error "Unsupported git install source: $spec"
|
|
813
|
+
exit 1
|
|
814
|
+
fi
|
|
815
|
+
|
|
816
|
+
local work
|
|
817
|
+
work="$(mktemp -d "${TMPDIR:-/tmp}/openclaw-gateway-src.XXXXXX")"
|
|
818
|
+
|
|
819
|
+
log_info "Cloning $(basename "$clone_url" .git) (shallow) for npm pack install..."
|
|
820
|
+
if [[ -n "$ref" ]]; then
|
|
821
|
+
git clone --depth 1 -b "$ref" "$clone_url" "$work/src" || {
|
|
822
|
+
log_error "git clone failed (check ref and network)"
|
|
823
|
+
rm -rf "$work"
|
|
824
|
+
exit 1
|
|
825
|
+
}
|
|
826
|
+
else
|
|
827
|
+
git clone --depth 1 "$clone_url" "$work/src" || {
|
|
828
|
+
log_error "git clone failed"
|
|
829
|
+
rm -rf "$work"
|
|
830
|
+
exit 1
|
|
831
|
+
}
|
|
832
|
+
fi
|
|
833
|
+
|
|
834
|
+
build_openclaw_in_dir "$work/src" || {
|
|
835
|
+
log_error "OpenClaw build failed in clone (need pnpm, Node 22.14+, network for deps)"
|
|
836
|
+
rm -rf "$work"
|
|
837
|
+
exit 1
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
log_info "npm pack --ignore-scripts (no publish prepare hooks required)..."
|
|
841
|
+
(cd "$work/src" && npm pack --ignore-scripts) || {
|
|
842
|
+
log_error "npm pack failed"
|
|
843
|
+
rm -rf "$work"
|
|
844
|
+
exit 1
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
local tgz
|
|
848
|
+
tgz="$(ls -t "$work/src"/openclaw-*.tgz 2>/dev/null | head -1)"
|
|
849
|
+
if [[ -z "$tgz" || ! -f "$tgz" ]]; then
|
|
850
|
+
log_error "npm pack did not produce openclaw-*.tgz under clone"
|
|
851
|
+
rm -rf "$work"
|
|
852
|
+
exit 1
|
|
853
|
+
fi
|
|
854
|
+
|
|
855
|
+
log_info "npm install -g $(basename "$tgz") ..."
|
|
856
|
+
npm install -g "$tgz" || {
|
|
857
|
+
log_error "npm install -g tarball failed"
|
|
858
|
+
rm -rf "$work"
|
|
859
|
+
exit 1
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
REMOTE_GATEWAY_CLONE_SRC="$work/src"
|
|
863
|
+
REMOTE_GATEWAY_WORK_DIR="$work"
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
# ============================================================================
|
|
867
|
+
# Check prerequisites
|
|
868
|
+
# ============================================================================
|
|
869
|
+
check_prerequisites() {
|
|
870
|
+
log_step "Checking prerequisites..."
|
|
871
|
+
|
|
872
|
+
local all_good=true
|
|
873
|
+
|
|
874
|
+
if ! ensure_node_npm; then
|
|
875
|
+
log_warn "Could not automatically provision Node.js/npm"
|
|
876
|
+
all_good=false
|
|
877
|
+
fi
|
|
878
|
+
|
|
879
|
+
# Node.js >= 22.14
|
|
880
|
+
if node_is_compatible; then
|
|
881
|
+
log_success "Node.js $(node -v)"
|
|
882
|
+
elif command -v node &>/dev/null; then
|
|
883
|
+
log_warn "Node.js $(node -v) — version 22.14+ required"
|
|
884
|
+
all_good=false
|
|
885
|
+
else
|
|
886
|
+
log_warn "Node.js not found (version 22.14+ required)"
|
|
887
|
+
echo " Automatic bootstrap failed. Install manually: https://nodejs.org/"
|
|
888
|
+
all_good=false
|
|
889
|
+
fi
|
|
890
|
+
|
|
891
|
+
# npm
|
|
892
|
+
if command -v npm &>/dev/null; then
|
|
893
|
+
log_success "npm $(npm -v)"
|
|
894
|
+
else
|
|
895
|
+
log_warn "npm not found"
|
|
896
|
+
all_good=false
|
|
897
|
+
fi
|
|
898
|
+
|
|
899
|
+
# git (clone + npm pack path for remote GitHub/git install sources)
|
|
900
|
+
if needs_pnpm; then
|
|
901
|
+
local src="$INSTALL_SOURCE"
|
|
902
|
+
if [[ "$src" != /* && "$src" != ./* ]]; then
|
|
903
|
+
if command -v git &>/dev/null; then
|
|
904
|
+
log_success "git $(git --version | head -1)"
|
|
905
|
+
else
|
|
906
|
+
log_warn "git not found (required for GitHub / git URL gateway install sources)"
|
|
907
|
+
all_good=false
|
|
908
|
+
fi
|
|
909
|
+
fi
|
|
910
|
+
fi
|
|
911
|
+
|
|
912
|
+
# pnpm (needed for pnpm build + ui:build when installing from git/local source)
|
|
913
|
+
if needs_pnpm; then
|
|
914
|
+
if command -v pnpm &>/dev/null; then
|
|
915
|
+
log_success "pnpm $(pnpm -v)"
|
|
916
|
+
else
|
|
917
|
+
if ensure_pnpm; then
|
|
918
|
+
log_success "pnpm $(pnpm -v)"
|
|
919
|
+
else
|
|
920
|
+
log_warn "pnpm not found (needed to build OpenClaw from source)"
|
|
921
|
+
all_good=false
|
|
922
|
+
fi
|
|
923
|
+
fi
|
|
924
|
+
else
|
|
925
|
+
log_info "pnpm not required for published package install"
|
|
926
|
+
fi
|
|
927
|
+
|
|
928
|
+
$all_good
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
# ============================================================================
|
|
932
|
+
# Ensure pnpm is available when we need to build the UI
|
|
933
|
+
# ============================================================================
|
|
934
|
+
ensure_pnpm() {
|
|
935
|
+
if command -v pnpm &>/dev/null; then
|
|
936
|
+
log_success "pnpm $(pnpm -v)"
|
|
937
|
+
return 0
|
|
938
|
+
fi
|
|
939
|
+
|
|
940
|
+
log_warn "pnpm not found — attempting to install"
|
|
941
|
+
|
|
942
|
+
if command -v corepack &>/dev/null; then
|
|
943
|
+
log_info "Installing pnpm via corepack..."
|
|
944
|
+
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
|
945
|
+
if corepack prepare pnpm@latest --activate &>/dev/null; then
|
|
946
|
+
if command -v pnpm &>/dev/null; then
|
|
947
|
+
log_success "pnpm $(pnpm -v)"
|
|
948
|
+
return 0
|
|
949
|
+
fi
|
|
950
|
+
fi
|
|
951
|
+
fi
|
|
952
|
+
|
|
953
|
+
if command -v npm &>/dev/null; then
|
|
954
|
+
log_info "Installing pnpm via npm..."
|
|
955
|
+
if npm install -g pnpm; then
|
|
956
|
+
log_success "pnpm $(pnpm -v)"
|
|
957
|
+
return 0
|
|
958
|
+
fi
|
|
959
|
+
fi
|
|
960
|
+
|
|
961
|
+
log_warn "pnpm install failed — skipping web UI build"
|
|
962
|
+
return 1
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
# Full compile + control UI in a repo checkout (dist/ is not committed to git).
|
|
966
|
+
build_openclaw_in_dir() {
|
|
967
|
+
local dir="$1"
|
|
968
|
+
if [[ ! -d "$dir" ]]; then
|
|
969
|
+
log_error "build_openclaw_in_dir: not a directory: $dir"
|
|
970
|
+
return 1
|
|
971
|
+
fi
|
|
972
|
+
ensure_pnpm || {
|
|
973
|
+
log_error "pnpm is required to build OpenClaw from a git checkout"
|
|
974
|
+
return 1
|
|
975
|
+
}
|
|
976
|
+
log_info "pnpm install && pnpm build && pnpm ui:build in $(basename "$dir") (may take several minutes)..."
|
|
977
|
+
(
|
|
978
|
+
cd "$dir" || exit 1
|
|
979
|
+
if [[ ! -f pnpm-lock.yaml ]]; then
|
|
980
|
+
log_error "pnpm-lock.yaml missing — expected an OpenClaw repo checkout"
|
|
981
|
+
exit 1
|
|
982
|
+
fi
|
|
983
|
+
pnpm install || {
|
|
984
|
+
log_error "pnpm install failed"
|
|
985
|
+
exit 1
|
|
986
|
+
}
|
|
987
|
+
pnpm build || {
|
|
988
|
+
log_error "pnpm build failed"
|
|
989
|
+
exit 1
|
|
990
|
+
}
|
|
991
|
+
pnpm ui:build || {
|
|
992
|
+
log_error "pnpm ui:build failed"
|
|
993
|
+
exit 1
|
|
994
|
+
}
|
|
995
|
+
)
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
# ============================================================================
|
|
999
|
+
# Check installed components
|
|
1000
|
+
# ============================================================================
|
|
1001
|
+
check_installed() {
|
|
1002
|
+
log_step "Checking installed components..."
|
|
1003
|
+
|
|
1004
|
+
local all_ok=true
|
|
1005
|
+
|
|
1006
|
+
# Gateway CLI binary (prefer hippoclaw from fork, fallback to openclaw)
|
|
1007
|
+
local cli_bin=""
|
|
1008
|
+
cli_bin="$(resolve_gateway_cli_bin || true)"
|
|
1009
|
+
if [[ -n "$cli_bin" ]]; then
|
|
1010
|
+
local oc_version
|
|
1011
|
+
if oc_version="$("$cli_bin" --version 2>/dev/null | head -1)" && [[ -n "$oc_version" ]]; then
|
|
1012
|
+
log_success "Gateway CLI installed ($(basename "$cli_bin")): $oc_version"
|
|
1013
|
+
log_info "Gateway CLI path: $cli_bin"
|
|
1014
|
+
else
|
|
1015
|
+
log_warn "Gateway CLI found ($cli_bin) but command failed (stale/broken shim)"
|
|
1016
|
+
all_ok=false
|
|
1017
|
+
fi
|
|
1018
|
+
else
|
|
1019
|
+
# Check common install locations
|
|
1020
|
+
local found=false
|
|
1021
|
+
local dir name candidate
|
|
1022
|
+
for dir in \
|
|
1023
|
+
"$HOME/Library/pnpm" \
|
|
1024
|
+
"$HOME/.local/share/pnpm" \
|
|
1025
|
+
"$HOME/.npm-global/bin" \
|
|
1026
|
+
"/usr/local/bin" \
|
|
1027
|
+
"/usr/bin"; do
|
|
1028
|
+
for name in hippoclaw openclaw; do
|
|
1029
|
+
candidate="$dir/$name"
|
|
1030
|
+
if [[ -x "$candidate" ]]; then
|
|
1031
|
+
local oc_version
|
|
1032
|
+
oc_version=$("$candidate" --version 2>/dev/null | head -1 || echo "unknown")
|
|
1033
|
+
log_success "Gateway CLI installed at $candidate: $oc_version"
|
|
1034
|
+
found=true
|
|
1035
|
+
break 2
|
|
1036
|
+
fi
|
|
1037
|
+
done
|
|
1038
|
+
done
|
|
1039
|
+
if ! $found; then
|
|
1040
|
+
log_warn "Gateway CLI not installed (hippoclaw/openclaw)"
|
|
1041
|
+
all_ok=false
|
|
1042
|
+
fi
|
|
1043
|
+
fi
|
|
1044
|
+
|
|
1045
|
+
# CLI dist and Web UI under global npm package (npm root first; ~/.npm-global legacy fallback)
|
|
1046
|
+
local npm_root groot ui_dir
|
|
1047
|
+
groot="$(resolve_managed_gateway_package_root_from_manifest || true)"
|
|
1048
|
+
if [[ -z "$groot" || ! -d "$groot" ]]; then
|
|
1049
|
+
npm_root="$(npm root -g 2>/dev/null || true)"
|
|
1050
|
+
groot=""
|
|
1051
|
+
[[ -n "$npm_root" ]] && groot="$npm_root/openclaw"
|
|
1052
|
+
if [[ -z "$groot" || ! -d "$groot" ]]; then
|
|
1053
|
+
groot="$NPM_GLOBAL_PREFIX/lib/node_modules/openclaw"
|
|
1054
|
+
fi
|
|
1055
|
+
fi
|
|
1056
|
+
if [[ -n "$groot" && -d "$groot" ]]; then
|
|
1057
|
+
if [[ -f "$groot/dist/entry.mjs" || -f "$groot/dist/entry.js" ]]; then
|
|
1058
|
+
log_success "CLI dist present ($groot/dist/entry.*)"
|
|
1059
|
+
else
|
|
1060
|
+
log_warn "CLI dist missing (run setup with source build or reinstall from npm)"
|
|
1061
|
+
all_ok=false
|
|
1062
|
+
fi
|
|
1063
|
+
|
|
1064
|
+
ui_dir="$groot/dist/control-ui"
|
|
1065
|
+
if [[ -f "$ui_dir/index.html" ]]; then
|
|
1066
|
+
log_success "Web UI built ($ui_dir)"
|
|
1067
|
+
else
|
|
1068
|
+
log_warn "Web UI not built"
|
|
1069
|
+
all_ok=false
|
|
1070
|
+
fi
|
|
1071
|
+
else
|
|
1072
|
+
if [[ -n "$cli_bin" ]]; then
|
|
1073
|
+
log_warn "Global npm openclaw package not found (CLI appears external/non-npm)"
|
|
1074
|
+
else
|
|
1075
|
+
log_warn "Global npm openclaw package not found"
|
|
1076
|
+
fi
|
|
1077
|
+
all_ok=false
|
|
1078
|
+
fi
|
|
1079
|
+
|
|
1080
|
+
# Gateway running? Informational only; install succeeds even when stopped.
|
|
1081
|
+
if nc -z 127.0.0.1 "$GATEWAY_PORT" 2>/dev/null; then
|
|
1082
|
+
log_success "Gateway running on 127.0.0.1:$GATEWAY_PORT"
|
|
1083
|
+
else
|
|
1084
|
+
log_info "Gateway not running on port $GATEWAY_PORT (this is OK; start it from Agent Anywhere when needed)"
|
|
1085
|
+
fi
|
|
1086
|
+
|
|
1087
|
+
# Config file
|
|
1088
|
+
local config_path="$HOME/.openclaw/openclaw.json"
|
|
1089
|
+
if [[ -f "$config_path" ]]; then
|
|
1090
|
+
log_success "Config file present ($config_path)"
|
|
1091
|
+
else
|
|
1092
|
+
log_warn "Config file not found ($config_path)"
|
|
1093
|
+
all_ok=false
|
|
1094
|
+
fi
|
|
1095
|
+
|
|
1096
|
+
echo ""
|
|
1097
|
+
if $all_ok; then
|
|
1098
|
+
echo -e "${GREEN}${BOLD}Agent Anywhere is fully installed!${NC}"
|
|
1099
|
+
return 0
|
|
1100
|
+
else
|
|
1101
|
+
echo -e "${YELLOW}${BOLD}Agent Anywhere setup is incomplete.${NC}"
|
|
1102
|
+
return 1
|
|
1103
|
+
fi
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
check_uninstalled() {
|
|
1107
|
+
log_step "Checking uninstall state..."
|
|
1108
|
+
|
|
1109
|
+
local all_ok=true
|
|
1110
|
+
local cli_bin=""
|
|
1111
|
+
|
|
1112
|
+
cli_bin="$(resolve_gateway_cli_bin_on_path 2>/dev/null || true)"
|
|
1113
|
+
if [[ -n "$cli_bin" ]]; then
|
|
1114
|
+
log_warn "Gateway CLI still resolves to $cli_bin (likely external/non-npm install)"
|
|
1115
|
+
else
|
|
1116
|
+
log_success "Gateway CLI not installed (hippoclaw/openclaw)"
|
|
1117
|
+
fi
|
|
1118
|
+
|
|
1119
|
+
local groot=""
|
|
1120
|
+
groot="$(resolve_managed_gateway_package_root_from_manifest || true)"
|
|
1121
|
+
if [[ -z "$groot" || ! -d "$groot" ]]; then
|
|
1122
|
+
groot="$NPM_GLOBAL_PREFIX/lib/node_modules/openclaw"
|
|
1123
|
+
fi
|
|
1124
|
+
if [[ -n "$groot" && -d "$groot" ]]; then
|
|
1125
|
+
log_warn "Managed npm openclaw package still present ($groot)"
|
|
1126
|
+
all_ok=false
|
|
1127
|
+
else
|
|
1128
|
+
log_success "Managed npm openclaw package not found"
|
|
1129
|
+
fi
|
|
1130
|
+
|
|
1131
|
+
if nc -z 127.0.0.1 "$GATEWAY_PORT" 2>/dev/null; then
|
|
1132
|
+
log_warn "Gateway still running on 127.0.0.1:$GATEWAY_PORT"
|
|
1133
|
+
all_ok=false
|
|
1134
|
+
else
|
|
1135
|
+
log_success "Gateway not running on port $GATEWAY_PORT"
|
|
1136
|
+
fi
|
|
1137
|
+
|
|
1138
|
+
local config_path="$HOME/.openclaw/openclaw.json"
|
|
1139
|
+
if [[ -f "$config_path" ]]; then
|
|
1140
|
+
log_success "Config file preserved ($config_path)"
|
|
1141
|
+
else
|
|
1142
|
+
log_info "Config file already absent ($config_path)"
|
|
1143
|
+
fi
|
|
1144
|
+
|
|
1145
|
+
echo ""
|
|
1146
|
+
if $all_ok; then
|
|
1147
|
+
echo -e "${GREEN}${BOLD}Agent Anywhere uninstall complete.${NC}"
|
|
1148
|
+
return 0
|
|
1149
|
+
else
|
|
1150
|
+
echo -e "${YELLOW}${BOLD}Agent Anywhere uninstall needs attention.${NC}"
|
|
1151
|
+
return 1
|
|
1152
|
+
fi
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
# ============================================================================
|
|
1156
|
+
# Install gateway
|
|
1157
|
+
# ============================================================================
|
|
1158
|
+
install_gateway() {
|
|
1159
|
+
if [[ -z "$INSTALL_SOURCE" ]]; then
|
|
1160
|
+
log_error "No install source specified. Use --source <source>"
|
|
1161
|
+
exit 1
|
|
1162
|
+
fi
|
|
1163
|
+
|
|
1164
|
+
REMOTE_GATEWAY_CLONE_SRC=""
|
|
1165
|
+
REMOTE_GATEWAY_WORK_DIR=""
|
|
1166
|
+
|
|
1167
|
+
log_step "Installing OpenClaw Gateway..."
|
|
1168
|
+
log_info "Source: $INSTALL_SOURCE"
|
|
1169
|
+
|
|
1170
|
+
local _npm_root
|
|
1171
|
+
_npm_root="$(npm root -g 2>/dev/null || true)"
|
|
1172
|
+
if [[ -n "$_npm_root" && -e "$_npm_root/openclaw" ]]; then
|
|
1173
|
+
log_info "Removing existing global openclaw tree (avoids partial install / tar errors)..."
|
|
1174
|
+
rm -rf "$_npm_root/openclaw"
|
|
1175
|
+
fi
|
|
1176
|
+
|
|
1177
|
+
# Local directory: npm links to that path (stable). Remote github:/git+: use clone+pack+tgz
|
|
1178
|
+
# so global node_modules/openclaw is a real tree (npm git+ignore-scripts leaves a dangling symlink).
|
|
1179
|
+
if needs_source_build; then
|
|
1180
|
+
if [[ "$INSTALL_SOURCE" == /* || "$INSTALL_SOURCE" == ./* ]]; then
|
|
1181
|
+
local abs_src
|
|
1182
|
+
abs_src="$(cd "$INSTALL_SOURCE" && pwd)"
|
|
1183
|
+
build_openclaw_in_dir "$abs_src" || exit 1
|
|
1184
|
+
npm install -g "$abs_src"
|
|
1185
|
+
else
|
|
1186
|
+
install_openclaw_from_remote_git_spec "$INSTALL_SOURCE"
|
|
1187
|
+
fi
|
|
1188
|
+
else
|
|
1189
|
+
npm install -g "$INSTALL_SOURCE"
|
|
1190
|
+
fi
|
|
1191
|
+
log_success "npm install complete"
|
|
1192
|
+
ensure_gateway_wrappers || true
|
|
1193
|
+
|
|
1194
|
+
if needs_source_build; then
|
|
1195
|
+
# dist/ was built before pack (remote) or before npm install -g (local); remove temp clone only.
|
|
1196
|
+
if [[ -n "${REMOTE_GATEWAY_WORK_DIR:-}" ]]; then
|
|
1197
|
+
log_info "Removing temporary clone directory..."
|
|
1198
|
+
rm -rf "$REMOTE_GATEWAY_WORK_DIR"
|
|
1199
|
+
REMOTE_GATEWAY_WORK_DIR=""
|
|
1200
|
+
REMOTE_GATEWAY_CLONE_SRC=""
|
|
1201
|
+
fi
|
|
1202
|
+
else
|
|
1203
|
+
log_info "Published package — web UI should be pre-built"
|
|
1204
|
+
fi
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
# ============================================================================
|
|
1208
|
+
# Stop gateway listeners (graceful CLI stop, then best-effort process/port cleanup)
|
|
1209
|
+
# ============================================================================
|
|
1210
|
+
resolve_gateway_cli_bin_on_path() {
|
|
1211
|
+
if command -v hippoclaw &>/dev/null; then
|
|
1212
|
+
command -v hippoclaw
|
|
1213
|
+
return 0
|
|
1214
|
+
fi
|
|
1215
|
+
if command -v openclaw &>/dev/null; then
|
|
1216
|
+
command -v openclaw
|
|
1217
|
+
return 0
|
|
1218
|
+
fi
|
|
1219
|
+
return 1
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
resolve_gateway_cli_bin() {
|
|
1223
|
+
if resolve_gateway_cli_bin_from_manifest >/dev/null 2>&1; then
|
|
1224
|
+
resolve_gateway_cli_bin_from_manifest
|
|
1225
|
+
return 0
|
|
1226
|
+
fi
|
|
1227
|
+
if resolve_gateway_cli_bin_on_path >/dev/null 2>&1; then
|
|
1228
|
+
resolve_gateway_cli_bin_on_path
|
|
1229
|
+
return 0
|
|
1230
|
+
fi
|
|
1231
|
+
local candidate
|
|
1232
|
+
local dir name
|
|
1233
|
+
local current_prefix
|
|
1234
|
+
current_prefix="$(npm prefix -g 2>/dev/null || true)"
|
|
1235
|
+
for dir in \
|
|
1236
|
+
"$MANAGED_GATEWAY_WRAPPER_DIR" \
|
|
1237
|
+
"${current_prefix}/bin" \
|
|
1238
|
+
"$HOME/Library/pnpm" \
|
|
1239
|
+
"$HOME/.local/share/pnpm" \
|
|
1240
|
+
"$HOME/.npm-global/bin" \
|
|
1241
|
+
"/usr/local/bin" \
|
|
1242
|
+
"/usr/bin"; do
|
|
1243
|
+
for name in hippoclaw openclaw; do
|
|
1244
|
+
candidate="$dir/$name"
|
|
1245
|
+
if [[ -x "$candidate" ]]; then
|
|
1246
|
+
printf '%s\n' "$candidate"
|
|
1247
|
+
return 0
|
|
1248
|
+
fi
|
|
1249
|
+
done
|
|
1250
|
+
done
|
|
1251
|
+
if [[ -d "$NODE_BOOTSTRAP_ROOT" ]]; then
|
|
1252
|
+
while IFS= read -r dir; do
|
|
1253
|
+
for name in hippoclaw openclaw; do
|
|
1254
|
+
candidate="$dir/$name"
|
|
1255
|
+
if [[ -x "$candidate" ]]; then
|
|
1256
|
+
printf '%s\n' "$candidate"
|
|
1257
|
+
return 0
|
|
1258
|
+
fi
|
|
1259
|
+
done
|
|
1260
|
+
done < <(
|
|
1261
|
+
find "$NODE_BOOTSTRAP_ROOT" -maxdepth 4 -type f -path '*/bin/node' -print 2>/dev/null \
|
|
1262
|
+
| xargs -I{} dirname "{}" 2>/dev/null \
|
|
1263
|
+
| sort -u
|
|
1264
|
+
)
|
|
1265
|
+
fi
|
|
1266
|
+
return 1
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
remove_managed_openclaw_artifacts() {
|
|
1270
|
+
local dir install_dir pkg_root
|
|
1271
|
+
|
|
1272
|
+
pkg_root="$NPM_GLOBAL_PREFIX/lib/node_modules/openclaw"
|
|
1273
|
+
if [[ -d "$pkg_root" ]]; then
|
|
1274
|
+
log_info "Removing managed openclaw package from $pkg_root"
|
|
1275
|
+
rm -rf "$pkg_root"
|
|
1276
|
+
fi
|
|
1277
|
+
rm -f "$NPM_GLOBAL_PREFIX/bin/openclaw" "$NPM_GLOBAL_PREFIX/bin/hippoclaw" 2>/dev/null || true
|
|
1278
|
+
|
|
1279
|
+
[[ -d "$NODE_BOOTSTRAP_ROOT" ]] || return 0
|
|
1280
|
+
while IFS= read -r dir; do
|
|
1281
|
+
install_dir="$(dirname "$dir")"
|
|
1282
|
+
pkg_root="$install_dir/lib/node_modules/openclaw"
|
|
1283
|
+
if [[ -d "$pkg_root" ]]; then
|
|
1284
|
+
log_info "Removing managed openclaw package from $pkg_root"
|
|
1285
|
+
rm -rf "$pkg_root"
|
|
1286
|
+
fi
|
|
1287
|
+
rm -f "$dir/openclaw" "$dir/hippoclaw" 2>/dev/null || true
|
|
1288
|
+
done < <(
|
|
1289
|
+
find "$NODE_BOOTSTRAP_ROOT" -maxdepth 4 -type f -path '*/bin/node' -print 2>/dev/null \
|
|
1290
|
+
| xargs -I{} dirname "{}" 2>/dev/null \
|
|
1291
|
+
| sort -u
|
|
1292
|
+
)
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
# Remove the openclaw package wherever the CLI on PATH actually resolves to, including per-version
|
|
1296
|
+
# Node global trees (e.g. nvm) that the managed-prefix cleanup above does not cover. Equivalent to
|
|
1297
|
+
# `npm uninstall -g openclaw` for that prefix (remove the package tree + its bin shims), but
|
|
1298
|
+
# reliable regardless of which Node owns the install. Bounded loop in case several Node versions
|
|
1299
|
+
# each have a copy.
|
|
1300
|
+
remove_resolved_cli_openclaw_install() {
|
|
1301
|
+
local i cli_bin node_bin_dir prefix pkg_root removed_any=false
|
|
1302
|
+
for ((i = 0; i < 8; i++)); do
|
|
1303
|
+
hash -r 2>/dev/null || true
|
|
1304
|
+
cli_bin="$(resolve_gateway_cli_bin_on_path 2>/dev/null || true)"
|
|
1305
|
+
[[ -n "$cli_bin" ]] || break
|
|
1306
|
+
node_bin_dir="$(cd "$(dirname "$cli_bin")" 2>/dev/null && pwd)" || break
|
|
1307
|
+
# npm global layout: <prefix>/bin/<cli> and <prefix>/lib/node_modules/openclaw.
|
|
1308
|
+
prefix="$(dirname "$node_bin_dir")"
|
|
1309
|
+
pkg_root="$prefix/lib/node_modules/openclaw"
|
|
1310
|
+
if [[ -d "$pkg_root" ]]; then
|
|
1311
|
+
log_info "Removing openclaw package tree resolved via CLI on PATH: $pkg_root"
|
|
1312
|
+
rm -rf "$pkg_root" 2>/dev/null || true
|
|
1313
|
+
removed_any=true
|
|
1314
|
+
fi
|
|
1315
|
+
rm -f "$node_bin_dir/openclaw" "$node_bin_dir/hippoclaw" 2>/dev/null || true
|
|
1316
|
+
# Bail if the same path still resolves (could not delete, e.g. permissions) to avoid looping.
|
|
1317
|
+
hash -r 2>/dev/null || true
|
|
1318
|
+
if [[ "$(resolve_gateway_cli_bin_on_path 2>/dev/null || true)" == "$cli_bin" ]]; then
|
|
1319
|
+
break
|
|
1320
|
+
fi
|
|
1321
|
+
done
|
|
1322
|
+
$removed_any && log_success "Removed openclaw install(s) the CLI resolved to outside the managed prefix"
|
|
1323
|
+
return 0
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
# After npm removes the CLI, clear any leftover listener (e.g. detached node). Service teardown is
|
|
1327
|
+
# openclaw uninstall --service; we do not duplicate launchd/systemd/pkill here.
|
|
1328
|
+
free_local_gateway_ports_if_busy() {
|
|
1329
|
+
log_step "Clearing local gateway listener(s) if still bound..."
|
|
1330
|
+
rm -f "$HOME/.openclaw/gateway.pid" 2>/dev/null || true
|
|
1331
|
+
local sweep_ports=("$GATEWAY_PORT")
|
|
1332
|
+
[[ "$GATEWAY_PORT" != "18789" ]] && sweep_ports+=(18789)
|
|
1333
|
+
local sp pids
|
|
1334
|
+
for sp in "${sweep_ports[@]}"; do
|
|
1335
|
+
nc -z 127.0.0.1 "$sp" 2>/dev/null || continue
|
|
1336
|
+
command -v lsof &>/dev/null || {
|
|
1337
|
+
log_warn "Port $sp in use but lsof not available — stop the process manually"
|
|
1338
|
+
continue
|
|
1339
|
+
}
|
|
1340
|
+
log_info "Port $sp in use — stopping listener PID(s)..."
|
|
1341
|
+
pids=$(lsof -nP -iTCP:"$sp" -sTCP:LISTEN -t 2>/dev/null | tr '\n' ' ' || true)
|
|
1342
|
+
if [[ -n "${pids// }" ]]; then
|
|
1343
|
+
# shellcheck disable=SC2086
|
|
1344
|
+
kill $pids 2>/dev/null || true
|
|
1345
|
+
sleep 1
|
|
1346
|
+
pids=$(lsof -nP -iTCP:"$sp" -sTCP:LISTEN -t 2>/dev/null | tr '\n' ' ' || true)
|
|
1347
|
+
if [[ -n "${pids// }" ]]; then
|
|
1348
|
+
# shellcheck disable=SC2086
|
|
1349
|
+
kill -9 $pids 2>/dev/null || true
|
|
1350
|
+
fi
|
|
1351
|
+
fi
|
|
1352
|
+
done
|
|
1353
|
+
local any_up=false
|
|
1354
|
+
for sp in "${sweep_ports[@]}"; do
|
|
1355
|
+
if nc -z 127.0.0.1 "$sp" 2>/dev/null; then
|
|
1356
|
+
any_up=true
|
|
1357
|
+
break
|
|
1358
|
+
fi
|
|
1359
|
+
done
|
|
1360
|
+
if $any_up; then
|
|
1361
|
+
log_warn "A process may still be listening on 127.0.0.1 (${sweep_ports[*]})"
|
|
1362
|
+
else
|
|
1363
|
+
log_success "Gateway port(s) free on 127.0.0.1 (${sweep_ports[*]})"
|
|
1364
|
+
fi
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
# Official teardown: openclaw uninstall --service (launchd/systemd/schtasks) before npm remove.
|
|
1368
|
+
# Docs: https://docs.openclaw.ai/cli/uninstall — does not remove ~/.openclaw unless --state.
|
|
1369
|
+
openclaw_cli_uninstall_service() {
|
|
1370
|
+
local oc_bin=""
|
|
1371
|
+
oc_bin=$(resolve_gateway_cli_bin) || true
|
|
1372
|
+
if [[ -z "$oc_bin" ]]; then
|
|
1373
|
+
return 0
|
|
1374
|
+
fi
|
|
1375
|
+
log_step "OpenClaw CLI: uninstall gateway service..."
|
|
1376
|
+
log_info "Running: $oc_bin uninstall --service --yes --non-interactive"
|
|
1377
|
+
if "$oc_bin" uninstall --service --yes --non-interactive; then
|
|
1378
|
+
log_success "openclaw uninstall --service completed"
|
|
1379
|
+
else
|
|
1380
|
+
log_info "openclaw uninstall --service failed or skipped (continuing)"
|
|
1381
|
+
fi
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
# ============================================================================
|
|
1385
|
+
# Uninstall gateway (OpenClaw service uninstall + npm global remove + port cleanup)
|
|
1386
|
+
# ============================================================================
|
|
1387
|
+
uninstall_gateway() {
|
|
1388
|
+
ensure_node_npm || true
|
|
1389
|
+
openclaw_cli_uninstall_service
|
|
1390
|
+
echo ""
|
|
1391
|
+
log_step "Uninstalling OpenClaw (global npm package)..."
|
|
1392
|
+
if ! command -v npm &>/dev/null; then
|
|
1393
|
+
log_error "npm not found"
|
|
1394
|
+
exit 1
|
|
1395
|
+
fi
|
|
1396
|
+
npm uninstall -g openclaw 2>/dev/null || true
|
|
1397
|
+
remove_managed_gateway_wrapper_state
|
|
1398
|
+
cleanup_shell_path_setup
|
|
1399
|
+
# Also remove the install wherever the CLI actually resolves (nvm/other Node global trees),
|
|
1400
|
+
# not just the active node + managed prefix that `npm uninstall -g` above covers.
|
|
1401
|
+
remove_resolved_cli_openclaw_install
|
|
1402
|
+
log_success "Ran: npm uninstall -g openclaw (global tree removed if present)"
|
|
1403
|
+
log_info "~/.openclaw was not removed (config, sessions, and credentials stay on disk)."
|
|
1404
|
+
local oc_after=""
|
|
1405
|
+
hash -r 2>/dev/null || true
|
|
1406
|
+
oc_after="$(resolve_gateway_cli_bin_on_path 2>/dev/null || true)"
|
|
1407
|
+
if [[ -n "$oc_after" ]]; then
|
|
1408
|
+
log_warn "CLI still resolves to $oc_after (could not be removed automatically; remove it manually)."
|
|
1409
|
+
fi
|
|
1410
|
+
echo ""
|
|
1411
|
+
free_local_gateway_ports_if_busy
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
# ============================================================================
|
|
1415
|
+
# Write starter config
|
|
1416
|
+
# ============================================================================
|
|
1417
|
+
write_config() {
|
|
1418
|
+
local config_path="$HOME/.openclaw/openclaw.json"
|
|
1419
|
+
|
|
1420
|
+
if [[ -f "$config_path" ]]; then
|
|
1421
|
+
log_info "Config already exists at $config_path — skipping"
|
|
1422
|
+
return
|
|
1423
|
+
fi
|
|
1424
|
+
|
|
1425
|
+
log_step "Writing starter config..."
|
|
1426
|
+
mkdir -p "$HOME/.openclaw"
|
|
1427
|
+
|
|
1428
|
+
# Generate a random auth token
|
|
1429
|
+
local random_token="ah-$(openssl rand -hex 24 2>/dev/null || head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \n')"
|
|
1430
|
+
|
|
1431
|
+
if [[ -n "$CONFIG_TEMPLATE" && -f "$CONFIG_TEMPLATE" ]]; then
|
|
1432
|
+
# Copy template and replace placeholder token
|
|
1433
|
+
sed "s/__GENERATED_TOKEN__/${random_token}/" "$CONFIG_TEMPLATE" > "$config_path"
|
|
1434
|
+
log_success "Config written from template: $config_path"
|
|
1435
|
+
else
|
|
1436
|
+
# Minimal inline config with generated token
|
|
1437
|
+
cat > "$config_path" <<CONF
|
|
1438
|
+
// OpenClaw Gateway Configuration (JSON5)
|
|
1439
|
+
// Docs: https://docs.openclaw.ai/configuration
|
|
1440
|
+
{
|
|
1441
|
+
"gateway": { "mode": "local", "auth": { "token": "${random_token}" } },
|
|
1442
|
+
"update": { "checkOnStart": false, "managedMode": true },
|
|
1443
|
+
"bindings": [],
|
|
1444
|
+
"channels": {},
|
|
1445
|
+
"plugins": { "entries": {} },
|
|
1446
|
+
"session": { "dmScope": "per-peer" },
|
|
1447
|
+
"agents": { "defaults": { "maxConcurrent": 4 } }
|
|
1448
|
+
}
|
|
1449
|
+
CONF
|
|
1450
|
+
log_success "Starter config written: $config_path"
|
|
1451
|
+
fi
|
|
1452
|
+
|
|
1453
|
+
# Restrict permissions — config contains auth token
|
|
1454
|
+
chmod 600 "$config_path" 2>/dev/null || true
|
|
1455
|
+
|
|
1456
|
+
echo ""
|
|
1457
|
+
echo -e "${CYAN}Next: Edit $config_path to add your channels (Telegram, WhatsApp, etc.)${NC}"
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
# ============================================================================
|
|
1461
|
+
# Main
|
|
1462
|
+
# ============================================================================
|
|
1463
|
+
|
|
1464
|
+
echo -e "${BOLD}${CYAN}"
|
|
1465
|
+
echo " ╔═══════════════════════════════════════╗"
|
|
1466
|
+
echo " ║ Agent Anywhere Setup ║"
|
|
1467
|
+
echo " ║ Reach your agents from anywhere ║"
|
|
1468
|
+
echo " ╚═══════════════════════════════════════╝"
|
|
1469
|
+
echo -e "${NC}"
|
|
1470
|
+
|
|
1471
|
+
if $CHECK_ONLY; then
|
|
1472
|
+
check_installed
|
|
1473
|
+
exit $?
|
|
1474
|
+
fi
|
|
1475
|
+
|
|
1476
|
+
if $REINSTALL; then
|
|
1477
|
+
if [[ -z "$INSTALL_SOURCE" ]]; then
|
|
1478
|
+
log_error "--reinstall requires --source <src> (or set INSTALL_SOURCE)"
|
|
1479
|
+
exit 1
|
|
1480
|
+
fi
|
|
1481
|
+
log_step "Reinstall: uninstall → verify → install"
|
|
1482
|
+
uninstall_gateway
|
|
1483
|
+
echo ""
|
|
1484
|
+
log_step "Post-uninstall verification (--check)..."
|
|
1485
|
+
check_uninstalled || true
|
|
1486
|
+
echo ""
|
|
1487
|
+
if ! check_prerequisites; then
|
|
1488
|
+
echo ""
|
|
1489
|
+
log_error "Prerequisites not met. Install the missing tools and try again."
|
|
1490
|
+
exit 1
|
|
1491
|
+
fi
|
|
1492
|
+
echo ""
|
|
1493
|
+
install_gateway
|
|
1494
|
+
write_config
|
|
1495
|
+
echo ""
|
|
1496
|
+
check_installed || true
|
|
1497
|
+
echo ""
|
|
1498
|
+
echo -e "${BOLD}Reinstall complete.${NC} Next steps:"
|
|
1499
|
+
echo -e " 1. Edit ${CYAN}~/.openclaw/openclaw.json${NC} to add your channels"
|
|
1500
|
+
echo -e " 2. Click ${CYAN}Agent Anywhere${NC} to start."
|
|
1501
|
+
echo ""
|
|
1502
|
+
exit 0
|
|
1503
|
+
fi
|
|
1504
|
+
|
|
1505
|
+
if $UNINSTALL; then
|
|
1506
|
+
uninstall_gateway
|
|
1507
|
+
echo ""
|
|
1508
|
+
check_uninstalled || true
|
|
1509
|
+
exit 0
|
|
1510
|
+
fi
|
|
1511
|
+
|
|
1512
|
+
# Prerequisites
|
|
1513
|
+
if ! check_prerequisites; then
|
|
1514
|
+
echo ""
|
|
1515
|
+
log_error "Prerequisites not met. Install the missing tools and try again."
|
|
1516
|
+
exit 1
|
|
1517
|
+
fi
|
|
1518
|
+
|
|
1519
|
+
# Install if not present
|
|
1520
|
+
if ! resolve_gateway_cli_bin &>/dev/null; then
|
|
1521
|
+
echo ""
|
|
1522
|
+
install_gateway
|
|
1523
|
+
fi
|
|
1524
|
+
|
|
1525
|
+
# Backfill stable wrappers/manifest for existing managed installs.
|
|
1526
|
+
if ! resolve_gateway_cli_bin_from_manifest >/dev/null 2>&1 && resolve_managed_gateway_install >/dev/null 2>&1; then
|
|
1527
|
+
ensure_gateway_wrappers || true
|
|
1528
|
+
fi
|
|
1529
|
+
|
|
1530
|
+
# Write config if missing
|
|
1531
|
+
write_config
|
|
1532
|
+
|
|
1533
|
+
# Final status
|
|
1534
|
+
echo ""
|
|
1535
|
+
check_installed || true
|
|
1536
|
+
|
|
1537
|
+
echo ""
|
|
1538
|
+
echo -e "${BOLD}Done!${NC} Next steps:"
|
|
1539
|
+
echo -e " 1. Edit ${CYAN}~/.openclaw/openclaw.json${NC} to add your channels"
|
|
1540
|
+
echo -e " 2. Click ${CYAN}Agent Anywhere${NC} to start."
|
|
1541
|
+
echo ""
|