@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,286 @@
|
|
|
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.ConsequenceForecaster = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const crypto = __importStar(require("crypto"));
|
|
40
|
+
const AtomicWriter_1 = require("./util/AtomicWriter");
|
|
41
|
+
class ConsequenceForecaster {
|
|
42
|
+
forecast(goal, governanceRisk, basePolicy, executors) {
|
|
43
|
+
const normalizedGoal = goal.toLowerCase();
|
|
44
|
+
const paths = [
|
|
45
|
+
this.buildConservativePath(basePolicy, executors, governanceRisk, normalizedGoal),
|
|
46
|
+
this.buildBalancedPath(basePolicy, executors, governanceRisk, normalizedGoal),
|
|
47
|
+
this.buildAggressivePath(basePolicy, executors, governanceRisk, normalizedGoal)
|
|
48
|
+
];
|
|
49
|
+
const selectedPath = this.pickBest(paths);
|
|
50
|
+
const executiveSummary = this.buildExecutiveSummary(selectedPath, governanceRisk, normalizedGoal);
|
|
51
|
+
return { selectedPath, consideredPaths: paths, executiveSummary };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Story 14.3 (v1.5) — Brain-enriched forecast with persistent cache.
|
|
55
|
+
*
|
|
56
|
+
* Calls `forecast()` first, then layers a Brain-derived
|
|
57
|
+
* `BrainForecastEnrichment` on top (riskAmplifiers / opportunityFactors /
|
|
58
|
+
* overallVerdict / rationale). The enrichment is cached at
|
|
59
|
+
* `.openlife/forecasts/<sha256(goal)>.json` keyed by goalHash + governanceRisk
|
|
60
|
+
* so repeated forecasts for the same goal don't burn tokens.
|
|
61
|
+
*
|
|
62
|
+
* Falls back gracefully:
|
|
63
|
+
* • Cache hit fresher than TTL (default 24h) → cached enrichment, source='cache'
|
|
64
|
+
* • Brain key absent → no enrichment attached; pure heuristic forecast
|
|
65
|
+
* • Brain available + parseable → fresh enrichment cached, source='brain'
|
|
66
|
+
* • Brain available + garbage → no enrichment attached
|
|
67
|
+
*
|
|
68
|
+
* Disable cache via OPENLIFE_FORECAST_CACHE=off. Custom TTL via
|
|
69
|
+
* OPENLIFE_FORECAST_CACHE_TTL_HOURS.
|
|
70
|
+
*/
|
|
71
|
+
async forecastWithBrain(goal, governanceRisk, basePolicy, executors) {
|
|
72
|
+
const base = this.forecast(goal, governanceRisk, basePolicy, executors);
|
|
73
|
+
const goalHash = crypto.createHash('sha256').update(goal).digest('hex');
|
|
74
|
+
const cacheKey = `${goalHash}_${governanceRisk}`;
|
|
75
|
+
const cached = this.readForecastCache(cacheKey);
|
|
76
|
+
if (cached)
|
|
77
|
+
return { ...base, brain: { ...cached, source: 'cache' } };
|
|
78
|
+
try {
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
80
|
+
const { Brain } = require('./Brain');
|
|
81
|
+
const brain = new Brain();
|
|
82
|
+
if (!brain.isAnyProviderAvailable())
|
|
83
|
+
return base;
|
|
84
|
+
const systemPrompt = [
|
|
85
|
+
'You are a risk forecaster for an autonomous orchestrator.',
|
|
86
|
+
'Given a mission goal, governance risk level, and selected execution path,',
|
|
87
|
+
'output ONE LINE of JSON: { "riskAmplifiers": [string,...], "opportunityFactors": [string,...], "overallVerdict": "safe"|"caution"|"block", "rationale": string }',
|
|
88
|
+
'Max 5 entries per array. No markdown, no preamble.',
|
|
89
|
+
].join(' ');
|
|
90
|
+
const userMessage = [
|
|
91
|
+
`Goal: ${goal}`,
|
|
92
|
+
`Governance risk: ${governanceRisk}`,
|
|
93
|
+
`Selected path: ${base.selectedPath.id} (${base.selectedPath.description})`,
|
|
94
|
+
`Considered consequences: ${base.selectedPath.consequences.join(' | ')}`,
|
|
95
|
+
].join('\n');
|
|
96
|
+
const raw = await brain.think(systemPrompt, userMessage);
|
|
97
|
+
const parsed = this.parseBrainEnrichment(raw);
|
|
98
|
+
if (!parsed)
|
|
99
|
+
return base;
|
|
100
|
+
const enrichment = { ...parsed, source: 'brain', cachedAt: new Date().toISOString() };
|
|
101
|
+
this.writeForecastCache(cacheKey, enrichment);
|
|
102
|
+
return { ...base, brain: enrichment };
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return base;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
parseBrainEnrichment(raw) {
|
|
109
|
+
try {
|
|
110
|
+
const start = raw.indexOf('{');
|
|
111
|
+
const end = raw.lastIndexOf('}');
|
|
112
|
+
if (start < 0 || end <= start)
|
|
113
|
+
return null;
|
|
114
|
+
const obj = JSON.parse(raw.slice(start, end + 1));
|
|
115
|
+
const amp = Array.isArray(obj.riskAmplifiers)
|
|
116
|
+
? obj.riskAmplifiers.filter((s) => typeof s === 'string').slice(0, 5)
|
|
117
|
+
: null;
|
|
118
|
+
const opp = Array.isArray(obj.opportunityFactors)
|
|
119
|
+
? obj.opportunityFactors.filter((s) => typeof s === 'string').slice(0, 5)
|
|
120
|
+
: null;
|
|
121
|
+
const verdict = obj.overallVerdict === 'safe' || obj.overallVerdict === 'caution' || obj.overallVerdict === 'block'
|
|
122
|
+
? obj.overallVerdict
|
|
123
|
+
: null;
|
|
124
|
+
const rationale = typeof obj.rationale === 'string' ? obj.rationale.slice(0, 400) : '';
|
|
125
|
+
if (!amp || !opp || !verdict)
|
|
126
|
+
return null;
|
|
127
|
+
return { riskAmplifiers: amp, opportunityFactors: opp, overallVerdict: verdict, rationale };
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
readForecastCache(cacheKey) {
|
|
134
|
+
if (process.env.OPENLIFE_FORECAST_CACHE === 'off')
|
|
135
|
+
return null;
|
|
136
|
+
const file = this.cacheFile(cacheKey);
|
|
137
|
+
if (!fs.existsSync(file))
|
|
138
|
+
return null;
|
|
139
|
+
try {
|
|
140
|
+
const entry = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
141
|
+
const ttlHours = Number(process.env.OPENLIFE_FORECAST_CACHE_TTL_HOURS || 24);
|
|
142
|
+
if (!entry.cachedAt)
|
|
143
|
+
return null;
|
|
144
|
+
const ageMs = Date.now() - new Date(entry.cachedAt).getTime();
|
|
145
|
+
if (ageMs > ttlHours * 60 * 60 * 1000)
|
|
146
|
+
return null;
|
|
147
|
+
return entry;
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
writeForecastCache(cacheKey, entry) {
|
|
154
|
+
if (process.env.OPENLIFE_FORECAST_CACHE === 'off')
|
|
155
|
+
return;
|
|
156
|
+
try {
|
|
157
|
+
const file = this.cacheFile(cacheKey);
|
|
158
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
159
|
+
(0, AtomicWriter_1.writeJsonAtomic)(file, entry);
|
|
160
|
+
}
|
|
161
|
+
catch { /* non-fatal */ }
|
|
162
|
+
}
|
|
163
|
+
cacheFile(cacheKey) {
|
|
164
|
+
const stateDir = process.env.OPENLIFE_STATE_DIR || path.join(process.cwd(), '.openlife');
|
|
165
|
+
return path.join(stateDir, 'forecasts', `${cacheKey}.json`);
|
|
166
|
+
}
|
|
167
|
+
buildConservativePath(basePolicy, executors, risk, normalizedGoal) {
|
|
168
|
+
const policy = {
|
|
169
|
+
executionMode: 'balanced',
|
|
170
|
+
swarmMode: 'none',
|
|
171
|
+
maxBranches: 1,
|
|
172
|
+
rationale: 'Conservador: minimizar risco de efeitos colaterais.'
|
|
173
|
+
};
|
|
174
|
+
const score = this.scorePath(risk, policy, executors, normalizedGoal, true);
|
|
175
|
+
return {
|
|
176
|
+
id: 'conservative',
|
|
177
|
+
description: 'Executa com baixa superfície e validação estrita.',
|
|
178
|
+
policy,
|
|
179
|
+
executors,
|
|
180
|
+
consequences: [
|
|
181
|
+
'Reduz chance de bloqueio por governança',
|
|
182
|
+
'Pode aumentar tempo total de execução',
|
|
183
|
+
'Preserva previsibilidade do serviço'
|
|
184
|
+
],
|
|
185
|
+
score
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
buildBalancedPath(basePolicy, executors, risk, normalizedGoal) {
|
|
189
|
+
const policy = {
|
|
190
|
+
...basePolicy,
|
|
191
|
+
executionMode: 'balanced',
|
|
192
|
+
swarmMode: basePolicy.swarmMode === 'consensus' ? 'parallel' : basePolicy.swarmMode,
|
|
193
|
+
maxBranches: Math.max(1, Math.min(basePolicy.maxBranches, 3)),
|
|
194
|
+
rationale: 'Balanceado: manter qualidade com risco controlado.'
|
|
195
|
+
};
|
|
196
|
+
const score = this.scorePath(risk, policy, executors, normalizedGoal, false) + 1;
|
|
197
|
+
return {
|
|
198
|
+
id: 'balanced',
|
|
199
|
+
description: 'Combina execução robusta com fallback e revisão.',
|
|
200
|
+
policy,
|
|
201
|
+
executors,
|
|
202
|
+
consequences: [
|
|
203
|
+
'Boa relação entre velocidade e segurança',
|
|
204
|
+
'Mantém chance alta de serviço completo',
|
|
205
|
+
'Risco moderado de retrabalho'
|
|
206
|
+
],
|
|
207
|
+
score
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
buildAggressivePath(basePolicy, executors, risk, normalizedGoal) {
|
|
211
|
+
const policy = {
|
|
212
|
+
executionMode: 'performance',
|
|
213
|
+
swarmMode: 'consensus',
|
|
214
|
+
maxBranches: 4,
|
|
215
|
+
rationale: 'Agressivo: maximizar throughput e paralelismo.'
|
|
216
|
+
};
|
|
217
|
+
const score = this.scorePath(risk, policy, executors, normalizedGoal, false) - 2;
|
|
218
|
+
return {
|
|
219
|
+
id: 'aggressive',
|
|
220
|
+
description: 'Força paralelismo para velocidade máxima.',
|
|
221
|
+
policy,
|
|
222
|
+
executors,
|
|
223
|
+
consequences: [
|
|
224
|
+
'Aumenta velocidade em cenários favoráveis',
|
|
225
|
+
'Eleva superfície de risco e custo',
|
|
226
|
+
'Maior probabilidade de bloqueio em risco alto'
|
|
227
|
+
],
|
|
228
|
+
score
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
pickBest(paths) {
|
|
232
|
+
return paths.reduce((best, current) => {
|
|
233
|
+
if (current.score > best.score)
|
|
234
|
+
return current;
|
|
235
|
+
if (current.score < best.score)
|
|
236
|
+
return best;
|
|
237
|
+
const stabilityRank = {
|
|
238
|
+
conservative: 3,
|
|
239
|
+
balanced: 2,
|
|
240
|
+
aggressive: 1
|
|
241
|
+
};
|
|
242
|
+
return stabilityRank[current.id] > stabilityRank[best.id] ? current : best;
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
buildExecutiveSummary(selectedPath, risk, normalizedGoal) {
|
|
246
|
+
const goalHint = this.goalBias(normalizedGoal);
|
|
247
|
+
return `Rota escolhida: ${selectedPath.id}. Risk=${risk}. Viés do objetivo=${goalHint}. Consequências previstas: ${selectedPath.consequences.join(' | ')}`;
|
|
248
|
+
}
|
|
249
|
+
goalBias(normalizedGoal) {
|
|
250
|
+
const speedTokens = ['deploy', 'urgente', 'hotfix', 'incident', 'performance', 'rápido', 'rapido'];
|
|
251
|
+
const safetyTokens = ['prod', 'produção', 'producao', 'governança', 'governanca', 'compliance', 'security', 'segurança', 'seguranca'];
|
|
252
|
+
const speed = speedTokens.some((token) => normalizedGoal.includes(token));
|
|
253
|
+
const safety = safetyTokens.some((token) => normalizedGoal.includes(token));
|
|
254
|
+
if (speed && !safety)
|
|
255
|
+
return 'speed';
|
|
256
|
+
if (safety)
|
|
257
|
+
return 'safety';
|
|
258
|
+
return 'neutral';
|
|
259
|
+
}
|
|
260
|
+
scorePath(risk, policy, executors, normalizedGoal, conservative) {
|
|
261
|
+
let score = 0;
|
|
262
|
+
if (executors.length > 1)
|
|
263
|
+
score += 2;
|
|
264
|
+
if (policy.swarmMode === 'none')
|
|
265
|
+
score += 1;
|
|
266
|
+
if (policy.swarmMode === 'light')
|
|
267
|
+
score += 1;
|
|
268
|
+
if (policy.swarmMode === 'parallel')
|
|
269
|
+
score += 1;
|
|
270
|
+
if (policy.swarmMode === 'consensus')
|
|
271
|
+
score -= 1;
|
|
272
|
+
if (risk === 'high')
|
|
273
|
+
score += conservative ? 4 : -3;
|
|
274
|
+
if (risk === 'medium')
|
|
275
|
+
score += conservative ? 1 : 0;
|
|
276
|
+
if (risk === 'low')
|
|
277
|
+
score += conservative ? 0 : 2;
|
|
278
|
+
const bias = this.goalBias(normalizedGoal);
|
|
279
|
+
if (bias === 'speed' && !conservative)
|
|
280
|
+
score += 2;
|
|
281
|
+
if (bias === 'safety' && conservative)
|
|
282
|
+
score += 2;
|
|
283
|
+
return score;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
exports.ConsequenceForecaster = ConsequenceForecaster;
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CronManager — minimal 5-field cron scheduler.
|
|
4
|
+
*
|
|
5
|
+
* Story 5.1 — OpenLife v1.3 Agent OS Integration.
|
|
6
|
+
*
|
|
7
|
+
* 5-field cron syntax: `minute hour day-of-month month day-of-week`
|
|
8
|
+
* - * (any)
|
|
9
|
+
* - n (literal)
|
|
10
|
+
* - n-m (range)
|
|
11
|
+
* - n,m (list)
|
|
12
|
+
* - * /n (step)
|
|
13
|
+
*
|
|
14
|
+
* Storage: `.openlife/crons.json` (atomic via AtomicWriter).
|
|
15
|
+
*
|
|
16
|
+
* Lifecycle: jobs are persisted; start() polls every 30s (or
|
|
17
|
+
* tickIntervalMs) and fires any job whose due-time falls inside the
|
|
18
|
+
* last interval. Idempotent start/stop.
|
|
19
|
+
*
|
|
20
|
+
* The trigger payload is dispatched via an optional `executor` callback
|
|
21
|
+
* supplied at construction time. By default, the cron only logs the fire
|
|
22
|
+
* event to `.openlife/cron-events.jsonl` — operators can wire QueueScheduler
|
|
23
|
+
* or any other dispatcher.
|
|
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.CronManager = void 0;
|
|
60
|
+
exports.parseCronExpression = parseCronExpression;
|
|
61
|
+
exports.matchesCron = matchesCron;
|
|
62
|
+
const fs = __importStar(require("fs"));
|
|
63
|
+
const path = __importStar(require("path"));
|
|
64
|
+
const AtomicWriter_1 = require("./util/AtomicWriter");
|
|
65
|
+
const ToolsetGuard_1 = require("./toolset/ToolsetGuard");
|
|
66
|
+
class CronManager {
|
|
67
|
+
file;
|
|
68
|
+
eventsFile;
|
|
69
|
+
tickIntervalMs;
|
|
70
|
+
executor;
|
|
71
|
+
timer = null;
|
|
72
|
+
lastTickAt = 0;
|
|
73
|
+
constructor(opts = {}) {
|
|
74
|
+
const stateDir = opts.stateDir
|
|
75
|
+
|| process.env.OPENLIFE_STATE_DIR
|
|
76
|
+
|| path.join(process.cwd(), '.openlife');
|
|
77
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
78
|
+
this.file = path.join(stateDir, 'crons.json');
|
|
79
|
+
this.eventsFile = path.join(stateDir, 'cron-events.jsonl');
|
|
80
|
+
this.tickIntervalMs = opts.tickIntervalMs ?? 30000;
|
|
81
|
+
this.executor = opts.executor;
|
|
82
|
+
}
|
|
83
|
+
read() {
|
|
84
|
+
if (!fs.existsSync(this.file))
|
|
85
|
+
return [];
|
|
86
|
+
try {
|
|
87
|
+
return JSON.parse(fs.readFileSync(this.file, 'utf-8'));
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
write(jobs) {
|
|
94
|
+
(0, AtomicWriter_1.writeJsonAtomic)(this.file, jobs);
|
|
95
|
+
}
|
|
96
|
+
list() {
|
|
97
|
+
return this.read();
|
|
98
|
+
}
|
|
99
|
+
create(id, expression, payload = {}) {
|
|
100
|
+
(0, ToolsetGuard_1.assertToolsetAllowed)('cron', 'CronManager.create');
|
|
101
|
+
if (!/^[a-z0-9][a-z0-9._-]+$/i.test(id)) {
|
|
102
|
+
throw Object.assign(new Error('invalid_cron_id'), { code: 'invalid_cron_id' });
|
|
103
|
+
}
|
|
104
|
+
const validation = parseCronExpression(expression);
|
|
105
|
+
if (!validation.ok) {
|
|
106
|
+
throw Object.assign(new Error(`invalid_cron_expression:${validation.error}`), { code: 'invalid_cron_expression', detail: validation.error });
|
|
107
|
+
}
|
|
108
|
+
const jobs = this.read();
|
|
109
|
+
if (jobs.some((j) => j.id === id)) {
|
|
110
|
+
throw Object.assign(new Error('cron_already_exists'), { code: 'cron_already_exists' });
|
|
111
|
+
}
|
|
112
|
+
const job = {
|
|
113
|
+
id, expression, payload,
|
|
114
|
+
status: 'active',
|
|
115
|
+
createdAt: new Date().toISOString(),
|
|
116
|
+
};
|
|
117
|
+
jobs.push(job);
|
|
118
|
+
this.write(jobs);
|
|
119
|
+
return job;
|
|
120
|
+
}
|
|
121
|
+
remove(id) {
|
|
122
|
+
const jobs = this.read();
|
|
123
|
+
const filtered = jobs.filter((j) => j.id !== id);
|
|
124
|
+
if (filtered.length === jobs.length)
|
|
125
|
+
return false;
|
|
126
|
+
this.write(filtered);
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
pause(id) {
|
|
130
|
+
return this.setStatus(id, 'paused');
|
|
131
|
+
}
|
|
132
|
+
resume(id) {
|
|
133
|
+
return this.setStatus(id, 'active');
|
|
134
|
+
}
|
|
135
|
+
setStatus(id, status) {
|
|
136
|
+
const jobs = this.read();
|
|
137
|
+
const idx = jobs.findIndex((j) => j.id === id);
|
|
138
|
+
if (idx === -1)
|
|
139
|
+
return false;
|
|
140
|
+
jobs[idx].status = status;
|
|
141
|
+
this.write(jobs);
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
/** Manually fire a job (regardless of schedule). */
|
|
145
|
+
async runNow(id) {
|
|
146
|
+
const jobs = this.read();
|
|
147
|
+
const job = jobs.find((j) => j.id === id);
|
|
148
|
+
if (!job)
|
|
149
|
+
return { ok: false, error: 'not_found' };
|
|
150
|
+
await this.fire(job);
|
|
151
|
+
return { ok: true };
|
|
152
|
+
}
|
|
153
|
+
start() {
|
|
154
|
+
if (this.timer)
|
|
155
|
+
return;
|
|
156
|
+
this.lastTickAt = Date.now();
|
|
157
|
+
// Run an immediate tick to catch up, then schedule.
|
|
158
|
+
void this.tick();
|
|
159
|
+
this.timer = setInterval(() => { void this.tick(); }, this.tickIntervalMs);
|
|
160
|
+
if (this.timer.unref)
|
|
161
|
+
this.timer.unref();
|
|
162
|
+
}
|
|
163
|
+
stop() {
|
|
164
|
+
if (this.timer)
|
|
165
|
+
clearInterval(this.timer);
|
|
166
|
+
this.timer = null;
|
|
167
|
+
}
|
|
168
|
+
/** Run one tick — fire any active jobs whose due-time falls in the last interval. */
|
|
169
|
+
async tick(now = new Date()) {
|
|
170
|
+
const fired = [];
|
|
171
|
+
const jobs = this.read();
|
|
172
|
+
let mutated = false;
|
|
173
|
+
for (const job of jobs) {
|
|
174
|
+
if (job.status !== 'active')
|
|
175
|
+
continue;
|
|
176
|
+
const expr = parseCronExpression(job.expression);
|
|
177
|
+
if (!expr.ok || !expr.fields)
|
|
178
|
+
continue;
|
|
179
|
+
// Fire if the current minute matches the schedule AND we haven't
|
|
180
|
+
// already fired in this minute (idempotency vs short tick intervals).
|
|
181
|
+
if (!matchesCron(expr.fields, now))
|
|
182
|
+
continue;
|
|
183
|
+
const minuteKey = `${now.getFullYear()}-${now.getMonth()}-${now.getDate()}-${now.getHours()}-${now.getMinutes()}`;
|
|
184
|
+
const lastKey = job.lastFiredAt ? (() => {
|
|
185
|
+
const d = new Date(job.lastFiredAt);
|
|
186
|
+
return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}-${d.getHours()}-${d.getMinutes()}`;
|
|
187
|
+
})() : null;
|
|
188
|
+
if (minuteKey === lastKey)
|
|
189
|
+
continue;
|
|
190
|
+
job.lastFiredAt = now.toISOString();
|
|
191
|
+
mutated = true;
|
|
192
|
+
await this.fire(job);
|
|
193
|
+
fired.push(job.id);
|
|
194
|
+
}
|
|
195
|
+
if (mutated)
|
|
196
|
+
this.write(jobs);
|
|
197
|
+
return fired;
|
|
198
|
+
}
|
|
199
|
+
async fire(job) {
|
|
200
|
+
(0, AtomicWriter_1.appendJsonlAtomic)(this.eventsFile, {
|
|
201
|
+
at: new Date().toISOString(),
|
|
202
|
+
type: 'cron_fired',
|
|
203
|
+
id: job.id,
|
|
204
|
+
expression: job.expression,
|
|
205
|
+
});
|
|
206
|
+
if (this.executor) {
|
|
207
|
+
try {
|
|
208
|
+
await this.executor.execute(job);
|
|
209
|
+
}
|
|
210
|
+
catch (err) {
|
|
211
|
+
(0, AtomicWriter_1.appendJsonlAtomic)(this.eventsFile, {
|
|
212
|
+
at: new Date().toISOString(),
|
|
213
|
+
type: 'cron_executor_error',
|
|
214
|
+
id: job.id,
|
|
215
|
+
error: err instanceof Error ? err.message : String(err),
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
exports.CronManager = CronManager;
|
|
222
|
+
function parseCronExpression(expr) {
|
|
223
|
+
const parts = expr.trim().split(/\s+/);
|
|
224
|
+
if (parts.length !== 5) {
|
|
225
|
+
return { ok: false, error: 'expected_5_fields' };
|
|
226
|
+
}
|
|
227
|
+
try {
|
|
228
|
+
const fields = {
|
|
229
|
+
minutes: expandField(parts[0], 0, 59),
|
|
230
|
+
hours: expandField(parts[1], 0, 23),
|
|
231
|
+
daysOfMonth: expandField(parts[2], 1, 31),
|
|
232
|
+
months: expandField(parts[3], 1, 12),
|
|
233
|
+
daysOfWeek: expandField(parts[4], 0, 6),
|
|
234
|
+
};
|
|
235
|
+
return { ok: true, fields };
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
return { ok: false, error: err instanceof Error ? err.message : 'parse_error' };
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function expandField(field, min, max) {
|
|
242
|
+
const out = new Set();
|
|
243
|
+
for (const token of field.split(',')) {
|
|
244
|
+
let stride = 1;
|
|
245
|
+
let body = token;
|
|
246
|
+
const slashIdx = body.indexOf('/');
|
|
247
|
+
if (slashIdx >= 0) {
|
|
248
|
+
stride = parseInt(body.slice(slashIdx + 1), 10);
|
|
249
|
+
if (!Number.isFinite(stride) || stride <= 0)
|
|
250
|
+
throw new Error(`invalid_step:${field}`);
|
|
251
|
+
body = body.slice(0, slashIdx);
|
|
252
|
+
}
|
|
253
|
+
let lo;
|
|
254
|
+
let hi;
|
|
255
|
+
if (body === '*' || body === '') {
|
|
256
|
+
lo = min;
|
|
257
|
+
hi = max;
|
|
258
|
+
}
|
|
259
|
+
else if (body.includes('-')) {
|
|
260
|
+
const [a, b] = body.split('-').map((n) => parseInt(n, 10));
|
|
261
|
+
if (!Number.isFinite(a) || !Number.isFinite(b))
|
|
262
|
+
throw new Error(`invalid_range:${field}`);
|
|
263
|
+
lo = a;
|
|
264
|
+
hi = b;
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
const n = parseInt(body, 10);
|
|
268
|
+
if (!Number.isFinite(n))
|
|
269
|
+
throw new Error(`invalid_number:${field}`);
|
|
270
|
+
lo = n;
|
|
271
|
+
hi = n;
|
|
272
|
+
}
|
|
273
|
+
if (lo < min || hi > max || lo > hi)
|
|
274
|
+
throw new Error(`out_of_range:${field}`);
|
|
275
|
+
for (let v = lo; v <= hi; v += stride)
|
|
276
|
+
out.add(v);
|
|
277
|
+
}
|
|
278
|
+
return out;
|
|
279
|
+
}
|
|
280
|
+
function matchesCron(fields, d) {
|
|
281
|
+
return (fields.minutes.has(d.getMinutes())
|
|
282
|
+
&& fields.hours.has(d.getHours())
|
|
283
|
+
&& fields.daysOfMonth.has(d.getDate())
|
|
284
|
+
&& fields.months.has(d.getMonth() + 1)
|
|
285
|
+
&& fields.daysOfWeek.has(d.getDay()));
|
|
286
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DynamicAgentBuilder = void 0;
|
|
4
|
+
class DynamicAgentBuilder {
|
|
5
|
+
brain;
|
|
6
|
+
constructor(brain) {
|
|
7
|
+
this.brain = brain;
|
|
8
|
+
}
|
|
9
|
+
async propose(goal, existingAgents) {
|
|
10
|
+
const prompt = `
|
|
11
|
+
Você é o DynamicAgentBuilder do OpenLife.
|
|
12
|
+
|
|
13
|
+
Objetivo:
|
|
14
|
+
${goal}
|
|
15
|
+
|
|
16
|
+
Agentes já disponíveis:
|
|
17
|
+
${existingAgents.map(a => `${a.id} -> ${a.role}`).join('\n')}
|
|
18
|
+
|
|
19
|
+
Decida se falta um agente temporário especializado.
|
|
20
|
+
Se sim, responda em JSON com:
|
|
21
|
+
- id
|
|
22
|
+
- name
|
|
23
|
+
- role
|
|
24
|
+
- capabilities (array)
|
|
25
|
+
- temporary: true
|
|
26
|
+
|
|
27
|
+
Se não precisar, responda {"temporary": false}.
|
|
28
|
+
`;
|
|
29
|
+
const raw = await this.brain.think('Decida se vale criar um agente temporário especializado.', prompt);
|
|
30
|
+
try {
|
|
31
|
+
const jsonStart = raw.indexOf('{');
|
|
32
|
+
const parsed = JSON.parse(jsonStart >= 0 ? raw.slice(jsonStart) : raw);
|
|
33
|
+
if (!parsed.temporary)
|
|
34
|
+
return null;
|
|
35
|
+
return {
|
|
36
|
+
id: parsed.id || `dynamic-agent-${Date.now()}`,
|
|
37
|
+
name: parsed.name || 'Dynamic Specialist',
|
|
38
|
+
role: parsed.role || 'specialist',
|
|
39
|
+
capabilities: Array.isArray(parsed.capabilities) ? parsed.capabilities : ['specialized-task'],
|
|
40
|
+
temporary: true
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.DynamicAgentBuilder = DynamicAgentBuilder;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DynamicAgentExecutor = void 0;
|
|
4
|
+
class DynamicAgentExecutor {
|
|
5
|
+
taskExecutor;
|
|
6
|
+
constructor(taskExecutor) {
|
|
7
|
+
this.taskExecutor = taskExecutor;
|
|
8
|
+
}
|
|
9
|
+
async execute(agent, goal, taskId) {
|
|
10
|
+
const prompt = `[Agente Dinâmico]\n${agent.name} (${agent.role})\n\n[Capabilities]\n${agent.capabilities.join(', ')}\n\n[Objetivo]\n${goal}`;
|
|
11
|
+
const result = await this.taskExecutor.execute('codex', prompt, `${taskId}_dynamic_${agent.id}`);
|
|
12
|
+
return result.stdout || result.stderr || '';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.DynamicAgentExecutor = DynamicAgentExecutor;
|