@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,112 @@
|
|
|
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
|
+
const http = __importStar(require("http"));
|
|
37
|
+
const PORT = 3098;
|
|
38
|
+
process.env.PORT = String(PORT);
|
|
39
|
+
process.env.TELEGRAM_BOT_TOKEN = '';
|
|
40
|
+
async function post(pathStr, body, headers = {}) {
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
const payload = JSON.stringify(body);
|
|
43
|
+
const req = http.request({
|
|
44
|
+
host: '127.0.0.1',
|
|
45
|
+
port: PORT,
|
|
46
|
+
path: pathStr,
|
|
47
|
+
method: 'POST',
|
|
48
|
+
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload), ...headers },
|
|
49
|
+
timeout: 5000
|
|
50
|
+
}, (res) => {
|
|
51
|
+
let chunks = '';
|
|
52
|
+
res.on('data', (d) => { chunks += d; });
|
|
53
|
+
res.on('end', () => resolve({ status: res.statusCode || 0, body: chunks }));
|
|
54
|
+
});
|
|
55
|
+
req.on('error', reject);
|
|
56
|
+
req.on('timeout', () => { req.destroy(); reject(new Error('timeout')); });
|
|
57
|
+
req.write(payload);
|
|
58
|
+
req.end();
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function basicAuthHeader(user, pass) {
|
|
62
|
+
return 'Basic ' + Buffer.from(`${user}:${pass}`).toString('base64');
|
|
63
|
+
}
|
|
64
|
+
async function bootGateway() {
|
|
65
|
+
const { Gateway } = require('./orchestrator/Gateway');
|
|
66
|
+
const gateway = new Gateway();
|
|
67
|
+
gateway.start();
|
|
68
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
69
|
+
return gateway;
|
|
70
|
+
}
|
|
71
|
+
async function caseAuthEnabled() {
|
|
72
|
+
process.env.OPENLIFE_TRIGGER_USER = 'webhook-user';
|
|
73
|
+
process.env.OPENLIFE_TRIGGER_PASS = 'webhook-pass';
|
|
74
|
+
const gateway = await bootGateway();
|
|
75
|
+
try {
|
|
76
|
+
const noAuth = await post('/api/v1/trigger', { text: 'ping' });
|
|
77
|
+
if (noAuth.status !== 401)
|
|
78
|
+
throw new Error(`AUTH_ENABLED_BUT_NO_AUTH_REQUEST_GOT_${noAuth.status}: ${noAuth.body}`);
|
|
79
|
+
const wrongPass = await post('/api/v1/trigger', { text: 'ping' }, { Authorization: basicAuthHeader('webhook-user', 'wrong') });
|
|
80
|
+
if (wrongPass.status !== 403)
|
|
81
|
+
throw new Error(`WRONG_CREDS_GOT_${wrongPass.status}: ${wrongPass.body}`);
|
|
82
|
+
const goodAuth = await post('/api/v1/trigger', { text: 'ping smoke' }, { Authorization: basicAuthHeader('webhook-user', 'webhook-pass') });
|
|
83
|
+
if (goodAuth.status !== 200 && goodAuth.status !== 500) {
|
|
84
|
+
throw new Error(`VALID_CREDS_GOT_${goodAuth.status} (expected 200 or 500-when-no-LLM): ${goodAuth.body}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
await gateway.shutdown('TEST_AUTH_ENABLED');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function caseAuthDisabled() {
|
|
92
|
+
delete process.env.OPENLIFE_TRIGGER_USER;
|
|
93
|
+
delete process.env.OPENLIFE_TRIGGER_PASS;
|
|
94
|
+
const gateway = await bootGateway();
|
|
95
|
+
try {
|
|
96
|
+
const r = await post('/api/v1/trigger', { text: 'ping unauth' });
|
|
97
|
+
if (r.status === 401 || r.status === 403)
|
|
98
|
+
throw new Error(`UNAUTHED_MODE_REJECTED_${r.status}: ${r.body}`);
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
await gateway.shutdown('TEST_AUTH_DISABLED');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function main() {
|
|
105
|
+
await caseAuthEnabled();
|
|
106
|
+
await caseAuthDisabled();
|
|
107
|
+
console.log('TEST_TRIGGER_BASIC_AUTH_OK');
|
|
108
|
+
}
|
|
109
|
+
main().catch((err) => {
|
|
110
|
+
console.error('TEST_TRIGGER_BASIC_AUTH_FAIL:', err?.message || err);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
});
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* doc_parity.ts — Story 7.2
|
|
4
|
+
*
|
|
5
|
+
* Reusable helpers for "documentation makes a claim about CLI surface — is it
|
|
6
|
+
* still true?" tests. Used by:
|
|
7
|
+
* - test_cli_doc_parity.ts (root help vs README quick-start)
|
|
8
|
+
* - test_multi_host_docs_parity.ts (per-host install docs vs CLI)
|
|
9
|
+
* - test_aiobuilder_cli_parity.ts (squad doc verbs vs aiobuilder sub-commands)
|
|
10
|
+
*
|
|
11
|
+
* Each helper is intentionally tiny. The goal is fewer copy-pasted regex
|
|
12
|
+
* loops across parity tests, not an inheritance hierarchy.
|
|
13
|
+
*/
|
|
14
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(o, k2, desc);
|
|
21
|
+
}) : (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
o[k2] = m[k];
|
|
24
|
+
}));
|
|
25
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
+
}) : function(o, v) {
|
|
28
|
+
o["default"] = v;
|
|
29
|
+
});
|
|
30
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
+
var ownKeys = function(o) {
|
|
32
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
+
var ar = [];
|
|
34
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
+
return ar;
|
|
36
|
+
};
|
|
37
|
+
return ownKeys(o);
|
|
38
|
+
};
|
|
39
|
+
return function (mod) {
|
|
40
|
+
if (mod && mod.__esModule) return mod;
|
|
41
|
+
var result = {};
|
|
42
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
+
__setModuleDefault(result, mod);
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.spawnCliHelp = spawnCliHelp;
|
|
49
|
+
exports.extractCommanderCommands = extractCommanderCommands;
|
|
50
|
+
exports.extractDocTokens = extractDocTokens;
|
|
51
|
+
exports.assertCliParity = assertCliParity;
|
|
52
|
+
const child_process_1 = require("child_process");
|
|
53
|
+
const fs = __importStar(require("fs"));
|
|
54
|
+
const path = __importStar(require("path"));
|
|
55
|
+
const CLI = path.join(process.cwd(), 'dist', 'index.js');
|
|
56
|
+
/** Spawn `node bin/openlife.js <args> --help` and return the merged stdout/stderr. */
|
|
57
|
+
function spawnCliHelp(args = [], timeoutMs = 20000) {
|
|
58
|
+
const r = (0, child_process_1.spawnSync)('node', [CLI, ...args, '--help'], { encoding: 'utf-8', timeout: timeoutMs });
|
|
59
|
+
return { ok: r.status === 0, status: r.status, help: (r.stdout || '') + (r.stderr || '') };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Extract Commander sub-command names from a help block.
|
|
63
|
+
* Commander prints each sub-command starting at column 2: " <name> [options]...".
|
|
64
|
+
*/
|
|
65
|
+
function extractCommanderCommands(helpText) {
|
|
66
|
+
const out = new Set();
|
|
67
|
+
const lines = helpText.split('\n');
|
|
68
|
+
let inCommands = false;
|
|
69
|
+
for (const line of lines) {
|
|
70
|
+
if (/^Commands:/.test(line)) {
|
|
71
|
+
inCommands = true;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (!inCommands)
|
|
75
|
+
continue;
|
|
76
|
+
const m = line.match(/^\s{2}([a-z][\w-]*)/);
|
|
77
|
+
if (m)
|
|
78
|
+
out.add(m[1]);
|
|
79
|
+
}
|
|
80
|
+
return out;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Read a doc file and extract every token matching `re` (must have one capture group).
|
|
84
|
+
* Returns a sorted, de-duplicated list. Throws if the file does not exist.
|
|
85
|
+
*/
|
|
86
|
+
function extractDocTokens(docPath, re) {
|
|
87
|
+
if (!fs.existsSync(docPath)) {
|
|
88
|
+
throw new Error(`DOC_NOT_FOUND: ${docPath}`);
|
|
89
|
+
}
|
|
90
|
+
const content = fs.readFileSync(docPath, 'utf-8');
|
|
91
|
+
const tokens = new Set();
|
|
92
|
+
// Use matchAll to avoid stateful regex iteration.
|
|
93
|
+
const reGlobal = new RegExp(re.source, re.flags.includes('g') ? re.flags : re.flags + 'g');
|
|
94
|
+
for (const m of content.matchAll(reGlobal)) {
|
|
95
|
+
if (m[1])
|
|
96
|
+
tokens.add(m[1]);
|
|
97
|
+
}
|
|
98
|
+
return Array.from(tokens).sort();
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Assert every doc token corresponds to a CLI command (direct or via alias map).
|
|
102
|
+
* Returns a verdict object — callers decide whether to throw, log, or annotate.
|
|
103
|
+
*/
|
|
104
|
+
function assertCliParity(docTokens, cliCommands, aliasMap = {}) {
|
|
105
|
+
const matched = [];
|
|
106
|
+
const missing = [];
|
|
107
|
+
for (const tok of docTokens) {
|
|
108
|
+
if (cliCommands.has(tok)) {
|
|
109
|
+
matched.push({ token: tok, via: tok });
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const alias = aliasMap[tok];
|
|
113
|
+
if (alias && cliCommands.has(alias)) {
|
|
114
|
+
matched.push({ token: tok, via: `${alias} (alias)` });
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
missing.push(tok);
|
|
118
|
+
}
|
|
119
|
+
return { ok: missing.length === 0, matched, missing, total: docTokens.length };
|
|
120
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* test_v15_e2e_integration.ts — Story 17.1 (v1.5)
|
|
4
|
+
*
|
|
5
|
+
* Walks every v1.5 surface in sequence from a tmp workspace, asserting
|
|
6
|
+
* that the cross-feature interactions hold:
|
|
7
|
+
*
|
|
8
|
+
* 1. Seed a Squad via SquadCreator.create.
|
|
9
|
+
* 2. Run a synthetic mission and persist a MissionState.
|
|
10
|
+
* 3. Trigger the post-mission evaluation hook (Story 13.1) directly
|
|
11
|
+
* via OrchestrationLoop.prototype.evaluateMission, stubbing Brain
|
|
12
|
+
* so the test stays offline. Expect a `.openlife/evaluations/<id>.json`
|
|
13
|
+
* with source='brain'.
|
|
14
|
+
* 4. `eval list` (Story 13.2) via the MissionEvaluationStore.list()
|
|
15
|
+
* surface — filters by verdict.
|
|
16
|
+
* 5. Squad migrate + extend + publish (v1.4 Stories 11.1–11.3).
|
|
17
|
+
* 6. Publish to remote via stubbed RemotePublisher (Story 14.1).
|
|
18
|
+
* 7. Governance evaluate writes to the scope ledger (Story 14.2);
|
|
19
|
+
* verify() walks the chain clean.
|
|
20
|
+
*
|
|
21
|
+
* No network. No filesystem outside the tmp workspace. Every Brain /
|
|
22
|
+
* RemotePublisher call is module-cache-stubbed.
|
|
23
|
+
*/
|
|
24
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
27
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
28
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
29
|
+
}
|
|
30
|
+
Object.defineProperty(o, k2, desc);
|
|
31
|
+
}) : (function(o, m, k, k2) {
|
|
32
|
+
if (k2 === undefined) k2 = k;
|
|
33
|
+
o[k2] = m[k];
|
|
34
|
+
}));
|
|
35
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
36
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
37
|
+
}) : function(o, v) {
|
|
38
|
+
o["default"] = v;
|
|
39
|
+
});
|
|
40
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
41
|
+
var ownKeys = function(o) {
|
|
42
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
43
|
+
var ar = [];
|
|
44
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
45
|
+
return ar;
|
|
46
|
+
};
|
|
47
|
+
return ownKeys(o);
|
|
48
|
+
};
|
|
49
|
+
return function (mod) {
|
|
50
|
+
if (mod && mod.__esModule) return mod;
|
|
51
|
+
var result = {};
|
|
52
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
53
|
+
__setModuleDefault(result, mod);
|
|
54
|
+
return result;
|
|
55
|
+
};
|
|
56
|
+
})();
|
|
57
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
|
+
const fs = __importStar(require("fs"));
|
|
59
|
+
const os = __importStar(require("os"));
|
|
60
|
+
const path = __importStar(require("path"));
|
|
61
|
+
function assertTrue(cond, label) {
|
|
62
|
+
if (!cond)
|
|
63
|
+
throw new Error(`ASSERT_FAILED[${label}]`);
|
|
64
|
+
}
|
|
65
|
+
function stubModule(modulePath, exports) {
|
|
66
|
+
const resolved = require.resolve(modulePath);
|
|
67
|
+
const orig = require.cache[resolved];
|
|
68
|
+
require.cache[resolved] = { ...orig, exports };
|
|
69
|
+
return () => {
|
|
70
|
+
if (orig)
|
|
71
|
+
require.cache[resolved] = orig;
|
|
72
|
+
else
|
|
73
|
+
delete require.cache[resolved];
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async function main() {
|
|
77
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'v15-e2e-'));
|
|
78
|
+
process.env.OPENLIFE_STATE_DIR = path.join(tmp, '.openlife');
|
|
79
|
+
delete process.env.OPENAI_API_KEY;
|
|
80
|
+
delete process.env.ANTHROPIC_API_KEY;
|
|
81
|
+
delete process.env.GEMINI_API_KEY;
|
|
82
|
+
delete process.env.OPENROUTER_API_KEY;
|
|
83
|
+
delete process.env.OLLAMA_URL;
|
|
84
|
+
delete process.env.OPENLIFE_GOVERNANCE_LEDGER;
|
|
85
|
+
try {
|
|
86
|
+
const SQUAD_TEMPLATE = path.resolve(__dirname, '..', 'dist-templates', 'squad-template');
|
|
87
|
+
const { SquadCreator } = require('./orchestrator/SquadCreator');
|
|
88
|
+
const sc = new SquadCreator({
|
|
89
|
+
catalogRoot: path.join(tmp, '.catalog', 'squads'),
|
|
90
|
+
templateRoot: SQUAD_TEMPLATE,
|
|
91
|
+
});
|
|
92
|
+
// ── Step 1: seed a squad ─────────────────────────────────────────
|
|
93
|
+
const seed = sc.create({
|
|
94
|
+
id: 'e2e-squad',
|
|
95
|
+
name: 'E2E Squad',
|
|
96
|
+
description: 'integration target',
|
|
97
|
+
version: '0.1.0',
|
|
98
|
+
status: 'draft',
|
|
99
|
+
agents: [{ id: 'lead', name: 'Lead', role: 'lead' }],
|
|
100
|
+
});
|
|
101
|
+
assertTrue(seed.ok, '[17.1] seed squad created');
|
|
102
|
+
console.log('[17.1] step 1: seed squad ✓');
|
|
103
|
+
// ── Step 2: persist a synthetic mission ──────────────────────────
|
|
104
|
+
const { MissionStateStore } = require('./orchestrator/MissionState');
|
|
105
|
+
const missionStore = new MissionStateStore();
|
|
106
|
+
const missionId = 'mission-e2e';
|
|
107
|
+
const mission = {
|
|
108
|
+
taskId: missionId,
|
|
109
|
+
userId: 'cli',
|
|
110
|
+
goal: 'audit the access ledger',
|
|
111
|
+
mode: 'task',
|
|
112
|
+
status: 'success',
|
|
113
|
+
plan: ['gather sources', 'cross-reference'],
|
|
114
|
+
successCriteria: ['evidence found', 'no gaps'],
|
|
115
|
+
reviewFindings: [{ approved: true, critique: 'looks good' }],
|
|
116
|
+
attempts: [],
|
|
117
|
+
chosenAgents: [],
|
|
118
|
+
chosenSquads: [],
|
|
119
|
+
chosenSkills: [],
|
|
120
|
+
routeMode: 'single',
|
|
121
|
+
memoryCandidates: [],
|
|
122
|
+
artifacts: [],
|
|
123
|
+
governanceEvents: [],
|
|
124
|
+
consequenceThoughtTrace: { snapshots: [{ note: 'analysed' }] },
|
|
125
|
+
createdAt: new Date().toISOString(),
|
|
126
|
+
updatedAt: new Date().toISOString(),
|
|
127
|
+
};
|
|
128
|
+
missionStore.persist(mission);
|
|
129
|
+
console.log('[17.1] step 2: mission persisted ✓');
|
|
130
|
+
// ── Step 3: stubbed Brain → evaluation lands as source=brain ────
|
|
131
|
+
const restoreBrain = stubModule('./orchestrator/Brain', {
|
|
132
|
+
Brain: class {
|
|
133
|
+
isAnyProviderAvailable() { return true; }
|
|
134
|
+
async think() {
|
|
135
|
+
return '{"score":91,"verdict":"ready_for_review","risks":["watch the redactor"],"rationale":"all criteria met"}';
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
try {
|
|
140
|
+
const { OrchestrationLoop } = require('./orchestrator/OrchestrationLoop');
|
|
141
|
+
const evaluateMission = OrchestrationLoop.prototype.evaluateMission;
|
|
142
|
+
const parseEvalJson = OrchestrationLoop.prototype.parseEvaluationJson;
|
|
143
|
+
await evaluateMission.call({ parseEvaluationJson: parseEvalJson }, mission);
|
|
144
|
+
const { MissionEvaluationStore } = require('./orchestrator/EnterpriseAgenticCore');
|
|
145
|
+
const evals = new MissionEvaluationStore().list();
|
|
146
|
+
assertTrue(evals.length === 1, '[17.1] one evaluation persisted');
|
|
147
|
+
assertTrue(evals[0].source === 'brain', '[17.1] source=brain landed');
|
|
148
|
+
assertTrue(evals[0].score === 91 && evals[0].verdict === 'ready_for_review', '[17.1] brain verdict landed');
|
|
149
|
+
console.log('[17.1] step 3: brain-driven evaluation persisted ✓');
|
|
150
|
+
// ── Step 4: eval list filter (Story 13.2) ──────────────────────
|
|
151
|
+
const readyFiltered = evals.filter((e) => e.verdict === 'ready_for_review');
|
|
152
|
+
assertTrue(readyFiltered.length === 1, '[17.1] eval list filter by verdict');
|
|
153
|
+
console.log('[17.1] step 4: eval list filter ✓');
|
|
154
|
+
}
|
|
155
|
+
finally {
|
|
156
|
+
restoreBrain();
|
|
157
|
+
}
|
|
158
|
+
// ── Step 5: squad migrate + extend + publish (v1.4 lifecycle) ────
|
|
159
|
+
const mig = sc.migrate('e2e-squad', '0.1.0', '1.0.0');
|
|
160
|
+
assertTrue(mig.ok, '[17.1] migrate ok');
|
|
161
|
+
const ext = sc.extend('e2e-squad', { kind: 'task', spec: { id: 'review', ownerAgentId: 'lead', purpose: 'gate' } });
|
|
162
|
+
assertTrue(ext.ok && ext.filesAdded?.length === 1, '[17.1] extend ok');
|
|
163
|
+
const pub = sc.publish('e2e-squad');
|
|
164
|
+
assertTrue(pub.ok && !!pub.sha256, '[17.1] local publish ok');
|
|
165
|
+
console.log('[17.1] step 5: squad migrate+extend+publish ✓');
|
|
166
|
+
// ── Step 6: remote publish via stubbed RemotePublisher ───────────
|
|
167
|
+
let remoteCalls = 0;
|
|
168
|
+
const restoreRemote = stubModule('./orchestrator/RemotePublisher', {
|
|
169
|
+
RemotePublisher: class {
|
|
170
|
+
async publishAsset(kind, id, sha256) {
|
|
171
|
+
remoteCalls += 1;
|
|
172
|
+
return { ok: true, url: `https://stub.example/${kind}/${id}/${sha256}.md`, status: 201 };
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
try {
|
|
177
|
+
const composed = await sc.publishWithRemote('e2e-squad');
|
|
178
|
+
assertTrue(composed.ok && composed.remote?.ok, '[17.1] composed publishWithRemote ok');
|
|
179
|
+
assertTrue(remoteCalls === 1, `[17.1] RemotePublisher invoked exactly once (got ${remoteCalls})`);
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
restoreRemote();
|
|
183
|
+
}
|
|
184
|
+
console.log('[17.1] step 6: remote publish composes with local ✓');
|
|
185
|
+
// ── Step 7: governance scope ledger (Story 14.2) ─────────────────
|
|
186
|
+
const { GovernanceLayer } = require('./orchestrator/GovernanceLayer');
|
|
187
|
+
const layer = new GovernanceLayer();
|
|
188
|
+
layer.evaluate('refactor the auth flow', 'e2e-project');
|
|
189
|
+
layer.evaluate('audit the access ledger', 'e2e-project');
|
|
190
|
+
const { GovernanceScopeLedger } = require('./orchestrator/GovernanceScopeLedger');
|
|
191
|
+
const ledger = new GovernanceScopeLedger();
|
|
192
|
+
const entries = ledger.read();
|
|
193
|
+
assertTrue(entries.length === 2, `[17.1] ledger has 2 entries (got ${entries.length})`);
|
|
194
|
+
const v = ledger.verify();
|
|
195
|
+
assertTrue(v.ok && v.entries === 2, '[17.1] ledger chain verifies');
|
|
196
|
+
console.log('[17.1] step 7: governance scope ledger verifies ✓');
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
delete process.env.OPENLIFE_STATE_DIR;
|
|
200
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
201
|
+
}
|
|
202
|
+
console.log('TEST_V15_E2E_INTEGRATION_OK');
|
|
203
|
+
}
|
|
204
|
+
main().catch((err) => {
|
|
205
|
+
console.error('[v15-e2e-integration] FAILED:', err instanceof Error ? err.message : err);
|
|
206
|
+
process.exit(1);
|
|
207
|
+
});
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* test_watchdog_heartbeat — Story 6.6 regression suite.
|
|
4
|
+
*
|
|
5
|
+
* Three scenarios:
|
|
6
|
+
* 1. start() emits immediately and writes a fresh heartbeat file
|
|
7
|
+
* 2. periodic emission updates `ts` after intervalMs elapses
|
|
8
|
+
* 3. stop() halts emission; subsequent file mtime stays frozen
|
|
9
|
+
*
|
|
10
|
+
* Prints TEST_WATCHDOG_HEARTBEAT_OK on full pass.
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const os = __importStar(require("os"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const WatchdogHeartbeat_1 = require("./orchestrator/util/WatchdogHeartbeat");
|
|
50
|
+
function assert(cond, msg) {
|
|
51
|
+
if (!cond)
|
|
52
|
+
throw new Error(`assertion failed: ${msg}`);
|
|
53
|
+
}
|
|
54
|
+
function mkTmp() {
|
|
55
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), 'wd-test-'));
|
|
56
|
+
}
|
|
57
|
+
function rmTmp(dir) {
|
|
58
|
+
try {
|
|
59
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
60
|
+
}
|
|
61
|
+
catch { /* ignore */ }
|
|
62
|
+
}
|
|
63
|
+
function read(filePath) {
|
|
64
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
65
|
+
}
|
|
66
|
+
function sleep(ms) {
|
|
67
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
68
|
+
}
|
|
69
|
+
// ─────────────────────────────────────────────────────────────
|
|
70
|
+
// Scenario 1 — start() emits immediately
|
|
71
|
+
// ─────────────────────────────────────────────────────────────
|
|
72
|
+
function scenarioStartImmediate() {
|
|
73
|
+
const tmp = mkTmp();
|
|
74
|
+
const filePath = path.join(tmp, 'heartbeat.json');
|
|
75
|
+
try {
|
|
76
|
+
const wd = new WatchdogHeartbeat_1.WatchdogHeartbeat({ filePath, intervalMs: 100_000, version: '1.2.0' });
|
|
77
|
+
wd.start();
|
|
78
|
+
assert(fs.existsSync(filePath), 'heartbeat file must exist immediately after start()');
|
|
79
|
+
const rec = read(filePath);
|
|
80
|
+
assert(rec.pid === process.pid, 'pid round-trip');
|
|
81
|
+
assert(typeof rec.ts === 'number' && rec.ts > 0, 'ts must be a positive ms epoch');
|
|
82
|
+
assert(rec.uptime_s >= 0, 'uptime_s must be non-negative');
|
|
83
|
+
assert(rec.version === '1.2.0', 'version round-trip');
|
|
84
|
+
wd.stop();
|
|
85
|
+
console.log('✅ scenario 1: start() emits immediately');
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
rmTmp(tmp);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// ─────────────────────────────────────────────────────────────
|
|
92
|
+
// Scenario 2 — periodic emission updates ts
|
|
93
|
+
// ─────────────────────────────────────────────────────────────
|
|
94
|
+
async function scenarioPeriodicEmission() {
|
|
95
|
+
const tmp = mkTmp();
|
|
96
|
+
const filePath = path.join(tmp, 'heartbeat.json');
|
|
97
|
+
try {
|
|
98
|
+
const wd = new WatchdogHeartbeat_1.WatchdogHeartbeat({ filePath, intervalMs: 50 });
|
|
99
|
+
wd.start();
|
|
100
|
+
const firstTs = read(filePath).ts;
|
|
101
|
+
await sleep(180); // wait ~3 intervals
|
|
102
|
+
const laterTs = read(filePath).ts;
|
|
103
|
+
assert(laterTs > firstTs, `ts must advance after interval: first=${firstTs}, later=${laterTs}`);
|
|
104
|
+
wd.stop();
|
|
105
|
+
console.log('✅ scenario 2: periodic emission updates ts');
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
rmTmp(tmp);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// ─────────────────────────────────────────────────────────────
|
|
112
|
+
// Scenario 3 — stop() halts emission
|
|
113
|
+
// ─────────────────────────────────────────────────────────────
|
|
114
|
+
async function scenarioStopHalts() {
|
|
115
|
+
const tmp = mkTmp();
|
|
116
|
+
const filePath = path.join(tmp, 'heartbeat.json');
|
|
117
|
+
try {
|
|
118
|
+
const wd = new WatchdogHeartbeat_1.WatchdogHeartbeat({ filePath, intervalMs: 50 });
|
|
119
|
+
wd.start();
|
|
120
|
+
await sleep(70);
|
|
121
|
+
const beforeStop = read(filePath).ts;
|
|
122
|
+
wd.stop();
|
|
123
|
+
await sleep(150); // would be 3 more intervals if still running
|
|
124
|
+
const afterStop = read(filePath).ts;
|
|
125
|
+
assert(afterStop === beforeStop, `ts must not change after stop(): before=${beforeStop}, after=${afterStop}`);
|
|
126
|
+
// Idempotent stop
|
|
127
|
+
wd.stop();
|
|
128
|
+
// Manual emit after stop still works (graceful-shutdown final beat use case)
|
|
129
|
+
wd.emit();
|
|
130
|
+
const manual = read(filePath).ts;
|
|
131
|
+
assert(manual >= afterStop, 'manual emit() after stop must succeed');
|
|
132
|
+
console.log('✅ scenario 3: stop() halts emission, emit() still callable');
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
rmTmp(tmp);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// ─────────────────────────────────────────────────────────────
|
|
139
|
+
// Driver
|
|
140
|
+
// ─────────────────────────────────────────────────────────────
|
|
141
|
+
async function main() {
|
|
142
|
+
console.log('🧪 test_watchdog_heartbeat — Story 6.6 regression suite');
|
|
143
|
+
scenarioStartImmediate();
|
|
144
|
+
await scenarioPeriodicEmission();
|
|
145
|
+
await scenarioStopHalts();
|
|
146
|
+
console.log('');
|
|
147
|
+
console.log('TEST_WATCHDOG_HEARTBEAT_OK');
|
|
148
|
+
}
|
|
149
|
+
main().catch((err) => {
|
|
150
|
+
console.error('❌ test_watchdog_heartbeat FAILED:', err instanceof Error ? err.message : err);
|
|
151
|
+
process.exit(1);
|
|
152
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* test_workflow_condition_parser.ts — Story 10.3
|
|
4
|
+
*
|
|
5
|
+
* Asserts the AND / OR / NOT / == / != boolean expression parser
|
|
6
|
+
* and its backward-compat with v1.2/v1.3 bare-identifier semantics.
|
|
7
|
+
*
|
|
8
|
+
* 10 scenarios.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
const ConditionParser_1 = require("./orchestrator/workflow/ConditionParser");
|
|
12
|
+
function assertTrue(cond, label) {
|
|
13
|
+
if (!cond)
|
|
14
|
+
throw new Error(`ASSERT_FAILED[${label}]`);
|
|
15
|
+
}
|
|
16
|
+
// 1. Backward-compat: bare identifier
|
|
17
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('user_wants_ai', { user_wants_ai: true }) === true, '1: bare identifier truthy');
|
|
18
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('user_wants_ai', { user_wants_ai: false }) === false, '1b: bare identifier false');
|
|
19
|
+
console.log('[10.3] scenario 1 (bare identifier) ✓');
|
|
20
|
+
// 2. AND
|
|
21
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('a AND b', { a: true, b: true }) === true, '2a: a=t & b=t');
|
|
22
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('a AND b', { a: true, b: false }) === false, '2b: a=t & b=f');
|
|
23
|
+
console.log('[10.3] scenario 2 (AND) ✓');
|
|
24
|
+
// 3. OR
|
|
25
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('a OR b', { a: false, b: true }) === true, '3a: a=f | b=t');
|
|
26
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('a OR b', { a: false, b: false }) === false, '3b: a=f | b=f');
|
|
27
|
+
console.log('[10.3] scenario 3 (OR) ✓');
|
|
28
|
+
// 4. NOT
|
|
29
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('NOT a', { a: false }) === true, '4a: !false');
|
|
30
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('NOT a', { a: true }) === false, '4b: !true');
|
|
31
|
+
console.log('[10.3] scenario 4 (NOT) ✓');
|
|
32
|
+
// 5. Equality with string literal
|
|
33
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('mode == "elite"', { mode: 'elite' }) === true, '5: mode == elite');
|
|
34
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('mode == "elite"', { mode: 'quick' }) === false, '5b: mode != elite');
|
|
35
|
+
console.log('[10.3] scenario 5 (== string) ✓');
|
|
36
|
+
// 6. Inequality with number
|
|
37
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('score != 0', { score: 5 }) === true, '6: score != 0');
|
|
38
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('score != 0', { score: 0 }) === false, '6b: score == 0');
|
|
39
|
+
console.log('[10.3] scenario 6 (!= number) ✓');
|
|
40
|
+
// 7. Parentheses + precedence
|
|
41
|
+
// (a OR b) AND NOT c
|
|
42
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('(a OR b) AND NOT c', { a: true, b: false, c: false }) === true, '7: precedence');
|
|
43
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('(a OR b) AND NOT c', { a: true, b: false, c: true }) === false, '7b: precedence c=t');
|
|
44
|
+
console.log('[10.3] scenario 7 (parentheses + precedence) ✓');
|
|
45
|
+
// 8. Nested object access via dot
|
|
46
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('user.is_admin', { user: { is_admin: true } }) === true, '8: nested truthy');
|
|
47
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('user.role == "owner"', { user: { role: 'owner' } }) === true, '8b: nested ==');
|
|
48
|
+
console.log('[10.3] scenario 8 (dotted identifier) ✓');
|
|
49
|
+
// 9. Unknown variable defaults to false
|
|
50
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('never_set', {}) === false, '9: unknown ident → false');
|
|
51
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('a OR never_set', { a: true }) === true, '9b: unknown in OR');
|
|
52
|
+
console.log('[10.3] scenario 9 (unknown var) ✓');
|
|
53
|
+
// 10. Empty/invalid expressions
|
|
54
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('', {}) === true, '10a: empty → true (no condition)');
|
|
55
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)(undefined, {}) === true, '10b: undefined → true');
|
|
56
|
+
assertTrue((0, ConditionParser_1.evaluateCondition)('(((unbalanced', {}) === false, '10c: parse failure → false');
|
|
57
|
+
console.log('[10.3] scenario 10 (empty + invalid) ✓');
|
|
58
|
+
// 11. Parser direct API
|
|
59
|
+
const p = (0, ConditionParser_1.parseCondition)('a AND (b OR NOT c)');
|
|
60
|
+
assertTrue(p.ok && p.ast?.kind === 'and', '11: AST shape');
|
|
61
|
+
assertTrue((0, ConditionParser_1.evaluate)(p.ast, { a: true, b: false, c: false }) === true, '11b: eval');
|
|
62
|
+
console.log('[10.3] scenario 11 (parse API) ✓');
|
|
63
|
+
console.log('TEST_WORKFLOW_CONDITION_PARSER_OK');
|