@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,368 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* WorkflowParser — load + validate workflow YAML documents.
|
|
4
|
+
*
|
|
5
|
+
* Reads either a YAML string or a file path; returns a structured
|
|
6
|
+
* { ok, workflow?, errors[] } result. Never throws on user input — the
|
|
7
|
+
* worst case is `ok: false` with a list of stable error codes.
|
|
8
|
+
*
|
|
9
|
+
* Story 4.1 — OpenLife v1.2 Royal Stack.
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.parseWorkflow = parseWorkflow;
|
|
46
|
+
exports.parseWorkflowFile = parseWorkflowFile;
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const yaml = __importStar(require("js-yaml"));
|
|
49
|
+
const WorkflowSchema_1 = require("./WorkflowSchema");
|
|
50
|
+
const VALID_TYPES = new Set(['greenfield', 'brownfield', 'story-cycle', 'qa-loop', 'custom']);
|
|
51
|
+
/**
|
|
52
|
+
* Parse a YAML string into a validated Workflow. Returns a structured
|
|
53
|
+
* result; never throws.
|
|
54
|
+
*/
|
|
55
|
+
function parseWorkflow(yamlContent) {
|
|
56
|
+
const errors = [];
|
|
57
|
+
let doc;
|
|
58
|
+
try {
|
|
59
|
+
doc = yaml.load(yamlContent);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
return {
|
|
63
|
+
ok: false,
|
|
64
|
+
errors: [{
|
|
65
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.INVALID_YAML,
|
|
66
|
+
message: err instanceof Error ? err.message : 'YAML parse failed',
|
|
67
|
+
}],
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (doc === null || typeof doc !== 'object') {
|
|
71
|
+
return {
|
|
72
|
+
ok: false,
|
|
73
|
+
errors: [{
|
|
74
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.MISSING_ROOT,
|
|
75
|
+
message: 'document must be a YAML mapping with a `workflow:` root key',
|
|
76
|
+
}],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const root = doc;
|
|
80
|
+
if (!root.workflow || typeof root.workflow !== 'object') {
|
|
81
|
+
return {
|
|
82
|
+
ok: false,
|
|
83
|
+
errors: [{
|
|
84
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.MISSING_ROOT,
|
|
85
|
+
message: 'top-level `workflow:` key is required',
|
|
86
|
+
}],
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const wf = root.workflow;
|
|
90
|
+
// Required scalars
|
|
91
|
+
requireString(wf, 'id', errors);
|
|
92
|
+
requireString(wf, 'name', errors);
|
|
93
|
+
requireString(wf, 'version', errors);
|
|
94
|
+
requireString(wf, 'type', errors);
|
|
95
|
+
if (typeof wf.type === 'string' && !VALID_TYPES.has(wf.type)) {
|
|
96
|
+
errors.push({
|
|
97
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.INVALID_TYPE,
|
|
98
|
+
message: `type must be one of: ${Array.from(VALID_TYPES).join(', ')}`,
|
|
99
|
+
context: { received: wf.type },
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// v1.3 — optional Hermes fields (all backward-compatible)
|
|
103
|
+
validateV13Fields(wf, errors);
|
|
104
|
+
// sequence must exist and be an array
|
|
105
|
+
if (!Array.isArray(wf.sequence)) {
|
|
106
|
+
errors.push({
|
|
107
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.MISSING_REQUIRED_FIELD,
|
|
108
|
+
message: '`sequence` must be an array',
|
|
109
|
+
});
|
|
110
|
+
return { ok: false, errors };
|
|
111
|
+
}
|
|
112
|
+
// Validate each sequence entry + collect step ids
|
|
113
|
+
const stepIds = new Set();
|
|
114
|
+
const allKnownIds = new Set();
|
|
115
|
+
const stepsForRequires = [];
|
|
116
|
+
for (let i = 0; i < wf.sequence.length; i++) {
|
|
117
|
+
const entry = wf.sequence[i];
|
|
118
|
+
if ((0, WorkflowSchema_1.isPhaseMarker)(entry)) {
|
|
119
|
+
continue; // phase markers don't need ids/agents
|
|
120
|
+
}
|
|
121
|
+
if (!(0, WorkflowSchema_1.isExecutableStep)(entry)) {
|
|
122
|
+
errors.push({
|
|
123
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.INVALID_SCHEMA,
|
|
124
|
+
message: `sequence[${i}] is neither a phase marker (needs phase:number+name) nor an executable step (needs id:string)`,
|
|
125
|
+
});
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
// Duplicate step id check
|
|
129
|
+
if (stepIds.has(entry.id)) {
|
|
130
|
+
errors.push({
|
|
131
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.DUPLICATE_STEP_ID,
|
|
132
|
+
message: `step id '${entry.id}' is used more than once`,
|
|
133
|
+
context: { stepId: entry.id, index: i },
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
stepIds.add(entry.id);
|
|
138
|
+
allKnownIds.add(entry.id);
|
|
139
|
+
}
|
|
140
|
+
// Exactly one of agent/squad required
|
|
141
|
+
const hasAgent = typeof entry.agent === 'string' && entry.agent.length > 0;
|
|
142
|
+
const hasSquad = typeof entry.squad === 'string' && entry.squad.length > 0;
|
|
143
|
+
if (hasAgent && hasSquad) {
|
|
144
|
+
errors.push({
|
|
145
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.AGENT_AND_SQUAD,
|
|
146
|
+
message: `step '${entry.id}' specifies both agent and squad; pick one`,
|
|
147
|
+
context: { stepId: entry.id },
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if (!hasAgent && !hasSquad) {
|
|
151
|
+
errors.push({
|
|
152
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.NEITHER_AGENT_NOR_SQUAD,
|
|
153
|
+
message: `step '${entry.id}' must specify either agent or squad`,
|
|
154
|
+
context: { stepId: entry.id },
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
stepsForRequires.push(entry);
|
|
158
|
+
}
|
|
159
|
+
// Cross-check `requires` references after all step ids are collected
|
|
160
|
+
for (const step of stepsForRequires) {
|
|
161
|
+
const reqs = normalizeRequires(step.requires);
|
|
162
|
+
for (const req of reqs) {
|
|
163
|
+
// `requires` can reference either a step id OR an artifact path.
|
|
164
|
+
// We can't validate artifact paths at parse time (they're created
|
|
165
|
+
// by upstream steps at runtime), so we only flag references that
|
|
166
|
+
// LOOK LIKE step ids (no slashes/extensions) but aren't found.
|
|
167
|
+
if (looksLikeStepId(req) && !allKnownIds.has(req)) {
|
|
168
|
+
errors.push({
|
|
169
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.UNKNOWN_REQUIRES,
|
|
170
|
+
message: `step '${step.id}' requires '${req}', which is not a known step id`,
|
|
171
|
+
context: { stepId: step.id, requires: req },
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Circular requires detection (step-id refs only)
|
|
177
|
+
const cycle = detectCycle(stepsForRequires);
|
|
178
|
+
if (cycle) {
|
|
179
|
+
errors.push({
|
|
180
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.CIRCULAR_REQUIRES,
|
|
181
|
+
message: `circular requires chain: ${cycle.join(' -> ')}`,
|
|
182
|
+
context: { chain: cycle.join(',') },
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
if (errors.length > 0) {
|
|
186
|
+
return { ok: false, errors };
|
|
187
|
+
}
|
|
188
|
+
return { ok: true, workflow: wf, errors: [] };
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Parse a workflow YAML file from disk. Returns the same result shape as
|
|
192
|
+
* parseWorkflow().
|
|
193
|
+
*/
|
|
194
|
+
function parseWorkflowFile(filePath) {
|
|
195
|
+
if (!fs.existsSync(filePath)) {
|
|
196
|
+
return {
|
|
197
|
+
ok: false,
|
|
198
|
+
errors: [{
|
|
199
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.INVALID_YAML,
|
|
200
|
+
message: `workflow file not found: ${filePath}`,
|
|
201
|
+
context: { filePath },
|
|
202
|
+
}],
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
206
|
+
return parseWorkflow(content);
|
|
207
|
+
}
|
|
208
|
+
// ─────────────────────────────────────────────────────────────
|
|
209
|
+
// Helpers
|
|
210
|
+
// ─────────────────────────────────────────────────────────────
|
|
211
|
+
function requireString(obj, field, errors) {
|
|
212
|
+
const v = obj[field];
|
|
213
|
+
if (typeof v !== 'string' || v.length === 0) {
|
|
214
|
+
errors.push({
|
|
215
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.MISSING_REQUIRED_FIELD,
|
|
216
|
+
message: `field '${field}' is required and must be a non-empty string`,
|
|
217
|
+
context: { field },
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function normalizeRequires(requires) {
|
|
222
|
+
if (requires === undefined)
|
|
223
|
+
return [];
|
|
224
|
+
if (typeof requires === 'string')
|
|
225
|
+
return [requires];
|
|
226
|
+
if (Array.isArray(requires))
|
|
227
|
+
return requires.filter((r) => typeof r === 'string');
|
|
228
|
+
return [];
|
|
229
|
+
}
|
|
230
|
+
function looksLikeStepId(ref) {
|
|
231
|
+
// Heuristic: step ids look like `kebab-case-words` — no slashes, no
|
|
232
|
+
// dots, no extensions. Artifact paths look like `path/to/file.md`.
|
|
233
|
+
return !ref.includes('/') && !ref.includes('.') && /^[a-z0-9-]+$/i.test(ref);
|
|
234
|
+
}
|
|
235
|
+
function detectCycle(steps) {
|
|
236
|
+
const graph = new Map();
|
|
237
|
+
for (const step of steps) {
|
|
238
|
+
const reqs = normalizeRequires(step.requires).filter(looksLikeStepId);
|
|
239
|
+
graph.set(step.id, reqs);
|
|
240
|
+
}
|
|
241
|
+
const WHITE = 0, GRAY = 1, BLACK = 2;
|
|
242
|
+
const color = new Map();
|
|
243
|
+
const parent = new Map();
|
|
244
|
+
function dfs(node) {
|
|
245
|
+
color.set(node, GRAY);
|
|
246
|
+
for (const next of graph.get(node) || []) {
|
|
247
|
+
if (!graph.has(next))
|
|
248
|
+
continue; // not a known step id; skip
|
|
249
|
+
const c = color.get(next) || WHITE;
|
|
250
|
+
if (c === GRAY) {
|
|
251
|
+
// Reconstruct cycle path: next … node -> next
|
|
252
|
+
const cyc = [next];
|
|
253
|
+
let curr = node;
|
|
254
|
+
while (curr && curr !== next) {
|
|
255
|
+
cyc.unshift(curr);
|
|
256
|
+
const p = parent.get(curr);
|
|
257
|
+
curr = p === null ? undefined : p;
|
|
258
|
+
}
|
|
259
|
+
cyc.unshift(next);
|
|
260
|
+
return cyc;
|
|
261
|
+
}
|
|
262
|
+
if (c === WHITE) {
|
|
263
|
+
parent.set(next, node);
|
|
264
|
+
const found = dfs(next);
|
|
265
|
+
if (found)
|
|
266
|
+
return found;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
color.set(node, BLACK);
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
for (const id of graph.keys()) {
|
|
273
|
+
if ((color.get(id) || WHITE) === WHITE) {
|
|
274
|
+
parent.set(id, null);
|
|
275
|
+
const cyc = dfs(id);
|
|
276
|
+
if (cyc)
|
|
277
|
+
return cyc;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
// ────────────────────────────────────────────────────────────────
|
|
283
|
+
// Story 2.2 — v1.3 field validators (all optional fields, backward-compat).
|
|
284
|
+
// ────────────────────────────────────────────────────────────────
|
|
285
|
+
const VALID_MODES = new Set(['task', 'service']);
|
|
286
|
+
const VALID_STATUSES = new Set(['draft', 'tested', 'active', 'deprecated']);
|
|
287
|
+
const VALID_TRIGGERS = new Set(['manual', 'cron', 'webhook', 'event']);
|
|
288
|
+
function validateV13Fields(wf, errors) {
|
|
289
|
+
// mode
|
|
290
|
+
if (wf.mode !== undefined && !VALID_MODES.has(wf.mode)) {
|
|
291
|
+
errors.push({
|
|
292
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.INVALID_MODE,
|
|
293
|
+
message: `mode must be one of: ${Array.from(VALID_MODES).join(', ')}`,
|
|
294
|
+
context: { received: String(wf.mode) },
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
// status
|
|
298
|
+
if (wf.status !== undefined && !VALID_STATUSES.has(wf.status)) {
|
|
299
|
+
errors.push({
|
|
300
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.INVALID_TYPE,
|
|
301
|
+
message: `status must be one of: ${Array.from(VALID_STATUSES).join(', ')}`,
|
|
302
|
+
context: { received: String(wf.status) },
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
// triggers
|
|
306
|
+
if (wf.triggers !== undefined) {
|
|
307
|
+
if (!Array.isArray(wf.triggers)) {
|
|
308
|
+
errors.push({
|
|
309
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.INVALID_TRIGGERS,
|
|
310
|
+
message: 'triggers must be an array',
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
for (const t of wf.triggers) {
|
|
315
|
+
if (!VALID_TRIGGERS.has(t)) {
|
|
316
|
+
errors.push({
|
|
317
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.INVALID_TRIGGERS,
|
|
318
|
+
message: `unknown trigger '${t}'; valid: ${Array.from(VALID_TRIGGERS).join(', ')}`,
|
|
319
|
+
context: { received: String(t) },
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// success_criteria
|
|
326
|
+
if (wf.success_criteria !== undefined) {
|
|
327
|
+
if (!Array.isArray(wf.success_criteria)) {
|
|
328
|
+
errors.push({
|
|
329
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.INVALID_SUCCESS_CRITERIA,
|
|
330
|
+
message: 'success_criteria must be an array of {id, description} entries',
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
for (let i = 0; i < wf.success_criteria.length; i++) {
|
|
335
|
+
const c = wf.success_criteria[i];
|
|
336
|
+
if (typeof c?.id !== 'string' || typeof c?.description !== 'string') {
|
|
337
|
+
errors.push({
|
|
338
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.INVALID_SUCCESS_CRITERIA,
|
|
339
|
+
message: `success_criteria[${i}] must have string id and description`,
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
// tools
|
|
346
|
+
if (wf.tools !== undefined) {
|
|
347
|
+
const t = wf.tools;
|
|
348
|
+
for (const key of ['allowed', 'restricted', 'forbidden']) {
|
|
349
|
+
const v = t[key];
|
|
350
|
+
if (v !== undefined && !Array.isArray(v)) {
|
|
351
|
+
errors.push({
|
|
352
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.INVALID_TOOLS_POLICY,
|
|
353
|
+
message: `tools.${key} must be a string array if present`,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
else if (Array.isArray(v)) {
|
|
357
|
+
for (const item of v) {
|
|
358
|
+
if (typeof item !== 'string') {
|
|
359
|
+
errors.push({
|
|
360
|
+
code: WorkflowSchema_1.WORKFLOW_ERRORS.INVALID_TOOLS_POLICY,
|
|
361
|
+
message: `tools.${key} entries must be strings`,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* WorkflowSchema — TypeScript types for OpenLife workflows.
|
|
4
|
+
*
|
|
5
|
+
* A workflow is a YAML-declared executable sequence of steps. Each step
|
|
6
|
+
* names an agent (or squad), an action to perform, and the artifacts it
|
|
7
|
+
* is expected to create or update. Workflows are loaded by the
|
|
8
|
+
* WorkflowEngine, validated by the WorkflowParser, and persisted as runs
|
|
9
|
+
* under `.openlife/workflows/<runId>.json`.
|
|
10
|
+
*
|
|
11
|
+
* Story 4.1 — OpenLife v1.2 Royal Stack.
|
|
12
|
+
*
|
|
13
|
+
* The schema is intentionally close to community story-cycle workflow
|
|
14
|
+
* conventions so the four ported workflows in dist-templates/workflows/
|
|
15
|
+
* (Story 4.4) round-trip without contortion. Two OpenLife-specific
|
|
16
|
+
* extensions:
|
|
17
|
+
*
|
|
18
|
+
* 1. `squad: <id>` — a step may dispatch to a Squad instead of a
|
|
19
|
+
* single agent, so the design-squad / qa-squad can be addressed as
|
|
20
|
+
* a single unit.
|
|
21
|
+
* 2. `idempotent: true` — declares the step is safe to re-execute on
|
|
22
|
+
* resume after a partial-run crash. WorkflowEngine.resume() uses
|
|
23
|
+
* this flag to decide whether to retry or skip a partially-
|
|
24
|
+
* completed step.
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.WORKFLOW_ERRORS = void 0;
|
|
28
|
+
exports.isPhaseMarker = isPhaseMarker;
|
|
29
|
+
exports.isExecutableStep = isExecutableStep;
|
|
30
|
+
// ─────────────────────────────────────────────────────────────
|
|
31
|
+
// Type guards — used by the parser to discriminate sequence entries
|
|
32
|
+
// ─────────────────────────────────────────────────────────────
|
|
33
|
+
function isPhaseMarker(entry) {
|
|
34
|
+
if (entry === null || typeof entry !== 'object')
|
|
35
|
+
return false;
|
|
36
|
+
const e = entry;
|
|
37
|
+
return typeof e.phase === 'number' && typeof e.name === 'string' && e.id === undefined;
|
|
38
|
+
}
|
|
39
|
+
function isExecutableStep(entry) {
|
|
40
|
+
if (entry === null || typeof entry !== 'object')
|
|
41
|
+
return false;
|
|
42
|
+
const e = entry;
|
|
43
|
+
return typeof e.id === 'string';
|
|
44
|
+
}
|
|
45
|
+
// ─────────────────────────────────────────────────────────────
|
|
46
|
+
// Stable error codes — exported so callers + tests assert on strings,
|
|
47
|
+
// not error messages.
|
|
48
|
+
// ─────────────────────────────────────────────────────────────
|
|
49
|
+
exports.WORKFLOW_ERRORS = {
|
|
50
|
+
INVALID_YAML: 'workflow_invalid_yaml',
|
|
51
|
+
INVALID_SCHEMA: 'workflow_invalid_schema',
|
|
52
|
+
MISSING_ROOT: 'workflow_missing_root',
|
|
53
|
+
MISSING_REQUIRED_FIELD: 'workflow_missing_required_field',
|
|
54
|
+
INVALID_TYPE: 'workflow_invalid_type',
|
|
55
|
+
DUPLICATE_STEP_ID: 'workflow_duplicate_step_id',
|
|
56
|
+
CIRCULAR_REQUIRES: 'workflow_circular_requires',
|
|
57
|
+
UNKNOWN_REQUIRES: 'workflow_unknown_requires',
|
|
58
|
+
AGENT_AND_SQUAD: 'workflow_agent_and_squad',
|
|
59
|
+
NEITHER_AGENT_NOR_SQUAD: 'workflow_neither_agent_nor_squad',
|
|
60
|
+
// v1.3 additions (Story 2.2)
|
|
61
|
+
INVALID_MODE: 'workflow_invalid_mode',
|
|
62
|
+
INVALID_TOOLS_POLICY: 'workflow_invalid_tools_policy',
|
|
63
|
+
INVALID_TRIGGERS: 'workflow_invalid_triggers',
|
|
64
|
+
INVALID_SUCCESS_CRITERIA: 'workflow_invalid_success_criteria',
|
|
65
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* WorkflowState — persisted runtime state for a workflow run.
|
|
4
|
+
*
|
|
5
|
+
* Story 4.2 — OpenLife v1.2 Royal Stack.
|
|
6
|
+
*
|
|
7
|
+
* Storage: <stateDir>/workflows/<runId>.json (atomic via AtomicWriter).
|
|
8
|
+
* Events: <stateDir>/workflows/events/<runId>.jsonl (append-only,
|
|
9
|
+
* atomic via appendJsonlAtomic).
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,134 @@
|
|
|
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.ReversaAgent = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const ReversaExecutors_1 = require("./ReversaExecutors");
|
|
40
|
+
const ReversaContracts_1 = require("./ReversaContracts");
|
|
41
|
+
class ReversaAgent {
|
|
42
|
+
statePath;
|
|
43
|
+
executors;
|
|
44
|
+
constructor() {
|
|
45
|
+
this.statePath = path.join(process.cwd(), '.reversa', 'state.json');
|
|
46
|
+
this.executors = new ReversaExecutors_1.ReversaExecutors(process.cwd());
|
|
47
|
+
fs.mkdirSync(path.dirname(this.statePath), { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
resume() {
|
|
50
|
+
if (!fs.existsSync(this.statePath)) {
|
|
51
|
+
const initial = { phase: 'reconnaissance', updatedAt: new Date().toISOString(), notes: ['Reversa initialized'] };
|
|
52
|
+
this.save(initial);
|
|
53
|
+
return initial;
|
|
54
|
+
}
|
|
55
|
+
return JSON.parse(fs.readFileSync(this.statePath, 'utf-8'));
|
|
56
|
+
}
|
|
57
|
+
advance(note) {
|
|
58
|
+
const cur = this.resume();
|
|
59
|
+
const phases = ['reconnaissance', 'excavation', 'interpretation', 'generation', 'review'];
|
|
60
|
+
const idx = phases.indexOf(cur.phase);
|
|
61
|
+
const nextPhase = phases[Math.min(idx + 1, phases.length - 1)];
|
|
62
|
+
const checkpoint = { ...(cur.checkpoint || {}) };
|
|
63
|
+
if (nextPhase === 'excavation')
|
|
64
|
+
checkpoint.scout = 'surface map ready';
|
|
65
|
+
if (nextPhase === 'interpretation')
|
|
66
|
+
checkpoint.archaeologist = 'module deep analysis ready';
|
|
67
|
+
if (nextPhase === 'generation')
|
|
68
|
+
checkpoint.detective = 'implicit business rules extracted';
|
|
69
|
+
if (nextPhase === 'review') {
|
|
70
|
+
checkpoint.architect = 'c4/erd/contracts synthesized';
|
|
71
|
+
checkpoint.writer = 'operational contracts generated';
|
|
72
|
+
checkpoint.reviewer = 'gaps reviewed';
|
|
73
|
+
}
|
|
74
|
+
const next = { phase: nextPhase, mode: cur.mode || 'default', designProfileId: cur.designProfileId, checkpoint, updatedAt: new Date().toISOString(), notes: [...cur.notes, note] };
|
|
75
|
+
this.save(next);
|
|
76
|
+
return next;
|
|
77
|
+
}
|
|
78
|
+
setMode(mode, designProfileId) {
|
|
79
|
+
const cur = this.resume();
|
|
80
|
+
const next = { ...cur, mode, designProfileId, updatedAt: new Date().toISOString(), notes: [...cur.notes, `Mode set to ${mode}${designProfileId ? ` (${designProfileId})` : ''}`] };
|
|
81
|
+
this.save(next);
|
|
82
|
+
return next;
|
|
83
|
+
}
|
|
84
|
+
runPhase(phase, note = 'phase run') {
|
|
85
|
+
const cur = this.resume();
|
|
86
|
+
const mapping = {
|
|
87
|
+
reconnaissance: 'scout', excavation: 'archaeologist', interpretation: 'detective', generation: 'writer', review: 'reviewer'
|
|
88
|
+
};
|
|
89
|
+
const result = this.executors.run(mapping[phase], { mode: cur.mode, profile: cur.designProfileId, note });
|
|
90
|
+
const next = { ...cur, phase, updatedAt: new Date().toISOString(), notes: [...cur.notes, `${phase}: ${result.summary}`] };
|
|
91
|
+
this.save(next);
|
|
92
|
+
return next;
|
|
93
|
+
}
|
|
94
|
+
runAll(note = 'run all') {
|
|
95
|
+
const phases = ['reconnaissance', 'excavation', 'interpretation', 'generation', 'review'];
|
|
96
|
+
let state = this.resume();
|
|
97
|
+
for (const p of phases)
|
|
98
|
+
state = this.runPhase(p, `${note} :: ${p}`);
|
|
99
|
+
this.writeFinalContracts();
|
|
100
|
+
return state;
|
|
101
|
+
}
|
|
102
|
+
writeFinalContracts() {
|
|
103
|
+
const cur = this.resume();
|
|
104
|
+
const artifactsRoot = path.join(process.cwd(), '.reversa', 'artifacts');
|
|
105
|
+
const validation = (0, ReversaContracts_1.validatePhaseChain)(artifactsRoot);
|
|
106
|
+
const contracts = (0, ReversaContracts_1.getContracts)();
|
|
107
|
+
const out = path.join(process.cwd(), '.reversa', 'final-contracts.md');
|
|
108
|
+
const body = [
|
|
109
|
+
'# Reversa Final Contracts',
|
|
110
|
+
`mode: ${cur.mode || 'default'}`,
|
|
111
|
+
`designProfileId: ${cur.designProfileId || 'none'}`,
|
|
112
|
+
`validation_ok: ${validation.ok}`,
|
|
113
|
+
`missing: ${validation.missing.join(', ') || 'none'}`,
|
|
114
|
+
'',
|
|
115
|
+
'## Contracts',
|
|
116
|
+
...contracts.map((c) => `- ${c.phase}/${c.role}: in=[${c.requiredInputs.join(', ')}] out=[${c.producedOutputs.join(', ')}]`)
|
|
117
|
+
].join('\n');
|
|
118
|
+
fs.writeFileSync(out, body, 'utf-8');
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
exportContractsJson() {
|
|
122
|
+
const cur = this.resume();
|
|
123
|
+
const artifactsRoot = path.join(process.cwd(), '.reversa', 'artifacts');
|
|
124
|
+
const validation = (0, ReversaContracts_1.validatePhaseChain)(artifactsRoot);
|
|
125
|
+
const contracts = (0, ReversaContracts_1.getContracts)();
|
|
126
|
+
const out = path.join(process.cwd(), '.reversa', 'final-contracts.json');
|
|
127
|
+
fs.writeFileSync(out, JSON.stringify({ mode: cur.mode || 'default', designProfileId: cur.designProfileId || 'none', validation, contracts }, null, 2), 'utf-8');
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
save(state) {
|
|
131
|
+
fs.writeFileSync(this.statePath, JSON.stringify(state, null, 2), 'utf-8');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
exports.ReversaAgent = ReversaAgent;
|
|
@@ -0,0 +1,62 @@
|
|
|
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.getContracts = getContracts;
|
|
37
|
+
exports.validatePhaseChain = validatePhaseChain;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const contracts = [
|
|
41
|
+
{ role: 'scout', phase: 'reconnaissance', requiredInputs: ['repo_path'], producedOutputs: ['surface_map'] },
|
|
42
|
+
{ role: 'archaeologist', phase: 'excavation', requiredInputs: ['surface_map'], producedOutputs: ['module_analysis'] },
|
|
43
|
+
{ role: 'detective', phase: 'interpretation', requiredInputs: ['module_analysis'], producedOutputs: ['business_rules'] },
|
|
44
|
+
{ role: 'writer', phase: 'generation', requiredInputs: ['business_rules'], producedOutputs: ['operational_contracts'] },
|
|
45
|
+
{ role: 'reviewer', phase: 'review', requiredInputs: ['operational_contracts'], producedOutputs: ['validated_contracts'] }
|
|
46
|
+
];
|
|
47
|
+
function getContracts() { return contracts; }
|
|
48
|
+
function validatePhaseChain(artifactsRoot) {
|
|
49
|
+
const missing = [];
|
|
50
|
+
const produced = new Set();
|
|
51
|
+
for (const c of contracts) {
|
|
52
|
+
for (const req of c.requiredInputs)
|
|
53
|
+
if (!produced.has(req) && req !== 'repo_path')
|
|
54
|
+
missing.push(`${c.phase}:${req}`);
|
|
55
|
+
for (const out of c.producedOutputs)
|
|
56
|
+
produced.add(out);
|
|
57
|
+
}
|
|
58
|
+
const hasArtifacts = fs.existsSync(path.join(artifactsRoot, 'reviewer'));
|
|
59
|
+
if (!hasArtifacts)
|
|
60
|
+
missing.push('reviewer artifacts missing');
|
|
61
|
+
return { ok: missing.length === 0, missing };
|
|
62
|
+
}
|