@openlife/cli 1.7.3
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/INSTALL.md +266 -0
- package/LICENSE +21 -0
- package/README.md +142 -0
- package/bin/openlife.js +3 -0
- package/dist/admin_panel_server.js +66 -0
- package/dist/cli/AgentManager.js +109 -0
- package/dist/cli/AutonomousInstaller.js +134 -0
- package/dist/cli/DreamOrganizer.js +88 -0
- package/dist/cli/HostInstaller.js +426 -0
- package/dist/cli/InstallBanner.js +16 -0
- package/dist/cli/InstallFlow.js +256 -0
- package/dist/cli/InstallHeadless.js +47 -0
- package/dist/cli/InstallModules.js +148 -0
- package/dist/cli/InstallStateStore.js +75 -0
- package/dist/cli/InstallWizard.js +364 -0
- package/dist/cli/ProfileManager.js +163 -0
- package/dist/cli/SystemInstaller.js +89 -0
- package/dist/cli/WorldClassCommands.js +208 -0
- package/dist/design/DesignMdImporter.js +82 -0
- package/dist/design/DesignMdMode.js +93 -0
- package/dist/design/DesignMdRegistry.js +67 -0
- package/dist/index.js +2575 -0
- package/dist/memory/ConversationMemory.js +33 -0
- package/dist/memory/LocalMemoryProvider.js +86 -0
- package/dist/memory/Mem0Provider.js +16 -0
- package/dist/memory/MemoryNamespacePolicy.js +27 -0
- package/dist/memory/MemoryOrchestrator.js +65 -0
- package/dist/memory/MemoryPromotionFlow.js +32 -0
- package/dist/memory/MemoryProvider.js +2 -0
- package/dist/memory/MemoryProviderRegistry.js +27 -0
- package/dist/memory/MemoryRetentionPolicy.js +60 -0
- package/dist/memory/MempalaceProvider.js +72 -0
- package/dist/memory/OmniMemory.js +106 -0
- package/dist/memory/RedisAgentMemoryProvider.js +16 -0
- package/dist/memory/SessionManager.js +86 -0
- package/dist/memory/ZepGraphitiProvider.js +16 -0
- package/dist/orchestrator/AgentRegistry.js +56 -0
- package/dist/orchestrator/AgentScoring.js +82 -0
- package/dist/orchestrator/AgentTeam.js +22 -0
- package/dist/orchestrator/ArbitrationAgent.js +43 -0
- package/dist/orchestrator/ArbitrationScorecard.js +17 -0
- package/dist/orchestrator/AssetPromotionEngine.js +65 -0
- package/dist/orchestrator/AssetReuseRouter.js +63 -0
- package/dist/orchestrator/BenchmarkEngine.js +75 -0
- package/dist/orchestrator/Brain.js +298 -0
- package/dist/orchestrator/CadenceEngine.js +76 -0
- package/dist/orchestrator/CapabilityRouter.js +36 -0
- package/dist/orchestrator/CommandLanguage.js +27 -0
- package/dist/orchestrator/CommandRouter.js +70 -0
- package/dist/orchestrator/ConsequenceForecaster.js +286 -0
- package/dist/orchestrator/CronManager.js +286 -0
- package/dist/orchestrator/DynamicAgentBuilder.js +48 -0
- package/dist/orchestrator/DynamicAgentExecutor.js +15 -0
- package/dist/orchestrator/EnterpriseAgenticCore.js +276 -0
- package/dist/orchestrator/ExecutionBoard.js +86 -0
- package/dist/orchestrator/ExecutionIntent.js +13 -0
- package/dist/orchestrator/ExecutionModePolicy.js +48 -0
- package/dist/orchestrator/ExecutionRouter.js +9 -0
- package/dist/orchestrator/ExecutionState.js +20 -0
- package/dist/orchestrator/ExecutorHealth.js +86 -0
- package/dist/orchestrator/ExternalCatalogRegistry.js +83 -0
- package/dist/orchestrator/Gatekeeper.js +414 -0
- package/dist/orchestrator/Gateway.js +508 -0
- package/dist/orchestrator/GovernanceConsentStore.js +66 -0
- package/dist/orchestrator/GovernanceLayer.js +179 -0
- package/dist/orchestrator/GovernancePolicyStore.js +53 -0
- package/dist/orchestrator/GovernanceScopeLedger.js +134 -0
- package/dist/orchestrator/GovernanceScopePolicy.js +67 -0
- package/dist/orchestrator/IntentClassifier.js +45 -0
- package/dist/orchestrator/JobLifecycle.js +91 -0
- package/dist/orchestrator/LearningRouter.js +24 -0
- package/dist/orchestrator/MediaManager.js +92 -0
- package/dist/orchestrator/MemoryCuratorAgent.js +41 -0
- package/dist/orchestrator/MissionState.js +155 -0
- package/dist/orchestrator/ModelManager.js +84 -0
- package/dist/orchestrator/OperatingSystem.js +71 -0
- package/dist/orchestrator/OperationalMemoryStore.js +94 -0
- package/dist/orchestrator/OptimizationLoop.js +72 -0
- package/dist/orchestrator/OrchestrationLoop.js +905 -0
- package/dist/orchestrator/OrgStructure.js +88 -0
- package/dist/orchestrator/OutcomeSimulator.js +46 -0
- package/dist/orchestrator/ParallelOrchestrationLoop.js +36 -0
- package/dist/orchestrator/PerformanceScorecard.js +105 -0
- package/dist/orchestrator/PlannerAgent.js +46 -0
- package/dist/orchestrator/ProcessSandbox.js +129 -0
- package/dist/orchestrator/PromotionPipeline.js +74 -0
- package/dist/orchestrator/PromotionReviewGate.js +11 -0
- package/dist/orchestrator/QueueScheduler.js +260 -0
- package/dist/orchestrator/ReleaseGate.js +36 -0
- package/dist/orchestrator/ReleaseWorkflow.js +68 -0
- package/dist/orchestrator/RemotePublisher.js +139 -0
- package/dist/orchestrator/ReuseEngine.js +89 -0
- package/dist/orchestrator/ReviewerAgent.js +49 -0
- package/dist/orchestrator/RoleHandoff.js +65 -0
- package/dist/orchestrator/RuntimeHealthMonitor.js +143 -0
- package/dist/orchestrator/RuntimePolicy.js +105 -0
- package/dist/orchestrator/RuntimeProbe.js +97 -0
- package/dist/orchestrator/RuntimeRegistry.js +73 -0
- package/dist/orchestrator/SandboxPolicy.js +22 -0
- package/dist/orchestrator/SecurityDownloadGuard.js +169 -0
- package/dist/orchestrator/SecurityEventStore.js +58 -0
- package/dist/orchestrator/ServiceCompletionPolicy.js +36 -0
- package/dist/orchestrator/ServiceState.js +195 -0
- package/dist/orchestrator/SkillCreator.js +404 -0
- package/dist/orchestrator/SkillLearningLoop.js +57 -0
- package/dist/orchestrator/SkillManager.js +75 -0
- package/dist/orchestrator/SkillNetwork.js +29 -0
- package/dist/orchestrator/SkillRegistryV2.js +28 -0
- package/dist/orchestrator/SkillScoring.js +70 -0
- package/dist/orchestrator/SquadAutoCreator.js +64 -0
- package/dist/orchestrator/SquadCreator.js +727 -0
- package/dist/orchestrator/SquadRegistry.js +28 -0
- package/dist/orchestrator/SquadRouter.js +33 -0
- package/dist/orchestrator/SquadScoring.js +70 -0
- package/dist/orchestrator/SubagentLifecycle.js +90 -0
- package/dist/orchestrator/SynthesizerAgent.js +48 -0
- package/dist/orchestrator/SystemDoctor.js +224 -0
- package/dist/orchestrator/TaskExecutor.js +422 -0
- package/dist/orchestrator/TeammateBoard.js +61 -0
- package/dist/orchestrator/TestHarness.js +184 -0
- package/dist/orchestrator/VoiceManager.js +203 -0
- package/dist/orchestrator/VoiceRouter.js +89 -0
- package/dist/orchestrator/capability/CapabilityGenesisEngine.js +278 -0
- package/dist/orchestrator/capability/CapabilityPackParser.js +223 -0
- package/dist/orchestrator/capability/CapabilityPackSchema.js +62 -0
- package/dist/orchestrator/capability/CapabilityPackState.js +163 -0
- package/dist/orchestrator/providers/AgentProvider.js +2 -0
- package/dist/orchestrator/providers/CapabilityProvider.js +12 -0
- package/dist/orchestrator/providers/CloudAgentProvider.js +55 -0
- package/dist/orchestrator/providers/CloudSkillProvider.js +55 -0
- package/dist/orchestrator/providers/CloudSquadProvider.js +55 -0
- package/dist/orchestrator/providers/CompositeAgentProvider.js +16 -0
- package/dist/orchestrator/providers/CompositeCapabilityProvider.js +25 -0
- package/dist/orchestrator/providers/CompositeSkillProvider.js +16 -0
- package/dist/orchestrator/providers/CompositeSquadProvider.js +16 -0
- package/dist/orchestrator/providers/CompositeWorkflowProvider.js +46 -0
- package/dist/orchestrator/providers/FileAgentProvider.js +105 -0
- package/dist/orchestrator/providers/FileCapabilityProvider.js +106 -0
- package/dist/orchestrator/providers/FileSkillProvider.js +65 -0
- package/dist/orchestrator/providers/FileSquadProvider.js +69 -0
- package/dist/orchestrator/providers/FileWorkflowProvider.js +103 -0
- package/dist/orchestrator/providers/SkillProvider.js +2 -0
- package/dist/orchestrator/providers/SquadProvider.js +2 -0
- package/dist/orchestrator/toolset/ToolsetGuard.js +69 -0
- package/dist/orchestrator/toolset/ToolsetRegistry.js +65 -0
- package/dist/orchestrator/toolset/ToolsetSchema.js +21 -0
- package/dist/orchestrator/util/AtomicWriter.js +204 -0
- package/dist/orchestrator/util/DistributedLock.js +232 -0
- package/dist/orchestrator/util/TemplateRenderer.js +87 -0
- package/dist/orchestrator/util/WatchdogHeartbeat.js +116 -0
- package/dist/orchestrator/workflow/ConditionParser.js +232 -0
- package/dist/orchestrator/workflow/WorkflowEngine.js +379 -0
- package/dist/orchestrator/workflow/WorkflowParser.js +368 -0
- package/dist/orchestrator/workflow/WorkflowSchema.js +65 -0
- package/dist/orchestrator/workflow/WorkflowState.js +11 -0
- package/dist/reversa/ReversaAgent.js +134 -0
- package/dist/reversa/ReversaContracts.js +62 -0
- package/dist/reversa/ReversaExecutors.js +65 -0
- package/dist/skills/SkillRegistry.js +71 -0
- package/dist/squads/SquadManager.js +87 -0
- package/dist/test_admin_teams_networks.js +54 -0
- package/dist/test_agent_team_skill_network.js +15 -0
- package/dist/test_aiobuilder_cli_parity.js +169 -0
- package/dist/test_ask_exit.js +73 -0
- package/dist/test_atomic_writer.js +209 -0
- package/dist/test_autonomous_soak.js +141 -0
- package/dist/test_benchmark_engine.js +41 -0
- package/dist/test_brain_error_diagnostics.js +51 -0
- package/dist/test_brain_fallback_chain.js +93 -0
- package/dist/test_capability_genesis_engine.js +225 -0
- package/dist/test_capability_pack_schema.js +214 -0
- package/dist/test_catalog_quality.js +150 -0
- package/dist/test_cli_crud_roundtrip.js +154 -0
- package/dist/test_cli_diagnostics.js +131 -0
- package/dist/test_cli_doc_parity.js +126 -0
- package/dist/test_cli_help_surface.js +106 -0
- package/dist/test_cli_service_commands.js +83 -0
- package/dist/test_consequence_forecast_brain.js +165 -0
- package/dist/test_consequence_forecaster.js +24 -0
- package/dist/test_conversation_memory.js +36 -0
- package/dist/test_create_entities.js +54 -0
- package/dist/test_creator_placeholders_completed.js +177 -0
- package/dist/test_cron_manager.js +123 -0
- package/dist/test_daemon_sigterm.js +72 -0
- package/dist/test_deep_research_capability.js +87 -0
- package/dist/test_designmd_import_registry.js +16 -0
- package/dist/test_designmd_mode.js +50 -0
- package/dist/test_designmd_mode_workspace.js +13 -0
- package/dist/test_dist_templates_layout.js +135 -0
- package/dist/test_distributed_lock.js +201 -0
- package/dist/test_distribution_installability.js +67 -0
- package/dist/test_doctor_sandbox_check.js +44 -0
- package/dist/test_dream_organizer.js +25 -0
- package/dist/test_dual_mode.js +15 -0
- package/dist/test_enterprise_agentic_core.js +128 -0
- package/dist/test_forecast_brain_wiring.js +87 -0
- package/dist/test_gateway_telegram_guardrails.js +52 -0
- package/dist/test_governance.js +34 -0
- package/dist/test_governance_advanced.js +75 -0
- package/dist/test_governance_scope_ledger.js +147 -0
- package/dist/test_governance_v13_policies.js +44 -0
- package/dist/test_guided_creator_cli.js +100 -0
- package/dist/test_host_install_e2e.js +324 -0
- package/dist/test_host_installer.js +259 -0
- package/dist/test_host_installers_gemini_codex.js +95 -0
- package/dist/test_host_uninstaller.js +295 -0
- package/dist/test_install_flow.js +70 -0
- package/dist/test_install_flow_host_validation.js +143 -0
- package/dist/test_install_wizard.js +272 -0
- package/dist/test_integration_gemini_live.js +95 -0
- package/dist/test_integration_http_trigger_live.js +154 -0
- package/dist/test_integration_telegram_live.js +102 -0
- package/dist/test_job_lifecycle.js +16 -0
- package/dist/test_memory_orchestrator.js +33 -0
- package/dist/test_memory_promotion.js +36 -0
- package/dist/test_memory_retention.js +37 -0
- package/dist/test_mission_checkpoint.js +204 -0
- package/dist/test_multi_host_docs_parity.js +125 -0
- package/dist/test_openlife_auto_creator_routing.js +69 -0
- package/dist/test_openlife_evolution_surface.js +77 -0
- package/dist/test_openlife_gatekeeper_routing.js +15 -0
- package/dist/test_openlife_routing_surface.js +27 -0
- package/dist/test_openlife_runtime_source_truth.js +25 -0
- package/dist/test_operating_system.js +45 -0
- package/dist/test_optimization_loop.js +38 -0
- package/dist/test_orchestration_assets_lifecycle.js +78 -0
- package/dist/test_outcome_simulator.js +38 -0
- package/dist/test_performance_latency.js +215 -0
- package/dist/test_performance_scorecard.js +38 -0
- package/dist/test_phase1_check_exit.js +103 -0
- package/dist/test_phase6_board.js +31 -0
- package/dist/test_phase6_cadence.js +29 -0
- package/dist/test_phase6_ops.js +37 -0
- package/dist/test_post_mission_evaluation.js +190 -0
- package/dist/test_process_sandbox.js +88 -0
- package/dist/test_profile_toolset_mcp.js +125 -0
- package/dist/test_queue_scheduler.js +239 -0
- package/dist/test_release_gate.js +23 -0
- package/dist/test_remote_publish.js +193 -0
- package/dist/test_reversa_contracts_e2e.js +48 -0
- package/dist/test_reversa_export_and_strict.js +51 -0
- package/dist/test_reversa_full_execution.js +12 -0
- package/dist/test_reversa_lite.js +9 -0
- package/dist/test_royal_stack_golden.js +179 -0
- package/dist/test_runtime_health_backoff.js +154 -0
- package/dist/test_runtime_policy.js +26 -0
- package/dist/test_runtime_probe.js +19 -0
- package/dist/test_runtime_profile_oauth_only.js +262 -0
- package/dist/test_runtime_registry.js +11 -0
- package/dist/test_security_download_and_scan.js +103 -0
- package/dist/test_security_download_guard.js +14 -0
- package/dist/test_service_command_surface.js +12 -0
- package/dist/test_service_completion_policy.js +32 -0
- package/dist/test_service_guardrails_delete.js +12 -0
- package/dist/test_service_mode_explicit_only.js +174 -0
- package/dist/test_sources_import_ref.js +46 -0
- package/dist/test_sources_scaffold.js +43 -0
- package/dist/test_squad_skill_creator.js +305 -0
- package/dist/test_squad_skill_design_llm.js +176 -0
- package/dist/test_subsystems_org_state.js +271 -0
- package/dist/test_subsystems_promotion_memory_assets.js +343 -0
- package/dist/test_subsystems_routing_governance.js +234 -0
- package/dist/test_task_executor_sandbox_optin.js +127 -0
- package/dist/test_teammate_learning.js +15 -0
- package/dist/test_telegram_delete_guardrail.js +21 -0
- package/dist/test_toolset_enforcement.js +188 -0
- package/dist/test_trigger_basic_auth.js +112 -0
- package/dist/test_util/doc_parity.js +120 -0
- package/dist/test_v15_e2e_integration.js +207 -0
- package/dist/test_watchdog_heartbeat.js +152 -0
- package/dist/test_workflow_condition_parser.js +63 -0
- package/dist/test_workflow_e2e.js +240 -0
- package/dist/test_workflow_engine.js +330 -0
- package/dist/test_workflow_parser.js +245 -0
- package/dist/test_workflow_schema_backward_compat.js +197 -0
- package/dist-templates/README.md +91 -0
- package/dist-templates/claude-code/agents/openlife-atlas.md +52 -0
- package/dist-templates/claude-code/agents/openlife-forge.md +42 -0
- package/dist-templates/claude-code/agents/openlife-genesis.md +59 -0
- package/dist-templates/claude-code/agents/openlife-lyra.md +40 -0
- package/dist-templates/claude-code/agents/openlife-maestro.md +45 -0
- package/dist-templates/claude-code/commands/openlife/ask.md +14 -0
- package/dist-templates/claude-code/commands/openlife/doctor.md +19 -0
- package/dist-templates/claude-code/commands/openlife/dream.md +20 -0
- package/dist-templates/claude-code/commands/openlife/status.md +14 -0
- package/dist-templates/claude-code/mcp/openlife-orchestrator.json +46 -0
- package/dist-templates/codex/README.md +7 -0
- package/dist-templates/codex/agents/openlife-atlas.md +52 -0
- package/dist-templates/codex/agents/openlife-forge.md +42 -0
- package/dist-templates/codex/agents/openlife-genesis.md +59 -0
- package/dist-templates/codex/agents/openlife-lyra.md +40 -0
- package/dist-templates/codex/agents/openlife-maestro.md +45 -0
- package/dist-templates/codex/commands/openlife/ask.md +14 -0
- package/dist-templates/codex/commands/openlife/doctor.md +19 -0
- package/dist-templates/codex/commands/openlife/dream.md +20 -0
- package/dist-templates/codex/commands/openlife/status.md +14 -0
- package/dist-templates/codex/mcp/openlife-orchestrator.json +46 -0
- package/dist-templates/gemini-cli/README.md +8 -0
- package/dist-templates/gemini-cli/agents/openlife-atlas.md +52 -0
- package/dist-templates/gemini-cli/agents/openlife-forge.md +42 -0
- package/dist-templates/gemini-cli/agents/openlife-genesis.md +59 -0
- package/dist-templates/gemini-cli/agents/openlife-lyra.md +40 -0
- package/dist-templates/gemini-cli/agents/openlife-maestro.md +45 -0
- package/dist-templates/gemini-cli/commands/openlife/ask.md +14 -0
- package/dist-templates/gemini-cli/commands/openlife/doctor.md +19 -0
- package/dist-templates/gemini-cli/commands/openlife/dream.md +20 -0
- package/dist-templates/gemini-cli/commands/openlife/status.md +14 -0
- package/dist-templates/gemini-cli/mcp/openlife-orchestrator.json +46 -0
- package/dist-templates/skill-template/README.md +34 -0
- package/dist-templates/skill-template/SKILL.md.template +59 -0
- package/dist-templates/squad-template/README.md +82 -0
- package/dist-templates/squad-template/SQUAD.md.template +51 -0
- package/dist-templates/squad-template/agent-template.md +51 -0
- package/dist-templates/squad-template/checklist-template.md +25 -0
- package/dist-templates/squad-template/task-template.md +36 -0
- package/dist-templates/workflows/PORTED_WORKFLOWS.md +60 -0
- package/dist-templates/workflows/brownfield-discovery.yaml +137 -0
- package/dist-templates/workflows/greenfield-fullstack.yaml +132 -0
- package/dist-templates/workflows/qa-loop.yaml +125 -0
- package/dist-templates/workflows/story-development-cycle.yaml +80 -0
- package/docs/CHANGELOG_FEATURE_ROLLOUT_DESIGNMD.md +43 -0
- package/docs/EXTERNAL_SOURCES_AND_SECURITY_GUARD.md +33 -0
- package/docs/OPENLIFE_AUDIT_2026-05-06.md +170 -0
- package/docs/OPENLIFE_CONSOLIDATED_PLAN_2026-05-06.md +299 -0
- package/docs/OPENLIFE_DUAL_MODE_IMPLEMENTATION_PLAN.md +205 -0
- package/docs/OPENLIFE_EVOLUTION_SURFACE_2026-05-07.md +53 -0
- package/docs/OPENLIFE_SKILLS_IMPORT_2026-05-07.json +223 -0
- package/docs/OPENLIFE_SQUADS_IMPORT_2026-05-07.json +184 -0
- package/docs/PAPERCLIP_OPENLIFE_INVESTIGATION.md +85 -0
- package/docs/README.md +28 -0
- package/docs/RELEASE_ORGANIZATION_PLAN.md +164 -0
- package/docs/audit/CLI-EXECUTION-RESULTS.md +113 -0
- package/docs/audit/CLI-MATRIX.md +556 -0
- package/docs/audit/DOC-PARITY-GAPS.md +351 -0
- package/docs/audit/ORCHESTRATOR-MATRIX.md +136 -0
- package/docs/audit/TEST-COVERAGE-GAPS.md +334 -0
- package/docs/audit/integrations/SKIPPED.md +101 -0
- package/docs/autonomous-install.md +79 -0
- package/docs/capability-genesis.md +137 -0
- package/docs/capability-pack-schema.md +157 -0
- package/docs/commands.md +82 -0
- package/docs/deep-research-capability.md +114 -0
- package/docs/development/typescript-conventions.md +95 -0
- package/docs/host-installers.md +68 -0
- package/docs/install/aiobuilder.md +70 -0
- package/docs/install/claude-code.md +83 -0
- package/docs/install/codex.md +64 -0
- package/docs/install/gemini-cli.md +64 -0
- package/docs/install/runtime-profiles.md +83 -0
- package/docs/openlife-agent-os-blueprint.md +114 -0
- package/docs/openlife-install-backlog.md +115 -0
- package/docs/openlife-install-spec.md +306 -0
- package/docs/operations/CLOUD_CUTOVER_AUDIT.md +37 -0
- package/docs/operations/PHASE_PROGRESS_CONTINUATION.md +24 -0
- package/docs/performance-benchmarks.md +83 -0
- package/docs/planning/v1.3-capability-genesis.md +157 -0
- package/docs/plans/2026-05-05-admin-interface-professional-dark-premium-plan.md +84 -0
- package/docs/plans/2026-05-05-openlife-autonomous-domain-marketplace-masterplan.md +122 -0
- package/docs/quickstart.md +60 -0
- package/docs/release-process.md +236 -0
- package/docs/roadmap/OPENLIFE_MASTER_PLAN_CLOUD_V3.md +97 -0
- package/docs/sandboxing-research.md +117 -0
- package/docs/stories/epic-feature-audit/1.1.story.md +84 -0
- package/docs/stories/epic-feature-audit/1.2.story.md +102 -0
- package/docs/stories/epic-feature-audit/1.3.story.md +93 -0
- package/docs/stories/epic-feature-audit/1.5.story.md +121 -0
- package/docs/stories/epic-feature-audit/1.6.story.md +80 -0
- package/docs/stories/epic-feature-completeness/2.1.story.md +70 -0
- package/docs/stories/epic-feature-completeness/2.2.story.md +49 -0
- package/docs/stories/epic-feature-completeness/2.3.story.md +74 -0
- package/docs/stories/epic-feature-completeness/2.4.story.md +71 -0
- package/docs/stories/epic-feature-completeness/3.1.story.md +56 -0
- package/docs/stories/epic-feature-completeness/3.2.story.md +80 -0
- package/docs/stories/epic-feature-completeness/3.3.story.md +68 -0
- package/docs/stories/epic-feature-completeness/3.4.story.md +71 -0
- package/docs/stories/epic-feature-completeness/3.5.story.md +72 -0
- package/docs/stories/epic-feature-completeness/3.6.story.md +69 -0
- package/docs/stories/epic-feature-completeness/3.7.story.md +68 -0
- package/docs/stories/epic-feature-completeness/3.8.story.md +57 -0
- package/docs/toolset-enforcement.md +122 -0
- package/docs/v1.4-changelog.md +159 -0
- package/docs/v1.5-changelog.md +106 -0
- package/docs/v1.5-roadmap.md +121 -0
- package/docs/v1.6-changelog.md +67 -0
- package/docs/v1.6-roadmap.md +89 -0
- package/docs/v1.7-changelog.md +98 -0
- package/docs/workflow-schema.md +177 -0
- package/package.json +177 -0
- package/scripts/clean-test-pollution.js +61 -0
- package/scripts/openlife-agent-start.sh +6 -0
- package/scripts/openlife-agent.service.example +13 -0
- package/scripts/openlife-agent.supervisord.conf.example +8 -0
- package/scripts/openlife-autonomous-install.sh +29 -0
- package/scripts/postinstall-check.sh +37 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.HeadlessInstallWizard = exports.InstallWizard = exports.CannedAnswerProvider = exports.ReadlineAnswerProvider = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const readline = __importStar(require("readline"));
|
|
40
|
+
const InstallFlow_1 = require("./InstallFlow");
|
|
41
|
+
const InstallStateStore_1 = require("./InstallStateStore");
|
|
42
|
+
const InstallModules_1 = require("./InstallModules");
|
|
43
|
+
const AgentManager_1 = require("./AgentManager");
|
|
44
|
+
/**
|
|
45
|
+
* Production answer provider — uses node:readline. Renders the question and
|
|
46
|
+
* available defaults (bracketed) so the operator can press Enter to accept.
|
|
47
|
+
*/
|
|
48
|
+
class ReadlineAnswerProvider {
|
|
49
|
+
rl;
|
|
50
|
+
ownsInterface;
|
|
51
|
+
constructor(rl) {
|
|
52
|
+
if (rl) {
|
|
53
|
+
this.rl = rl;
|
|
54
|
+
this.ownsInterface = false;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
this.rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
58
|
+
this.ownsInterface = true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
close() {
|
|
62
|
+
if (this.ownsInterface) {
|
|
63
|
+
this.rl.close();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
ask(prompt) {
|
|
67
|
+
return new Promise((resolve) => {
|
|
68
|
+
this.rl.question(prompt, (answer) => resolve(answer));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
async choice(question, options, defaultIndex = 0) {
|
|
72
|
+
const lines = [question];
|
|
73
|
+
for (let i = 0; i < options.length; i++) {
|
|
74
|
+
const marker = i === defaultIndex ? '*' : ' ';
|
|
75
|
+
lines.push(` ${marker} ${i + 1}) ${options[i]}`);
|
|
76
|
+
}
|
|
77
|
+
lines.push(`Choice [${defaultIndex + 1}]: `);
|
|
78
|
+
const raw = (await this.ask(lines.join('\n'))).trim();
|
|
79
|
+
if (!raw)
|
|
80
|
+
return defaultIndex;
|
|
81
|
+
const parsed = Number.parseInt(raw, 10);
|
|
82
|
+
if (Number.isNaN(parsed) || parsed < 1 || parsed > options.length) {
|
|
83
|
+
// Re-ask once instead of silently picking default — gives the operator
|
|
84
|
+
// a chance to fix a typo rather than getting an unexpected install.
|
|
85
|
+
const retry = (await this.ask(`Invalid choice. Pick 1-${options.length} [${defaultIndex + 1}]: `)).trim();
|
|
86
|
+
if (!retry)
|
|
87
|
+
return defaultIndex;
|
|
88
|
+
const retryParsed = Number.parseInt(retry, 10);
|
|
89
|
+
if (Number.isNaN(retryParsed) || retryParsed < 1 || retryParsed > options.length) {
|
|
90
|
+
return defaultIndex;
|
|
91
|
+
}
|
|
92
|
+
return retryParsed - 1;
|
|
93
|
+
}
|
|
94
|
+
return parsed - 1;
|
|
95
|
+
}
|
|
96
|
+
async text(question, defaultValue) {
|
|
97
|
+
const suffix = defaultValue !== undefined && defaultValue !== '' ? ` [${defaultValue}]` : '';
|
|
98
|
+
const raw = (await this.ask(`${question}${suffix}: `)).trim();
|
|
99
|
+
if (!raw && defaultValue !== undefined)
|
|
100
|
+
return defaultValue;
|
|
101
|
+
return raw;
|
|
102
|
+
}
|
|
103
|
+
async yesNo(question, defaultYes = false) {
|
|
104
|
+
const hint = defaultYes ? '[Y/n]' : '[y/N]';
|
|
105
|
+
const raw = (await this.ask(`${question} ${hint}: `)).trim().toLowerCase();
|
|
106
|
+
if (!raw)
|
|
107
|
+
return defaultYes;
|
|
108
|
+
if (raw === 'y' || raw === 'yes')
|
|
109
|
+
return true;
|
|
110
|
+
if (raw === 'n' || raw === 'no')
|
|
111
|
+
return false;
|
|
112
|
+
return defaultYes;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.ReadlineAnswerProvider = ReadlineAnswerProvider;
|
|
116
|
+
/**
|
|
117
|
+
* Test seam — feeds canned answers from a FIFO queue. Each call shifts one off.
|
|
118
|
+
* When the queue is exhausted, throws WIZARD_TEST_OUT_OF_ANSWERS so tests can't
|
|
119
|
+
* silently fall through to a default and mask bugs.
|
|
120
|
+
*/
|
|
121
|
+
class CannedAnswerProvider {
|
|
122
|
+
queue;
|
|
123
|
+
constructor(answers) {
|
|
124
|
+
this.queue = [...answers];
|
|
125
|
+
}
|
|
126
|
+
next(kind) {
|
|
127
|
+
if (this.queue.length === 0) {
|
|
128
|
+
throw new Error(`WIZARD_TEST_OUT_OF_ANSWERS: wizard requested another ${kind} answer but the canned queue is empty`);
|
|
129
|
+
}
|
|
130
|
+
return this.queue.shift();
|
|
131
|
+
}
|
|
132
|
+
async choice(_question, _options, _defaultIndex) {
|
|
133
|
+
const v = this.next('choice');
|
|
134
|
+
if (typeof v !== 'number') {
|
|
135
|
+
throw new Error(`WIZARD_TEST_WRONG_ANSWER_TYPE: expected number for choice, got ${typeof v}`);
|
|
136
|
+
}
|
|
137
|
+
return v;
|
|
138
|
+
}
|
|
139
|
+
async text(_question, _defaultValue) {
|
|
140
|
+
const v = this.next('text');
|
|
141
|
+
if (typeof v !== 'string') {
|
|
142
|
+
throw new Error(`WIZARD_TEST_WRONG_ANSWER_TYPE: expected string for text, got ${typeof v}`);
|
|
143
|
+
}
|
|
144
|
+
return v;
|
|
145
|
+
}
|
|
146
|
+
async yesNo(_question, _defaultYes) {
|
|
147
|
+
const v = this.next('yesNo');
|
|
148
|
+
if (typeof v !== 'boolean') {
|
|
149
|
+
throw new Error(`WIZARD_TEST_WRONG_ANSWER_TYPE: expected boolean for yesNo, got ${typeof v}`);
|
|
150
|
+
}
|
|
151
|
+
return v;
|
|
152
|
+
}
|
|
153
|
+
remaining() {
|
|
154
|
+
return this.queue.length;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
exports.CannedAnswerProvider = CannedAnswerProvider;
|
|
158
|
+
/**
|
|
159
|
+
* Interactive install wizard. Walks the operator through profile, host,
|
|
160
|
+
* model order, Telegram bits (autonomous only), doctor toggle, and a final
|
|
161
|
+
* confirm preview. Returns a WizardResult that the caller passes into
|
|
162
|
+
* `new InstallFlow().run(options)`.
|
|
163
|
+
*
|
|
164
|
+
* Re-entry safe: if `<root>/.openlife/install-manifest.json` exists, the
|
|
165
|
+
* wizard asks the operator whether to reinstall, repair, or abort BEFORE
|
|
166
|
+
* touching any other question — so an accidental rerun doesn't clobber
|
|
167
|
+
* a working install silently.
|
|
168
|
+
*/
|
|
169
|
+
class InstallWizard {
|
|
170
|
+
root;
|
|
171
|
+
answers;
|
|
172
|
+
constructor(root = process.cwd(), answers = new ReadlineAnswerProvider()) {
|
|
173
|
+
this.root = root;
|
|
174
|
+
this.answers = answers;
|
|
175
|
+
}
|
|
176
|
+
async run() {
|
|
177
|
+
const warnings = [];
|
|
178
|
+
// 1. Pre-existing install detection
|
|
179
|
+
const manifestPath = path.join(this.root, '.openlife', 'install-manifest.json');
|
|
180
|
+
let preExistingAction;
|
|
181
|
+
if (fs.existsSync(manifestPath)) {
|
|
182
|
+
const idx = await this.answers.choice('Detected an existing OpenLife install at .openlife/install-manifest.json. What do you want to do?', ['abort (recommended)', 'reinstall (overwrite)', 'repair (re-run install over existing)'], 0);
|
|
183
|
+
if (idx === 0) {
|
|
184
|
+
return { ok: false, reason: 'user_aborted', detail: 'pre_existing_install_abort' };
|
|
185
|
+
}
|
|
186
|
+
preExistingAction = idx === 1 ? 'reinstall' : 'repair';
|
|
187
|
+
}
|
|
188
|
+
// 2. Profile selection
|
|
189
|
+
const profileIdx = await this.answers.choice('Which profile do you want to install?\n framework — local interactive CLI (default)\n autonomous — long-running daemon with Telegram gateway and governance', ['framework', 'autonomous'], 0);
|
|
190
|
+
const profile = profileIdx === 1 ? 'autonomous' : 'framework';
|
|
191
|
+
// 3. Host selection — auto-detect, but always ask to confirm.
|
|
192
|
+
const detected = (0, InstallFlow_1.detectHostFromEnv)();
|
|
193
|
+
const hostOptions = [...InstallFlow_1.VALID_HOSTS];
|
|
194
|
+
const defaultHostIdx = hostOptions.indexOf(detected || InstallFlow_1.DEFAULT_HOST);
|
|
195
|
+
const hostHeader = detected
|
|
196
|
+
? `Which host CLI? (detected: ${detected})`
|
|
197
|
+
: 'Which host CLI?';
|
|
198
|
+
const hostIdx = await this.answers.choice(`${hostHeader}\n claude-code — Anthropic Claude Code (fully supported)\n gemini-cli — Google Gemini CLI (host-install not yet wired)\n codex — OpenAI Codex CLI (host-install not yet wired)`, [...hostOptions], defaultHostIdx >= 0 ? defaultHostIdx : 0);
|
|
199
|
+
const host = hostOptions[hostIdx];
|
|
200
|
+
let validatedHost;
|
|
201
|
+
try {
|
|
202
|
+
validatedHost = (0, InstallFlow_1.validateHost)(host);
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
return { ok: false, reason: 'invalid_input', detail: err instanceof Error ? err.message : String(err) };
|
|
206
|
+
}
|
|
207
|
+
if (validatedHost !== 'claude-code') {
|
|
208
|
+
warnings.push(`HOST_NOT_YET_SUPPORTED: ${validatedHost} host-specific install is a no-op for now; .openlife state will still be created`);
|
|
209
|
+
}
|
|
210
|
+
// 4. Model chain (optional)
|
|
211
|
+
const modelsRaw = await this.answers.text('LLM model order (comma-separated provider/model chain, blank = defaults)', '');
|
|
212
|
+
const modelOrder = modelsRaw
|
|
213
|
+
? modelsRaw.split(',').map((m) => m.trim()).filter(Boolean)
|
|
214
|
+
: undefined;
|
|
215
|
+
// 5. Telegram (autonomous only)
|
|
216
|
+
if (profile === 'autonomous') {
|
|
217
|
+
const hasTelegram = await this.answers.yesNo('Do you already have TELEGRAM_BOT_TOKEN and OPENLIFE_TELEGRAM_ALLOWED_USER_ID set in your .env?', false);
|
|
218
|
+
if (!hasTelegram) {
|
|
219
|
+
warnings.push('TELEGRAM_NOT_CONFIGURED: autonomous profile needs TELEGRAM_BOT_TOKEN and OPENLIFE_TELEGRAM_ALLOWED_USER_ID — set them in .env before running `openlife agent start`');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// 6. Skip doctor?
|
|
223
|
+
const skipDoctor = await this.answers.yesNo('Skip the system doctor run?', false);
|
|
224
|
+
// 7. Confirm preview
|
|
225
|
+
const previewLines = [
|
|
226
|
+
'Review your choices:',
|
|
227
|
+
` profile : ${profile}`,
|
|
228
|
+
` host : ${validatedHost}`,
|
|
229
|
+
` modelOrder : ${modelOrder ? modelOrder.join(', ') : '(defaults)'}`,
|
|
230
|
+
` skipDoctor : ${skipDoctor}`,
|
|
231
|
+
preExistingAction ? ` preExisting : ${preExistingAction}` : ''
|
|
232
|
+
].filter(Boolean);
|
|
233
|
+
if (warnings.length) {
|
|
234
|
+
previewLines.push(' warnings:');
|
|
235
|
+
for (const w of warnings)
|
|
236
|
+
previewLines.push(` - ${w}`);
|
|
237
|
+
}
|
|
238
|
+
const confirmed = await this.answers.yesNo(`${previewLines.join('\n')}\nProceed with install?`, false);
|
|
239
|
+
if (!confirmed) {
|
|
240
|
+
return { ok: false, reason: 'user_aborted', detail: 'preview_not_confirmed' };
|
|
241
|
+
}
|
|
242
|
+
const options = {
|
|
243
|
+
profile,
|
|
244
|
+
host: validatedHost,
|
|
245
|
+
skipDoctor,
|
|
246
|
+
modelOrder
|
|
247
|
+
};
|
|
248
|
+
return {
|
|
249
|
+
ok: true,
|
|
250
|
+
options,
|
|
251
|
+
preExistingAction,
|
|
252
|
+
warnings: warnings.length ? warnings : undefined
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
exports.InstallWizard = InstallWizard;
|
|
257
|
+
class HeadlessInstallWizard {
|
|
258
|
+
root;
|
|
259
|
+
flow;
|
|
260
|
+
state;
|
|
261
|
+
constructor(root = process.cwd(), flow = new InstallFlow_1.InstallFlow(root), state = new InstallStateStore_1.InstallStateStore(root)) {
|
|
262
|
+
this.root = root;
|
|
263
|
+
this.flow = flow;
|
|
264
|
+
this.state = state;
|
|
265
|
+
}
|
|
266
|
+
run(options) {
|
|
267
|
+
const mode = this.resolveMode(options.mode);
|
|
268
|
+
if (options.resume) {
|
|
269
|
+
const loaded = this.state.load();
|
|
270
|
+
if (!loaded) {
|
|
271
|
+
return ['⚠️ Nenhum estado salvo para retomar em .openlife/install-state.json'];
|
|
272
|
+
}
|
|
273
|
+
return [
|
|
274
|
+
`♻️ Retomando setup salvo`,
|
|
275
|
+
`- mode: ${loaded.mode}`,
|
|
276
|
+
`- currentStep: ${loaded.currentStep}`,
|
|
277
|
+
`- completed: ${loaded.completedSteps.join(', ') || '(none)'}`,
|
|
278
|
+
`- state: ${this.state.path()}`
|
|
279
|
+
];
|
|
280
|
+
}
|
|
281
|
+
const pre = (0, InstallModules_1.runPrecheck)();
|
|
282
|
+
const preLines = pre.checks.map(c => `- ${c.ok ? '✅' : '❌'} ${c.name}: ${c.detail}`);
|
|
283
|
+
const installChecklist = [];
|
|
284
|
+
if (options.telegramToken) {
|
|
285
|
+
const tokenValidation = (0, InstallModules_1.validateTelegramToken)(options.telegramToken);
|
|
286
|
+
if (!tokenValidation.ok) {
|
|
287
|
+
installChecklist.push(`❌ telegram_token: ${tokenValidation.detail}`);
|
|
288
|
+
return ['📋 Install checklist', ...installChecklist, `❌ Telegram token inválido: ${tokenValidation.detail}`];
|
|
289
|
+
}
|
|
290
|
+
installChecklist.push(`✅ telegram_token: ${tokenValidation.detail}`);
|
|
291
|
+
const conflict = (0, InstallModules_1.checkTelegram409Conflict)(this.root, options.telegramToken);
|
|
292
|
+
if (!conflict.ok) {
|
|
293
|
+
installChecklist.push(`❌ telegram_conflict: ${conflict.detail}`);
|
|
294
|
+
return [
|
|
295
|
+
'📋 Install checklist',
|
|
296
|
+
...installChecklist,
|
|
297
|
+
`❌ ${conflict.detail}`,
|
|
298
|
+
'Ações: pare a outra instância, use outro token, ou rode sem --telegram-token.'
|
|
299
|
+
];
|
|
300
|
+
}
|
|
301
|
+
installChecklist.push(`✅ telegram_conflict: ${conflict.detail}`);
|
|
302
|
+
(0, InstallModules_1.saveTelegramConfig)(this.root, options.telegramToken, options.telegramChatId);
|
|
303
|
+
installChecklist.push('✅ telegram_save: configuração salva em .env');
|
|
304
|
+
const chatValidation = (0, InstallModules_1.validateTelegramChatId)(options.telegramToken, options.telegramChatId);
|
|
305
|
+
if (!chatValidation.ok) {
|
|
306
|
+
installChecklist.push(`❌ telegram_chat: ${chatValidation.detail}`);
|
|
307
|
+
return ['📋 Install checklist', ...installChecklist, `❌ Telegram chat_id inválido: ${chatValidation.detail}`];
|
|
308
|
+
}
|
|
309
|
+
installChecklist.push(`✅ telegram_chat: ${chatValidation.detail}`);
|
|
310
|
+
(0, InstallModules_1.writeTelegramLock)(this.root, options.telegramToken);
|
|
311
|
+
installChecklist.push('✅ telegram_lock: lock de polling gravado');
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
installChecklist.push('ℹ️ telegram: não configurado nesta execução');
|
|
315
|
+
}
|
|
316
|
+
this.state.save({ mode, currentStep: 'run-install-flow', completedSteps: ['precheck'] });
|
|
317
|
+
const profile = mode === 'autonomous' ? 'autonomous' : 'framework';
|
|
318
|
+
const result = this.flow.run({
|
|
319
|
+
profile,
|
|
320
|
+
host: options.host,
|
|
321
|
+
skipDoctor: options.skipDoctor,
|
|
322
|
+
modelOrder: options.modelOrder
|
|
323
|
+
});
|
|
324
|
+
const chat = (0, InstallModules_1.chatSmoke)();
|
|
325
|
+
let agentLines = [];
|
|
326
|
+
if (mode === 'autonomous') {
|
|
327
|
+
const manager = new AgentManager_1.AgentManager(this.root);
|
|
328
|
+
let agents = manager.ensureDefault(options.defaultAgentName);
|
|
329
|
+
if (options.additionalAgentName) {
|
|
330
|
+
agents = manager.createAdditional(options.additionalAgentName);
|
|
331
|
+
}
|
|
332
|
+
agentLines = [
|
|
333
|
+
'🤖 Agent manager',
|
|
334
|
+
...agents.map(a => `- ${a.isDefault ? '[default]' : '[extra]'} ${a.name} (${a.id})`)
|
|
335
|
+
];
|
|
336
|
+
}
|
|
337
|
+
this.state.save({
|
|
338
|
+
mode,
|
|
339
|
+
currentStep: 'completed',
|
|
340
|
+
completedSteps: ['precheck', 'run-install-flow', 'chat-smoke', 'completed'],
|
|
341
|
+
metadata: { reportPath: result.reportPath }
|
|
342
|
+
});
|
|
343
|
+
return [
|
|
344
|
+
'📋 Install checklist',
|
|
345
|
+
`- ${pre.ok ? '✅' : '❌'} precheck`,
|
|
346
|
+
...installChecklist.map(i => `- ${i}`),
|
|
347
|
+
`- ✅ install_flow: concluído`,
|
|
348
|
+
...agentLines.length ? ['- ✅ agent_manager: aplicado (modo autônomo)'] : ['- ℹ️ agent_manager: não aplicável no modo CLI'],
|
|
349
|
+
`- ${chat.ok ? '✅' : '❌'} chat_smoke`,
|
|
350
|
+
'- ✅ state_save: install-state.json atualizado',
|
|
351
|
+
'',
|
|
352
|
+
'🩺 Precheck',
|
|
353
|
+
...preLines,
|
|
354
|
+
...this.flow.renderSummary(result),
|
|
355
|
+
...agentLines,
|
|
356
|
+
`${chat.ok ? '✅' : '❌'} Chat smoke: ${chat.detail}`,
|
|
357
|
+
`🧩 State file: ${this.state.path()}`
|
|
358
|
+
];
|
|
359
|
+
}
|
|
360
|
+
resolveMode(mode) {
|
|
361
|
+
return String(mode || '').toLowerCase() === 'autonomous' ? 'autonomous' : 'cli';
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
exports.HeadlessInstallWizard = HeadlessInstallWizard;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ProfileManager — runtime profile manager.
|
|
4
|
+
*
|
|
5
|
+
* Story 5.2 — OpenLife v1.3 Agent OS Integration.
|
|
6
|
+
*
|
|
7
|
+
* Wraps the existing InstallStateStore + AgentManager surface with a
|
|
8
|
+
* per-profile namespace concept. A Profile carries:
|
|
9
|
+
* - id, name, description
|
|
10
|
+
* - memoryNamespace (passed through to OmniMemory)
|
|
11
|
+
* - catalogScope[] (limits which .catalog/ subtrees are visible)
|
|
12
|
+
* - toolsetAllowed[] (controls ToolsetRegistry — Story 5.3)
|
|
13
|
+
* - modelChain (optional override of ModelManager primary+fallbacks)
|
|
14
|
+
* - gatewaySettings (Telegram allowlist, /health metadata)
|
|
15
|
+
*
|
|
16
|
+
* Storage: `.openlife/profiles/<id>.json` + `.openlife/active-profile.json`
|
|
17
|
+
*
|
|
18
|
+
* Profiles default to global scope (catalogScope=[], toolsetAllowed=[*])
|
|
19
|
+
* for backwards compatibility with existing AgentProfile entries.
|
|
20
|
+
*
|
|
21
|
+
* Lifecycle is fully append-only: create/update produce a new file
|
|
22
|
+
* (atomic write); use(<id>) just updates the active-profile pointer.
|
|
23
|
+
* No deletion in v1.3 — call use(<other>) and ignore the old file.
|
|
24
|
+
*/
|
|
25
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
28
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
29
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
30
|
+
}
|
|
31
|
+
Object.defineProperty(o, k2, desc);
|
|
32
|
+
}) : (function(o, m, k, k2) {
|
|
33
|
+
if (k2 === undefined) k2 = k;
|
|
34
|
+
o[k2] = m[k];
|
|
35
|
+
}));
|
|
36
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
37
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
38
|
+
}) : function(o, v) {
|
|
39
|
+
o["default"] = v;
|
|
40
|
+
});
|
|
41
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
42
|
+
var ownKeys = function(o) {
|
|
43
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
44
|
+
var ar = [];
|
|
45
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
46
|
+
return ar;
|
|
47
|
+
};
|
|
48
|
+
return ownKeys(o);
|
|
49
|
+
};
|
|
50
|
+
return function (mod) {
|
|
51
|
+
if (mod && mod.__esModule) return mod;
|
|
52
|
+
var result = {};
|
|
53
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
54
|
+
__setModuleDefault(result, mod);
|
|
55
|
+
return result;
|
|
56
|
+
};
|
|
57
|
+
})();
|
|
58
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
59
|
+
exports.ProfileManager = void 0;
|
|
60
|
+
const fs = __importStar(require("fs"));
|
|
61
|
+
const path = __importStar(require("path"));
|
|
62
|
+
const AtomicWriter_1 = require("../orchestrator/util/AtomicWriter");
|
|
63
|
+
class ProfileManager {
|
|
64
|
+
profilesDir;
|
|
65
|
+
activeFile;
|
|
66
|
+
constructor(opts = {}) {
|
|
67
|
+
const stateDir = opts.stateDir
|
|
68
|
+
|| process.env.OPENLIFE_STATE_DIR
|
|
69
|
+
|| path.join(process.cwd(), '.openlife');
|
|
70
|
+
this.profilesDir = path.join(stateDir, 'profiles');
|
|
71
|
+
this.activeFile = path.join(stateDir, 'active-profile.json');
|
|
72
|
+
fs.mkdirSync(this.profilesDir, { recursive: true });
|
|
73
|
+
}
|
|
74
|
+
profilePath(id) {
|
|
75
|
+
const safe = id.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
76
|
+
return path.join(this.profilesDir, `${safe}.json`);
|
|
77
|
+
}
|
|
78
|
+
list() {
|
|
79
|
+
if (!fs.existsSync(this.profilesDir))
|
|
80
|
+
return [];
|
|
81
|
+
const out = [];
|
|
82
|
+
for (const f of fs.readdirSync(this.profilesDir)) {
|
|
83
|
+
if (!f.endsWith('.json'))
|
|
84
|
+
continue;
|
|
85
|
+
try {
|
|
86
|
+
out.push(JSON.parse(fs.readFileSync(path.join(this.profilesDir, f), 'utf-8')));
|
|
87
|
+
}
|
|
88
|
+
catch { /* skip corrupt */ }
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
show(id) {
|
|
93
|
+
const p = this.profilePath(id);
|
|
94
|
+
if (!fs.existsSync(p))
|
|
95
|
+
return null;
|
|
96
|
+
try {
|
|
97
|
+
return JSON.parse(fs.readFileSync(p, 'utf-8'));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
create(opts) {
|
|
104
|
+
if (!/^[a-z0-9][a-z0-9._-]+$/i.test(opts.id)) {
|
|
105
|
+
throw Object.assign(new Error('invalid_profile_id'), { code: 'invalid_profile_id' });
|
|
106
|
+
}
|
|
107
|
+
const file = this.profilePath(opts.id);
|
|
108
|
+
if (fs.existsSync(file)) {
|
|
109
|
+
throw Object.assign(new Error('profile_already_exists'), { code: 'profile_already_exists' });
|
|
110
|
+
}
|
|
111
|
+
const now = new Date().toISOString();
|
|
112
|
+
const profile = {
|
|
113
|
+
id: opts.id,
|
|
114
|
+
name: opts.name,
|
|
115
|
+
description: opts.description,
|
|
116
|
+
memoryNamespace: opts.memoryNamespace || `profile-${opts.id}`,
|
|
117
|
+
catalogScope: opts.catalogScope || [],
|
|
118
|
+
toolsetAllowed: opts.toolsetAllowed || ['*'],
|
|
119
|
+
modelChain: opts.modelChain,
|
|
120
|
+
gatewaySettings: opts.gatewaySettings,
|
|
121
|
+
createdAt: now,
|
|
122
|
+
updatedAt: now,
|
|
123
|
+
};
|
|
124
|
+
(0, AtomicWriter_1.writeJsonAtomic)(file, profile);
|
|
125
|
+
return profile;
|
|
126
|
+
}
|
|
127
|
+
/** Set the active profile pointer. The profile must already exist. */
|
|
128
|
+
use(id) {
|
|
129
|
+
if (!this.show(id))
|
|
130
|
+
return { ok: false, error: 'not_found' };
|
|
131
|
+
(0, AtomicWriter_1.writeJsonAtomic)(this.activeFile, { activeProfileId: id, at: new Date().toISOString() });
|
|
132
|
+
return { ok: true };
|
|
133
|
+
}
|
|
134
|
+
/** Return the active profile id, or null if none set. */
|
|
135
|
+
active() {
|
|
136
|
+
if (!fs.existsSync(this.activeFile))
|
|
137
|
+
return { profileId: null, profile: null };
|
|
138
|
+
try {
|
|
139
|
+
const ptr = JSON.parse(fs.readFileSync(this.activeFile, 'utf-8'));
|
|
140
|
+
const id = ptr.activeProfileId || null;
|
|
141
|
+
return { profileId: id, profile: id ? this.show(id) : null };
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return { profileId: null, profile: null };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** Export a profile as plain JSON (for import on another machine). */
|
|
148
|
+
export(id) {
|
|
149
|
+
return this.show(id);
|
|
150
|
+
}
|
|
151
|
+
/** Import a profile from a JSON object. Idempotent — overwrites on id collision. */
|
|
152
|
+
import(profile) {
|
|
153
|
+
if (!profile?.id || !/^[a-z0-9][a-z0-9._-]+$/i.test(profile.id)) {
|
|
154
|
+
return { ok: false, error: 'invalid_profile_id' };
|
|
155
|
+
}
|
|
156
|
+
(0, AtomicWriter_1.writeJsonAtomic)(this.profilePath(profile.id), {
|
|
157
|
+
...profile,
|
|
158
|
+
updatedAt: new Date().toISOString(),
|
|
159
|
+
});
|
|
160
|
+
return { ok: true };
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
exports.ProfileManager = ProfileManager;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.SystemInstaller = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
class SystemInstaller {
|
|
40
|
+
root;
|
|
41
|
+
constructor(root = process.cwd()) {
|
|
42
|
+
this.root = root;
|
|
43
|
+
}
|
|
44
|
+
install() {
|
|
45
|
+
const configDir = path.join(this.root, '.openlife');
|
|
46
|
+
if (!fs.existsSync(configDir))
|
|
47
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
48
|
+
const installManifest = {
|
|
49
|
+
installedAt: new Date().toISOString(),
|
|
50
|
+
root: this.root,
|
|
51
|
+
files: [
|
|
52
|
+
'models.json',
|
|
53
|
+
'executor-policy.json',
|
|
54
|
+
'voice.config.json'
|
|
55
|
+
],
|
|
56
|
+
providers: {
|
|
57
|
+
openai: !!process.env.OPENAI_API_KEY,
|
|
58
|
+
gemini: !!process.env.GEMINI_API_KEY,
|
|
59
|
+
anthropic: !!process.env.ANTHROPIC_API_KEY
|
|
60
|
+
},
|
|
61
|
+
clis: {
|
|
62
|
+
codex: true,
|
|
63
|
+
gemini: true,
|
|
64
|
+
ollama: true
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const manifestPath = path.join(configDir, 'install-manifest.json');
|
|
68
|
+
fs.writeFileSync(manifestPath, JSON.stringify(installManifest, null, 2), 'utf-8');
|
|
69
|
+
return manifestPath;
|
|
70
|
+
}
|
|
71
|
+
status() {
|
|
72
|
+
return {
|
|
73
|
+
root: this.root,
|
|
74
|
+
hasModels: fs.existsSync(path.join(this.root, 'models.json')),
|
|
75
|
+
hasExecutorPolicy: fs.existsSync(path.join(this.root, 'executor-policy.json')),
|
|
76
|
+
hasVoiceConfig: fs.existsSync(path.join(this.root, 'voice.config.json')),
|
|
77
|
+
hasArtifacts: fs.existsSync(path.join(this.root, '.artifacts')),
|
|
78
|
+
hasInstallManifest: fs.existsSync(path.join(this.root, '.openlife', 'install-manifest.json'))
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
initProject() {
|
|
82
|
+
const file = path.join(this.root, 'OPENLIFE_PROJECT.md');
|
|
83
|
+
if (!fs.existsSync(file)) {
|
|
84
|
+
fs.writeFileSync(file, '# OPENLIFE PROJECT\n\nDescreva aqui o projeto, contexto, regras e objetivos.\n', 'utf-8');
|
|
85
|
+
}
|
|
86
|
+
return file;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.SystemInstaller = SystemInstaller;
|