@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.
Files changed (394) hide show
  1. package/INSTALL.md +266 -0
  2. package/LICENSE +21 -0
  3. package/README.md +142 -0
  4. package/bin/openlife.js +3 -0
  5. package/dist/admin_panel_server.js +66 -0
  6. package/dist/cli/AgentManager.js +109 -0
  7. package/dist/cli/AutonomousInstaller.js +134 -0
  8. package/dist/cli/DreamOrganizer.js +88 -0
  9. package/dist/cli/HostInstaller.js +426 -0
  10. package/dist/cli/InstallBanner.js +16 -0
  11. package/dist/cli/InstallFlow.js +256 -0
  12. package/dist/cli/InstallHeadless.js +47 -0
  13. package/dist/cli/InstallModules.js +148 -0
  14. package/dist/cli/InstallStateStore.js +75 -0
  15. package/dist/cli/InstallWizard.js +364 -0
  16. package/dist/cli/ProfileManager.js +163 -0
  17. package/dist/cli/SystemInstaller.js +89 -0
  18. package/dist/cli/WorldClassCommands.js +208 -0
  19. package/dist/design/DesignMdImporter.js +82 -0
  20. package/dist/design/DesignMdMode.js +93 -0
  21. package/dist/design/DesignMdRegistry.js +67 -0
  22. package/dist/index.js +2575 -0
  23. package/dist/memory/ConversationMemory.js +33 -0
  24. package/dist/memory/LocalMemoryProvider.js +86 -0
  25. package/dist/memory/Mem0Provider.js +16 -0
  26. package/dist/memory/MemoryNamespacePolicy.js +27 -0
  27. package/dist/memory/MemoryOrchestrator.js +65 -0
  28. package/dist/memory/MemoryPromotionFlow.js +32 -0
  29. package/dist/memory/MemoryProvider.js +2 -0
  30. package/dist/memory/MemoryProviderRegistry.js +27 -0
  31. package/dist/memory/MemoryRetentionPolicy.js +60 -0
  32. package/dist/memory/MempalaceProvider.js +72 -0
  33. package/dist/memory/OmniMemory.js +106 -0
  34. package/dist/memory/RedisAgentMemoryProvider.js +16 -0
  35. package/dist/memory/SessionManager.js +86 -0
  36. package/dist/memory/ZepGraphitiProvider.js +16 -0
  37. package/dist/orchestrator/AgentRegistry.js +56 -0
  38. package/dist/orchestrator/AgentScoring.js +82 -0
  39. package/dist/orchestrator/AgentTeam.js +22 -0
  40. package/dist/orchestrator/ArbitrationAgent.js +43 -0
  41. package/dist/orchestrator/ArbitrationScorecard.js +17 -0
  42. package/dist/orchestrator/AssetPromotionEngine.js +65 -0
  43. package/dist/orchestrator/AssetReuseRouter.js +63 -0
  44. package/dist/orchestrator/BenchmarkEngine.js +75 -0
  45. package/dist/orchestrator/Brain.js +298 -0
  46. package/dist/orchestrator/CadenceEngine.js +76 -0
  47. package/dist/orchestrator/CapabilityRouter.js +36 -0
  48. package/dist/orchestrator/CommandLanguage.js +27 -0
  49. package/dist/orchestrator/CommandRouter.js +70 -0
  50. package/dist/orchestrator/ConsequenceForecaster.js +286 -0
  51. package/dist/orchestrator/CronManager.js +286 -0
  52. package/dist/orchestrator/DynamicAgentBuilder.js +48 -0
  53. package/dist/orchestrator/DynamicAgentExecutor.js +15 -0
  54. package/dist/orchestrator/EnterpriseAgenticCore.js +276 -0
  55. package/dist/orchestrator/ExecutionBoard.js +86 -0
  56. package/dist/orchestrator/ExecutionIntent.js +13 -0
  57. package/dist/orchestrator/ExecutionModePolicy.js +48 -0
  58. package/dist/orchestrator/ExecutionRouter.js +9 -0
  59. package/dist/orchestrator/ExecutionState.js +20 -0
  60. package/dist/orchestrator/ExecutorHealth.js +86 -0
  61. package/dist/orchestrator/ExternalCatalogRegistry.js +83 -0
  62. package/dist/orchestrator/Gatekeeper.js +414 -0
  63. package/dist/orchestrator/Gateway.js +508 -0
  64. package/dist/orchestrator/GovernanceConsentStore.js +66 -0
  65. package/dist/orchestrator/GovernanceLayer.js +179 -0
  66. package/dist/orchestrator/GovernancePolicyStore.js +53 -0
  67. package/dist/orchestrator/GovernanceScopeLedger.js +134 -0
  68. package/dist/orchestrator/GovernanceScopePolicy.js +67 -0
  69. package/dist/orchestrator/IntentClassifier.js +45 -0
  70. package/dist/orchestrator/JobLifecycle.js +91 -0
  71. package/dist/orchestrator/LearningRouter.js +24 -0
  72. package/dist/orchestrator/MediaManager.js +92 -0
  73. package/dist/orchestrator/MemoryCuratorAgent.js +41 -0
  74. package/dist/orchestrator/MissionState.js +155 -0
  75. package/dist/orchestrator/ModelManager.js +84 -0
  76. package/dist/orchestrator/OperatingSystem.js +71 -0
  77. package/dist/orchestrator/OperationalMemoryStore.js +94 -0
  78. package/dist/orchestrator/OptimizationLoop.js +72 -0
  79. package/dist/orchestrator/OrchestrationLoop.js +905 -0
  80. package/dist/orchestrator/OrgStructure.js +88 -0
  81. package/dist/orchestrator/OutcomeSimulator.js +46 -0
  82. package/dist/orchestrator/ParallelOrchestrationLoop.js +36 -0
  83. package/dist/orchestrator/PerformanceScorecard.js +105 -0
  84. package/dist/orchestrator/PlannerAgent.js +46 -0
  85. package/dist/orchestrator/ProcessSandbox.js +129 -0
  86. package/dist/orchestrator/PromotionPipeline.js +74 -0
  87. package/dist/orchestrator/PromotionReviewGate.js +11 -0
  88. package/dist/orchestrator/QueueScheduler.js +260 -0
  89. package/dist/orchestrator/ReleaseGate.js +36 -0
  90. package/dist/orchestrator/ReleaseWorkflow.js +68 -0
  91. package/dist/orchestrator/RemotePublisher.js +139 -0
  92. package/dist/orchestrator/ReuseEngine.js +89 -0
  93. package/dist/orchestrator/ReviewerAgent.js +49 -0
  94. package/dist/orchestrator/RoleHandoff.js +65 -0
  95. package/dist/orchestrator/RuntimeHealthMonitor.js +143 -0
  96. package/dist/orchestrator/RuntimePolicy.js +105 -0
  97. package/dist/orchestrator/RuntimeProbe.js +97 -0
  98. package/dist/orchestrator/RuntimeRegistry.js +73 -0
  99. package/dist/orchestrator/SandboxPolicy.js +22 -0
  100. package/dist/orchestrator/SecurityDownloadGuard.js +169 -0
  101. package/dist/orchestrator/SecurityEventStore.js +58 -0
  102. package/dist/orchestrator/ServiceCompletionPolicy.js +36 -0
  103. package/dist/orchestrator/ServiceState.js +195 -0
  104. package/dist/orchestrator/SkillCreator.js +404 -0
  105. package/dist/orchestrator/SkillLearningLoop.js +57 -0
  106. package/dist/orchestrator/SkillManager.js +75 -0
  107. package/dist/orchestrator/SkillNetwork.js +29 -0
  108. package/dist/orchestrator/SkillRegistryV2.js +28 -0
  109. package/dist/orchestrator/SkillScoring.js +70 -0
  110. package/dist/orchestrator/SquadAutoCreator.js +64 -0
  111. package/dist/orchestrator/SquadCreator.js +727 -0
  112. package/dist/orchestrator/SquadRegistry.js +28 -0
  113. package/dist/orchestrator/SquadRouter.js +33 -0
  114. package/dist/orchestrator/SquadScoring.js +70 -0
  115. package/dist/orchestrator/SubagentLifecycle.js +90 -0
  116. package/dist/orchestrator/SynthesizerAgent.js +48 -0
  117. package/dist/orchestrator/SystemDoctor.js +224 -0
  118. package/dist/orchestrator/TaskExecutor.js +422 -0
  119. package/dist/orchestrator/TeammateBoard.js +61 -0
  120. package/dist/orchestrator/TestHarness.js +184 -0
  121. package/dist/orchestrator/VoiceManager.js +203 -0
  122. package/dist/orchestrator/VoiceRouter.js +89 -0
  123. package/dist/orchestrator/capability/CapabilityGenesisEngine.js +278 -0
  124. package/dist/orchestrator/capability/CapabilityPackParser.js +223 -0
  125. package/dist/orchestrator/capability/CapabilityPackSchema.js +62 -0
  126. package/dist/orchestrator/capability/CapabilityPackState.js +163 -0
  127. package/dist/orchestrator/providers/AgentProvider.js +2 -0
  128. package/dist/orchestrator/providers/CapabilityProvider.js +12 -0
  129. package/dist/orchestrator/providers/CloudAgentProvider.js +55 -0
  130. package/dist/orchestrator/providers/CloudSkillProvider.js +55 -0
  131. package/dist/orchestrator/providers/CloudSquadProvider.js +55 -0
  132. package/dist/orchestrator/providers/CompositeAgentProvider.js +16 -0
  133. package/dist/orchestrator/providers/CompositeCapabilityProvider.js +25 -0
  134. package/dist/orchestrator/providers/CompositeSkillProvider.js +16 -0
  135. package/dist/orchestrator/providers/CompositeSquadProvider.js +16 -0
  136. package/dist/orchestrator/providers/CompositeWorkflowProvider.js +46 -0
  137. package/dist/orchestrator/providers/FileAgentProvider.js +105 -0
  138. package/dist/orchestrator/providers/FileCapabilityProvider.js +106 -0
  139. package/dist/orchestrator/providers/FileSkillProvider.js +65 -0
  140. package/dist/orchestrator/providers/FileSquadProvider.js +69 -0
  141. package/dist/orchestrator/providers/FileWorkflowProvider.js +103 -0
  142. package/dist/orchestrator/providers/SkillProvider.js +2 -0
  143. package/dist/orchestrator/providers/SquadProvider.js +2 -0
  144. package/dist/orchestrator/toolset/ToolsetGuard.js +69 -0
  145. package/dist/orchestrator/toolset/ToolsetRegistry.js +65 -0
  146. package/dist/orchestrator/toolset/ToolsetSchema.js +21 -0
  147. package/dist/orchestrator/util/AtomicWriter.js +204 -0
  148. package/dist/orchestrator/util/DistributedLock.js +232 -0
  149. package/dist/orchestrator/util/TemplateRenderer.js +87 -0
  150. package/dist/orchestrator/util/WatchdogHeartbeat.js +116 -0
  151. package/dist/orchestrator/workflow/ConditionParser.js +232 -0
  152. package/dist/orchestrator/workflow/WorkflowEngine.js +379 -0
  153. package/dist/orchestrator/workflow/WorkflowParser.js +368 -0
  154. package/dist/orchestrator/workflow/WorkflowSchema.js +65 -0
  155. package/dist/orchestrator/workflow/WorkflowState.js +11 -0
  156. package/dist/reversa/ReversaAgent.js +134 -0
  157. package/dist/reversa/ReversaContracts.js +62 -0
  158. package/dist/reversa/ReversaExecutors.js +65 -0
  159. package/dist/skills/SkillRegistry.js +71 -0
  160. package/dist/squads/SquadManager.js +87 -0
  161. package/dist/test_admin_teams_networks.js +54 -0
  162. package/dist/test_agent_team_skill_network.js +15 -0
  163. package/dist/test_aiobuilder_cli_parity.js +169 -0
  164. package/dist/test_ask_exit.js +73 -0
  165. package/dist/test_atomic_writer.js +209 -0
  166. package/dist/test_autonomous_soak.js +141 -0
  167. package/dist/test_benchmark_engine.js +41 -0
  168. package/dist/test_brain_error_diagnostics.js +51 -0
  169. package/dist/test_brain_fallback_chain.js +93 -0
  170. package/dist/test_capability_genesis_engine.js +225 -0
  171. package/dist/test_capability_pack_schema.js +214 -0
  172. package/dist/test_catalog_quality.js +150 -0
  173. package/dist/test_cli_crud_roundtrip.js +154 -0
  174. package/dist/test_cli_diagnostics.js +131 -0
  175. package/dist/test_cli_doc_parity.js +126 -0
  176. package/dist/test_cli_help_surface.js +106 -0
  177. package/dist/test_cli_service_commands.js +83 -0
  178. package/dist/test_consequence_forecast_brain.js +165 -0
  179. package/dist/test_consequence_forecaster.js +24 -0
  180. package/dist/test_conversation_memory.js +36 -0
  181. package/dist/test_create_entities.js +54 -0
  182. package/dist/test_creator_placeholders_completed.js +177 -0
  183. package/dist/test_cron_manager.js +123 -0
  184. package/dist/test_daemon_sigterm.js +72 -0
  185. package/dist/test_deep_research_capability.js +87 -0
  186. package/dist/test_designmd_import_registry.js +16 -0
  187. package/dist/test_designmd_mode.js +50 -0
  188. package/dist/test_designmd_mode_workspace.js +13 -0
  189. package/dist/test_dist_templates_layout.js +135 -0
  190. package/dist/test_distributed_lock.js +201 -0
  191. package/dist/test_distribution_installability.js +67 -0
  192. package/dist/test_doctor_sandbox_check.js +44 -0
  193. package/dist/test_dream_organizer.js +25 -0
  194. package/dist/test_dual_mode.js +15 -0
  195. package/dist/test_enterprise_agentic_core.js +128 -0
  196. package/dist/test_forecast_brain_wiring.js +87 -0
  197. package/dist/test_gateway_telegram_guardrails.js +52 -0
  198. package/dist/test_governance.js +34 -0
  199. package/dist/test_governance_advanced.js +75 -0
  200. package/dist/test_governance_scope_ledger.js +147 -0
  201. package/dist/test_governance_v13_policies.js +44 -0
  202. package/dist/test_guided_creator_cli.js +100 -0
  203. package/dist/test_host_install_e2e.js +324 -0
  204. package/dist/test_host_installer.js +259 -0
  205. package/dist/test_host_installers_gemini_codex.js +95 -0
  206. package/dist/test_host_uninstaller.js +295 -0
  207. package/dist/test_install_flow.js +70 -0
  208. package/dist/test_install_flow_host_validation.js +143 -0
  209. package/dist/test_install_wizard.js +272 -0
  210. package/dist/test_integration_gemini_live.js +95 -0
  211. package/dist/test_integration_http_trigger_live.js +154 -0
  212. package/dist/test_integration_telegram_live.js +102 -0
  213. package/dist/test_job_lifecycle.js +16 -0
  214. package/dist/test_memory_orchestrator.js +33 -0
  215. package/dist/test_memory_promotion.js +36 -0
  216. package/dist/test_memory_retention.js +37 -0
  217. package/dist/test_mission_checkpoint.js +204 -0
  218. package/dist/test_multi_host_docs_parity.js +125 -0
  219. package/dist/test_openlife_auto_creator_routing.js +69 -0
  220. package/dist/test_openlife_evolution_surface.js +77 -0
  221. package/dist/test_openlife_gatekeeper_routing.js +15 -0
  222. package/dist/test_openlife_routing_surface.js +27 -0
  223. package/dist/test_openlife_runtime_source_truth.js +25 -0
  224. package/dist/test_operating_system.js +45 -0
  225. package/dist/test_optimization_loop.js +38 -0
  226. package/dist/test_orchestration_assets_lifecycle.js +78 -0
  227. package/dist/test_outcome_simulator.js +38 -0
  228. package/dist/test_performance_latency.js +215 -0
  229. package/dist/test_performance_scorecard.js +38 -0
  230. package/dist/test_phase1_check_exit.js +103 -0
  231. package/dist/test_phase6_board.js +31 -0
  232. package/dist/test_phase6_cadence.js +29 -0
  233. package/dist/test_phase6_ops.js +37 -0
  234. package/dist/test_post_mission_evaluation.js +190 -0
  235. package/dist/test_process_sandbox.js +88 -0
  236. package/dist/test_profile_toolset_mcp.js +125 -0
  237. package/dist/test_queue_scheduler.js +239 -0
  238. package/dist/test_release_gate.js +23 -0
  239. package/dist/test_remote_publish.js +193 -0
  240. package/dist/test_reversa_contracts_e2e.js +48 -0
  241. package/dist/test_reversa_export_and_strict.js +51 -0
  242. package/dist/test_reversa_full_execution.js +12 -0
  243. package/dist/test_reversa_lite.js +9 -0
  244. package/dist/test_royal_stack_golden.js +179 -0
  245. package/dist/test_runtime_health_backoff.js +154 -0
  246. package/dist/test_runtime_policy.js +26 -0
  247. package/dist/test_runtime_probe.js +19 -0
  248. package/dist/test_runtime_profile_oauth_only.js +262 -0
  249. package/dist/test_runtime_registry.js +11 -0
  250. package/dist/test_security_download_and_scan.js +103 -0
  251. package/dist/test_security_download_guard.js +14 -0
  252. package/dist/test_service_command_surface.js +12 -0
  253. package/dist/test_service_completion_policy.js +32 -0
  254. package/dist/test_service_guardrails_delete.js +12 -0
  255. package/dist/test_service_mode_explicit_only.js +174 -0
  256. package/dist/test_sources_import_ref.js +46 -0
  257. package/dist/test_sources_scaffold.js +43 -0
  258. package/dist/test_squad_skill_creator.js +305 -0
  259. package/dist/test_squad_skill_design_llm.js +176 -0
  260. package/dist/test_subsystems_org_state.js +271 -0
  261. package/dist/test_subsystems_promotion_memory_assets.js +343 -0
  262. package/dist/test_subsystems_routing_governance.js +234 -0
  263. package/dist/test_task_executor_sandbox_optin.js +127 -0
  264. package/dist/test_teammate_learning.js +15 -0
  265. package/dist/test_telegram_delete_guardrail.js +21 -0
  266. package/dist/test_toolset_enforcement.js +188 -0
  267. package/dist/test_trigger_basic_auth.js +112 -0
  268. package/dist/test_util/doc_parity.js +120 -0
  269. package/dist/test_v15_e2e_integration.js +207 -0
  270. package/dist/test_watchdog_heartbeat.js +152 -0
  271. package/dist/test_workflow_condition_parser.js +63 -0
  272. package/dist/test_workflow_e2e.js +240 -0
  273. package/dist/test_workflow_engine.js +330 -0
  274. package/dist/test_workflow_parser.js +245 -0
  275. package/dist/test_workflow_schema_backward_compat.js +197 -0
  276. package/dist-templates/README.md +91 -0
  277. package/dist-templates/claude-code/agents/openlife-atlas.md +52 -0
  278. package/dist-templates/claude-code/agents/openlife-forge.md +42 -0
  279. package/dist-templates/claude-code/agents/openlife-genesis.md +59 -0
  280. package/dist-templates/claude-code/agents/openlife-lyra.md +40 -0
  281. package/dist-templates/claude-code/agents/openlife-maestro.md +45 -0
  282. package/dist-templates/claude-code/commands/openlife/ask.md +14 -0
  283. package/dist-templates/claude-code/commands/openlife/doctor.md +19 -0
  284. package/dist-templates/claude-code/commands/openlife/dream.md +20 -0
  285. package/dist-templates/claude-code/commands/openlife/status.md +14 -0
  286. package/dist-templates/claude-code/mcp/openlife-orchestrator.json +46 -0
  287. package/dist-templates/codex/README.md +7 -0
  288. package/dist-templates/codex/agents/openlife-atlas.md +52 -0
  289. package/dist-templates/codex/agents/openlife-forge.md +42 -0
  290. package/dist-templates/codex/agents/openlife-genesis.md +59 -0
  291. package/dist-templates/codex/agents/openlife-lyra.md +40 -0
  292. package/dist-templates/codex/agents/openlife-maestro.md +45 -0
  293. package/dist-templates/codex/commands/openlife/ask.md +14 -0
  294. package/dist-templates/codex/commands/openlife/doctor.md +19 -0
  295. package/dist-templates/codex/commands/openlife/dream.md +20 -0
  296. package/dist-templates/codex/commands/openlife/status.md +14 -0
  297. package/dist-templates/codex/mcp/openlife-orchestrator.json +46 -0
  298. package/dist-templates/gemini-cli/README.md +8 -0
  299. package/dist-templates/gemini-cli/agents/openlife-atlas.md +52 -0
  300. package/dist-templates/gemini-cli/agents/openlife-forge.md +42 -0
  301. package/dist-templates/gemini-cli/agents/openlife-genesis.md +59 -0
  302. package/dist-templates/gemini-cli/agents/openlife-lyra.md +40 -0
  303. package/dist-templates/gemini-cli/agents/openlife-maestro.md +45 -0
  304. package/dist-templates/gemini-cli/commands/openlife/ask.md +14 -0
  305. package/dist-templates/gemini-cli/commands/openlife/doctor.md +19 -0
  306. package/dist-templates/gemini-cli/commands/openlife/dream.md +20 -0
  307. package/dist-templates/gemini-cli/commands/openlife/status.md +14 -0
  308. package/dist-templates/gemini-cli/mcp/openlife-orchestrator.json +46 -0
  309. package/dist-templates/skill-template/README.md +34 -0
  310. package/dist-templates/skill-template/SKILL.md.template +59 -0
  311. package/dist-templates/squad-template/README.md +82 -0
  312. package/dist-templates/squad-template/SQUAD.md.template +51 -0
  313. package/dist-templates/squad-template/agent-template.md +51 -0
  314. package/dist-templates/squad-template/checklist-template.md +25 -0
  315. package/dist-templates/squad-template/task-template.md +36 -0
  316. package/dist-templates/workflows/PORTED_WORKFLOWS.md +60 -0
  317. package/dist-templates/workflows/brownfield-discovery.yaml +137 -0
  318. package/dist-templates/workflows/greenfield-fullstack.yaml +132 -0
  319. package/dist-templates/workflows/qa-loop.yaml +125 -0
  320. package/dist-templates/workflows/story-development-cycle.yaml +80 -0
  321. package/docs/CHANGELOG_FEATURE_ROLLOUT_DESIGNMD.md +43 -0
  322. package/docs/EXTERNAL_SOURCES_AND_SECURITY_GUARD.md +33 -0
  323. package/docs/OPENLIFE_AUDIT_2026-05-06.md +170 -0
  324. package/docs/OPENLIFE_CONSOLIDATED_PLAN_2026-05-06.md +299 -0
  325. package/docs/OPENLIFE_DUAL_MODE_IMPLEMENTATION_PLAN.md +205 -0
  326. package/docs/OPENLIFE_EVOLUTION_SURFACE_2026-05-07.md +53 -0
  327. package/docs/OPENLIFE_SKILLS_IMPORT_2026-05-07.json +223 -0
  328. package/docs/OPENLIFE_SQUADS_IMPORT_2026-05-07.json +184 -0
  329. package/docs/PAPERCLIP_OPENLIFE_INVESTIGATION.md +85 -0
  330. package/docs/README.md +28 -0
  331. package/docs/RELEASE_ORGANIZATION_PLAN.md +164 -0
  332. package/docs/audit/CLI-EXECUTION-RESULTS.md +113 -0
  333. package/docs/audit/CLI-MATRIX.md +556 -0
  334. package/docs/audit/DOC-PARITY-GAPS.md +351 -0
  335. package/docs/audit/ORCHESTRATOR-MATRIX.md +136 -0
  336. package/docs/audit/TEST-COVERAGE-GAPS.md +334 -0
  337. package/docs/audit/integrations/SKIPPED.md +101 -0
  338. package/docs/autonomous-install.md +79 -0
  339. package/docs/capability-genesis.md +137 -0
  340. package/docs/capability-pack-schema.md +157 -0
  341. package/docs/commands.md +82 -0
  342. package/docs/deep-research-capability.md +114 -0
  343. package/docs/development/typescript-conventions.md +95 -0
  344. package/docs/host-installers.md +68 -0
  345. package/docs/install/aiobuilder.md +70 -0
  346. package/docs/install/claude-code.md +83 -0
  347. package/docs/install/codex.md +64 -0
  348. package/docs/install/gemini-cli.md +64 -0
  349. package/docs/install/runtime-profiles.md +83 -0
  350. package/docs/openlife-agent-os-blueprint.md +114 -0
  351. package/docs/openlife-install-backlog.md +115 -0
  352. package/docs/openlife-install-spec.md +306 -0
  353. package/docs/operations/CLOUD_CUTOVER_AUDIT.md +37 -0
  354. package/docs/operations/PHASE_PROGRESS_CONTINUATION.md +24 -0
  355. package/docs/performance-benchmarks.md +83 -0
  356. package/docs/planning/v1.3-capability-genesis.md +157 -0
  357. package/docs/plans/2026-05-05-admin-interface-professional-dark-premium-plan.md +84 -0
  358. package/docs/plans/2026-05-05-openlife-autonomous-domain-marketplace-masterplan.md +122 -0
  359. package/docs/quickstart.md +60 -0
  360. package/docs/release-process.md +236 -0
  361. package/docs/roadmap/OPENLIFE_MASTER_PLAN_CLOUD_V3.md +97 -0
  362. package/docs/sandboxing-research.md +117 -0
  363. package/docs/stories/epic-feature-audit/1.1.story.md +84 -0
  364. package/docs/stories/epic-feature-audit/1.2.story.md +102 -0
  365. package/docs/stories/epic-feature-audit/1.3.story.md +93 -0
  366. package/docs/stories/epic-feature-audit/1.5.story.md +121 -0
  367. package/docs/stories/epic-feature-audit/1.6.story.md +80 -0
  368. package/docs/stories/epic-feature-completeness/2.1.story.md +70 -0
  369. package/docs/stories/epic-feature-completeness/2.2.story.md +49 -0
  370. package/docs/stories/epic-feature-completeness/2.3.story.md +74 -0
  371. package/docs/stories/epic-feature-completeness/2.4.story.md +71 -0
  372. package/docs/stories/epic-feature-completeness/3.1.story.md +56 -0
  373. package/docs/stories/epic-feature-completeness/3.2.story.md +80 -0
  374. package/docs/stories/epic-feature-completeness/3.3.story.md +68 -0
  375. package/docs/stories/epic-feature-completeness/3.4.story.md +71 -0
  376. package/docs/stories/epic-feature-completeness/3.5.story.md +72 -0
  377. package/docs/stories/epic-feature-completeness/3.6.story.md +69 -0
  378. package/docs/stories/epic-feature-completeness/3.7.story.md +68 -0
  379. package/docs/stories/epic-feature-completeness/3.8.story.md +57 -0
  380. package/docs/toolset-enforcement.md +122 -0
  381. package/docs/v1.4-changelog.md +159 -0
  382. package/docs/v1.5-changelog.md +106 -0
  383. package/docs/v1.5-roadmap.md +121 -0
  384. package/docs/v1.6-changelog.md +67 -0
  385. package/docs/v1.6-roadmap.md +89 -0
  386. package/docs/v1.7-changelog.md +98 -0
  387. package/docs/workflow-schema.md +177 -0
  388. package/package.json +177 -0
  389. package/scripts/clean-test-pollution.js +61 -0
  390. package/scripts/openlife-agent-start.sh +6 -0
  391. package/scripts/openlife-agent.service.example +13 -0
  392. package/scripts/openlife-agent.supervisord.conf.example +8 -0
  393. package/scripts/openlife-autonomous-install.sh +29 -0
  394. package/scripts/postinstall-check.sh +37 -0
@@ -0,0 +1,508 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.Gateway = void 0;
40
+ const telegraf_1 = require("telegraf");
41
+ const filters_1 = require("telegraf/filters");
42
+ const IntentClassifier_1 = require("./IntentClassifier");
43
+ const Gatekeeper_1 = require("./Gatekeeper");
44
+ const VoiceManager_1 = require("./VoiceManager");
45
+ const axios_1 = __importDefault(require("axios"));
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const express_1 = __importDefault(require("express"));
49
+ const GovernanceLayer_1 = require("./GovernanceLayer");
50
+ const WatchdogHeartbeat_1 = require("./util/WatchdogHeartbeat");
51
+ const ToolsetGuard_1 = require("./toolset/ToolsetGuard");
52
+ class Gateway {
53
+ bot = null;
54
+ reasoningMode = (() => {
55
+ const raw = String(process.env.OPENLIFE_REASONING_MODE || 'errors').toLowerCase();
56
+ return raw === 'off' || raw === 'always' ? raw : 'errors';
57
+ })();
58
+ classifier;
59
+ gatekeeper;
60
+ voiceManager;
61
+ app;
62
+ server = null;
63
+ ttsEnabled;
64
+ governance;
65
+ allowedTelegramUserId;
66
+ isShuttingDown = false;
67
+ watchdog = null;
68
+ bootTs = Date.now();
69
+ constructor() {
70
+ this.classifier = new IntentClassifier_1.IntentClassifier();
71
+ this.gatekeeper = new Gatekeeper_1.Gatekeeper();
72
+ this.voiceManager = new VoiceManager_1.VoiceManager();
73
+ this.app = (0, express_1.default)();
74
+ this.app.use(express_1.default.json());
75
+ this.ttsEnabled = (process.env.OPENLIFE_ENABLE_TTS || '').toLowerCase() === 'true';
76
+ this.governance = new GovernanceLayer_1.GovernanceLayer();
77
+ this.allowedTelegramUserId = (process.env.OPENLIFE_TELEGRAM_ALLOWED_USER_ID || '1344110010').trim() || null;
78
+ const token = process.env.TELEGRAM_BOT_TOKEN;
79
+ if (token && token.trim() !== '') {
80
+ this.bot = new telegraf_1.Telegraf(token);
81
+ }
82
+ }
83
+ /**
84
+ * Redact a Telegram bot token in any log line. Public so callers can
85
+ * use the same helper to scrub their own logs. Token shape is
86
+ * `<numeric_id>:<35-char_secret>`; we keep the numeric prefix and
87
+ * mask the rest.
88
+ *
89
+ * Story 4.3 — OpenLife v1.3 Agent OS Integration.
90
+ */
91
+ static redactBotToken(text) {
92
+ return String(text).replace(/(\d{6,12}):[A-Za-z0-9_-]{20,}/g, '$1:[REDACTED]');
93
+ }
94
+ /**
95
+ * Validate the configured TELEGRAM_BOT_TOKEN by calling getMe.
96
+ * Returns `{ ok: true, botId, botUsername }` on success;
97
+ * `{ ok: false, error, status? }` on failure. Never throws.
98
+ * Never logs the token itself.
99
+ *
100
+ * Story 4.3 — OpenLife v1.3 Agent OS Integration.
101
+ */
102
+ async validateBotToken(opts = {}) {
103
+ const token = process.env.TELEGRAM_BOT_TOKEN;
104
+ if (!token || token.trim() === '') {
105
+ return { ok: false, error: 'token_missing' };
106
+ }
107
+ const timeoutMs = opts.timeoutMs ?? 8000;
108
+ const url = `https://api.telegram.org/bot${token}/getMe`;
109
+ try {
110
+ const controller = new AbortController();
111
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
112
+ const res = await fetch(url, { signal: controller.signal });
113
+ clearTimeout(timer);
114
+ if (!res.ok) {
115
+ return { ok: false, error: 'getme_failed', status: res.status };
116
+ }
117
+ const body = await res.json();
118
+ if (!body?.ok || !body.result?.id || !body.result.username) {
119
+ return { ok: false, error: 'invalid_getme_response' };
120
+ }
121
+ return { ok: true, botId: body.result.id, botUsername: body.result.username };
122
+ }
123
+ catch (err) {
124
+ const msg = err instanceof Error ? err.message : String(err);
125
+ return { ok: false, error: 'getme_exception', status: msg.includes('aborted') ? 408 : undefined };
126
+ }
127
+ }
128
+ start() {
129
+ (0, ToolsetGuard_1.assertToolsetAllowed)('gateway', 'Gateway.start');
130
+ const adminUser = process.env.OPENLIFE_ADMIN_USER || 'admin';
131
+ const adminPass = process.env.OPENLIFE_ADMIN_PASS || '';
132
+ const adminAuth = (req, res, next) => {
133
+ if (!adminPass)
134
+ return next();
135
+ const header = String(req.headers.authorization || '');
136
+ if (!header.startsWith('Basic ')) {
137
+ res.setHeader('WWW-Authenticate', 'Basic realm="OpenLife Admin"');
138
+ return res.status(401).json({ ok: false, error: 'auth_required' });
139
+ }
140
+ const decoded = Buffer.from(header.slice(6), 'base64').toString('utf-8');
141
+ const [user, pass] = decoded.split(':');
142
+ if (user !== adminUser || pass !== adminPass) {
143
+ return res.status(403).json({ ok: false, error: 'forbidden' });
144
+ }
145
+ next();
146
+ };
147
+ const triggerUser = (process.env.OPENLIFE_TRIGGER_USER || '').trim();
148
+ const triggerPass = (process.env.OPENLIFE_TRIGGER_PASS || '').trim();
149
+ const triggerAuthEnabled = !!(triggerUser && triggerPass);
150
+ if (!triggerAuthEnabled) {
151
+ console.warn('[GATEWAY] WARNING: /api/v1/trigger sem autenticação. Defina OPENLIFE_TRIGGER_USER e OPENLIFE_TRIGGER_PASS para internet-exposed deploys.');
152
+ }
153
+ const triggerAuth = (req, res, next) => {
154
+ if (!triggerAuthEnabled)
155
+ return next();
156
+ const header = String(req.headers.authorization || '');
157
+ if (!header.startsWith('Basic ')) {
158
+ res.setHeader('WWW-Authenticate', 'Basic realm="OpenLife Trigger"');
159
+ return res.status(401).json({ ok: false, error: 'auth_required' });
160
+ }
161
+ const decoded = Buffer.from(header.slice(6), 'base64').toString('utf-8');
162
+ const sepIdx = decoded.indexOf(':');
163
+ const user = sepIdx >= 0 ? decoded.slice(0, sepIdx) : decoded;
164
+ const pass = sepIdx >= 0 ? decoded.slice(sepIdx + 1) : '';
165
+ if (user !== triggerUser || pass !== triggerPass) {
166
+ return res.status(403).json({ ok: false, error: 'forbidden' });
167
+ }
168
+ next();
169
+ };
170
+ // Configuração do Webhook (Fase 4)
171
+ this.app.post('/api/v1/trigger', triggerAuth, async (req, res) => {
172
+ const payload = req.body;
173
+ console.log('[WEBHOOK] Nova task recebida:', payload);
174
+ // Simula o contexto do Telegram para o pipeline interno do Brain
175
+ const mockCtx = {
176
+ reply: async (text) => console.log('[WEBHOOK-REPLY]', text),
177
+ sendChatAction: async (action) => { },
178
+ message: { from: { id: payload.user_id || 'webhook' }, text: payload.text }
179
+ };
180
+ try {
181
+ await this.processInput(mockCtx, mockCtx.message.from.id.toString(), payload.text);
182
+ res.status(200).json({ status: 'success', message: 'Task enviada ao Córtex' });
183
+ }
184
+ catch (err) {
185
+ res.status(500).json({ status: 'error', error: String(err) });
186
+ }
187
+ });
188
+ this.app.get('/api/v1/admin/teams', adminAuth, (_req, res) => {
189
+ const file = path.join(process.cwd(), '.catalog', 'teams.json');
190
+ const teams = fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf-8')) : [];
191
+ res.status(200).json({ ok: true, teams });
192
+ });
193
+ this.app.get('/api/v1/admin/networks', adminAuth, (_req, res) => {
194
+ const file = path.join(process.cwd(), '.catalog', 'skill-networks.json');
195
+ const networks = fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf-8')) : [];
196
+ res.status(200).json({ ok: true, networks });
197
+ });
198
+ this.app.post('/api/v1/admin/teams/upsert', adminAuth, (req, res) => {
199
+ const body = req.body || {};
200
+ if (!body.id)
201
+ return res.status(400).json({ ok: false, error: 'id obrigatório' });
202
+ const dir = path.join(process.cwd(), '.catalog');
203
+ const file = path.join(dir, 'teams.json');
204
+ fs.mkdirSync(dir, { recursive: true });
205
+ const arr = fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf-8')) : [];
206
+ const next = { id: String(body.id), domain: String(body.domain || 'general'), description: String(body.description || ''), slaProfile: String(body.slaProfile || 'balanced'), members: Array.isArray(body.members) ? body.members : [] };
207
+ const idx = arr.findIndex((x) => x.id === next.id);
208
+ if (idx >= 0)
209
+ arr[idx] = { ...arr[idx], ...next };
210
+ else
211
+ arr.push(next);
212
+ fs.writeFileSync(file, JSON.stringify(arr, null, 2), 'utf-8');
213
+ res.status(200).json({ ok: true, team: next });
214
+ });
215
+ this.app.post('/api/v1/admin/networks/upsert', adminAuth, (req, res) => {
216
+ const body = req.body || {};
217
+ if (!body.id)
218
+ return res.status(400).json({ ok: false, error: 'id obrigatório' });
219
+ const dir = path.join(process.cwd(), '.catalog');
220
+ const file = path.join(dir, 'skill-networks.json');
221
+ fs.mkdirSync(dir, { recursive: true });
222
+ const arr = fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf-8')) : [];
223
+ const next = { id: String(body.id), domain: String(body.domain || 'general'), nodes: Array.isArray(body.nodes) ? body.nodes : [] };
224
+ const idx = arr.findIndex((x) => x.id === next.id);
225
+ if (idx >= 0)
226
+ arr[idx] = { ...arr[idx], ...next };
227
+ else
228
+ arr.push(next);
229
+ fs.writeFileSync(file, JSON.stringify(arr, null, 2), 'utf-8');
230
+ res.status(200).json({ ok: true, network: next });
231
+ });
232
+ this.app.get('/api/v1/admin/status', adminAuth, (_req, res) => {
233
+ res.status(200).json({ ok: true, service: 'openlife-gateway', mode: this.reasoningMode, telegram: !!this.bot, now: new Date().toISOString() });
234
+ });
235
+ this.app.get('/admin', adminAuth, (_req, res) => {
236
+ res.sendFile(path.join(process.cwd(), 'src', 'admin_panel.html'));
237
+ });
238
+ this.app.get('/', (_req, res) => {
239
+ res.status(200).json({ ok: true, service: 'openlife-gateway' });
240
+ });
241
+ // Story 6.6 — watchdog/health endpoint for external supervisors
242
+ this.app.get('/health', (_req, res) => {
243
+ const uptime_s = Math.floor((Date.now() - this.bootTs) / 1000);
244
+ res.status(200).json({
245
+ ok: true,
246
+ service: 'openlife-gateway',
247
+ uptime_s,
248
+ pid: process.pid,
249
+ telegram: !!this.bot,
250
+ shutting_down: this.isShuttingDown,
251
+ ts: new Date().toISOString(),
252
+ });
253
+ });
254
+ // Heartbeat file emission (best-effort; opt-out via OPENLIFE_HEARTBEAT_DISABLE)
255
+ if ((process.env.OPENLIFE_HEARTBEAT_DISABLE || '').toLowerCase() !== 'true') {
256
+ try {
257
+ const intervalMs = Number(process.env.OPENLIFE_HEARTBEAT_INTERVAL_MS || 30_000);
258
+ this.watchdog = new WatchdogHeartbeat_1.WatchdogHeartbeat({ intervalMs });
259
+ this.watchdog.start();
260
+ }
261
+ catch (err) {
262
+ console.error('[GATEWAY] Failed to start watchdog heartbeat:', err);
263
+ }
264
+ }
265
+ const port = Number(process.env.PORT || 3000);
266
+ this.server = this.app.listen(port, () => {
267
+ console.log(`[GATEWAY] Servidor Express de Webhooks rodando na porta ${port}`);
268
+ });
269
+ if (!this.bot) {
270
+ console.log("[GATEWAY] Telegram Token não fornecido. Rodando apenas em modo CLI local.");
271
+ return;
272
+ }
273
+ console.log("[GATEWAY] Inicializando receptor Multimodal do Telegram...");
274
+ this.bot.catch((err, ctx) => {
275
+ console.error('[GATEWAY] Erro global no Telegram update handler:', err);
276
+ void this.safeReply(ctx, 'Desculpe — houve timeout no processamento. Tente novamente em instantes.');
277
+ });
278
+ // 1. Processamento de TEXTO
279
+ this.bot.on((0, filters_1.message)('text'), async (ctx) => {
280
+ if (ctx.message.from.is_bot)
281
+ return;
282
+ const userId = ctx.message.from.id.toString();
283
+ const text = ctx.message.text;
284
+ console.log(`\n[TELEGRAM] Nova mensagem de texto de ${userId}: "${text}"`);
285
+ try {
286
+ await this.processInput(ctx, userId, text);
287
+ }
288
+ catch (err) {
289
+ console.error('[GATEWAY] Erro no handler de texto:', err);
290
+ }
291
+ });
292
+ // 2. Processamento de ÁUDIO (Ouvidos)
293
+ this.bot.on((0, filters_1.message)('voice'), async (ctx) => {
294
+ if (ctx.message.from.is_bot)
295
+ return;
296
+ const userId = ctx.message.from.id.toString();
297
+ console.log(`\n[TELEGRAM] Novo Áudio recebido de ${userId}`);
298
+ await ctx.sendChatAction('record_voice');
299
+ try {
300
+ // Aqui o Telegram nos dá o Link do arquivo OGG.
301
+ // O VoiceManager vai processar (via Whisper ou preparar para Gemini 2.5)
302
+ const voiceFileId = ctx.message.voice.file_id;
303
+ const fileLink = await ctx.telegram.getFileLink(voiceFileId);
304
+ const transcribedText = await this.voiceManager.processAudioInput(fileLink.toString());
305
+ await ctx.reply(`🎙️ (Ouvido): "${transcribedText}"`);
306
+ await this.processInput(ctx, userId, transcribedText);
307
+ }
308
+ catch (err) {
309
+ console.error("[GATEWAY] Erro ao processar áudio:", err);
310
+ await ctx.reply("Desculpe, não consegui entender o áudio no momento.");
311
+ }
312
+ });
313
+ // 3. Processamento de IMAGEM (Olhos)
314
+ this.bot.on((0, filters_1.message)('photo'), async (ctx) => {
315
+ if (ctx.message.from.is_bot)
316
+ return;
317
+ const userId = ctx.message.from.id.toString();
318
+ console.log(`\n[TELEGRAM] Nova Imagem (Visão) recebida de ${userId}`);
319
+ await ctx.sendChatAction('typing');
320
+ try {
321
+ const photo = ctx.message.photo.pop(); // Pega a maior resolução
322
+ if (!photo)
323
+ throw new Error("Foto inválida.");
324
+ const fileLink = await ctx.telegram.getFileLink(photo.file_id);
325
+ // Download the image locally
326
+ const tempDir = path.join(process.cwd(), '.temp_images');
327
+ if (!fs.existsSync(tempDir))
328
+ fs.mkdirSync(tempDir, { recursive: true });
329
+ const localPath = path.join(tempDir, `${photo.file_id}.jpg`);
330
+ const response = await (0, axios_1.default)({ url: fileLink.toString(), responseType: 'stream' });
331
+ await new Promise((resolve, reject) => {
332
+ response.data.pipe(fs.createWriteStream(localPath))
333
+ .on('finish', resolve)
334
+ .on('error', reject);
335
+ });
336
+ const caption = ctx.message.caption || "Descreva e analise esta imagem enviada pelo usuário.";
337
+ // O texto enviado com a imagem + a tag do arquivo local vai pro Córtex (Brain.ts resolverá)
338
+ this.voiceManager.logMediaRoute('vision', 'gemini', 'success', 'prefer_gemini_for_media=true');
339
+ const multimodalInput = `${caption}\n[LOCAL_ATTACHMENT: ${localPath}]`;
340
+ await this.processInput(ctx, userId, multimodalInput);
341
+ }
342
+ catch (err) {
343
+ console.error("[GATEWAY] Erro ao processar imagem:", err);
344
+ await ctx.reply("Erro no módulo de visão ao baixar a imagem.");
345
+ }
346
+ });
347
+ this.bot.launch().catch((err) => {
348
+ const msg = err instanceof Error ? err.message : String(err);
349
+ if (msg.includes('409') || msg.includes('terminated by other getUpdates request')) {
350
+ console.error('[GATEWAY] Telegram 409 Conflict: outra instância está conectada com este bot. Mantendo processo vivo para healthcheck; Telegram polling fica desativado nesta instância.');
351
+ return;
352
+ }
353
+ console.error('[GATEWAY] Falha ao iniciar Telegram bot:', err);
354
+ process.exit(1);
355
+ });
356
+ console.log("[GATEWAY] Telegram Bot escutando com suporte Multimodal (Voz/Visão).");
357
+ }
358
+ async shutdown(reason = 'manual') {
359
+ if (this.isShuttingDown)
360
+ return;
361
+ this.isShuttingDown = true;
362
+ console.log(`[GATEWAY] Iniciando shutdown gracioso (motivo: ${reason})...`);
363
+ if (this.watchdog) {
364
+ try {
365
+ this.watchdog.emit(); // final beat so supervisors see fresh ts before we go
366
+ this.watchdog.stop();
367
+ }
368
+ catch (err) {
369
+ console.error('[GATEWAY] Falha ao parar watchdog heartbeat:', err);
370
+ }
371
+ }
372
+ try {
373
+ this.flushAgentQueue();
374
+ }
375
+ catch (err) {
376
+ console.error('[GATEWAY] Falha ao flushar fila durante shutdown:', err);
377
+ }
378
+ if (this.bot) {
379
+ try {
380
+ this.bot.stop(reason);
381
+ }
382
+ catch (err) {
383
+ console.error('[GATEWAY] Falha ao parar Telegraf bot:', err);
384
+ }
385
+ }
386
+ if (this.server) {
387
+ await new Promise((resolve) => {
388
+ this.server.close((err) => {
389
+ if (err)
390
+ console.error('[GATEWAY] Falha ao fechar servidor Express:', err);
391
+ resolve();
392
+ });
393
+ });
394
+ this.server = null;
395
+ }
396
+ console.log('[GATEWAY] Graceful shutdown complete');
397
+ }
398
+ flushAgentQueue() {
399
+ const stateDir = process.env.OPENLIFE_STATE_DIR || path.join(process.cwd(), '.openlife');
400
+ if (!fs.existsSync(stateDir)) {
401
+ fs.mkdirSync(stateDir, { recursive: true });
402
+ }
403
+ const queueFile = path.join(stateDir, 'agent-queue.json');
404
+ if (!fs.existsSync(queueFile)) {
405
+ fs.writeFileSync(queueFile, JSON.stringify({ items: [], lastFlushedAt: new Date().toISOString() }, null, 2), 'utf-8');
406
+ return;
407
+ }
408
+ try {
409
+ const raw = JSON.parse(fs.readFileSync(queueFile, 'utf-8'));
410
+ raw.lastFlushedAt = new Date().toISOString();
411
+ fs.writeFileSync(queueFile, JSON.stringify(raw, null, 2), 'utf-8');
412
+ }
413
+ catch {
414
+ fs.writeFileSync(queueFile, JSON.stringify({ items: [], lastFlushedAt: new Date().toISOString(), note: 'recreated_after_parse_error' }, null, 2), 'utf-8');
415
+ }
416
+ }
417
+ async processTextForTest(userId, text) {
418
+ let finalReply = '';
419
+ const testCtx = {
420
+ sendChatAction: async (_action) => { },
421
+ reply: async (message) => { finalReply = message; },
422
+ sendVoice: async (_source, options) => {
423
+ finalReply = options?.caption || '[voice_sent]';
424
+ }
425
+ };
426
+ await this.processInput(testCtx, userId, text);
427
+ return finalReply;
428
+ }
429
+ async processImageForTest(userId, imagePath, caption = 'Descreva esta imagem.') {
430
+ (0, ToolsetGuard_1.assertToolsetAllowed)('vision', 'Gateway.processImageForTest');
431
+ const multimodalInput = `${caption}\n[LOCAL_ATTACHMENT: ${imagePath}]`;
432
+ return this.processTextForTest(userId, multimodalInput);
433
+ }
434
+ isAuthorizedUser(userId) {
435
+ if (!this.allowedTelegramUserId)
436
+ return true;
437
+ return userId === this.allowedTelegramUserId;
438
+ }
439
+ async processInput(ctx, userId, text) {
440
+ if (!this.isAuthorizedUser(userId)) {
441
+ console.warn(`[GATEWAY] Acesso negado para userId=${userId}`);
442
+ await this.safeReply(ctx, 'Acesso negado por policy de segurança deste bot.');
443
+ return;
444
+ }
445
+ const stopTyping = this.startTypingIndicator(ctx);
446
+ const trace = [];
447
+ try {
448
+ trace.push(`🔎 classify_intent: "${text.slice(0, 80).replace(/\n/g, ' ')}${text.length > 80 ? '...' : ''}"`);
449
+ const task = await this.classifier.classify(text);
450
+ trace.push(`🧭 route_task: "${String(task.intent)}"`);
451
+ const response = await this.gatekeeper.routeTask(task, text, userId);
452
+ trace.push(`✅ finalize_reply: "${String(task.intent)}"`);
453
+ const safeResponse = this.governance.redact(response);
454
+ const finalResponse = this.reasoningMode === 'always' ? `${trace.join('\n')}\n\n${safeResponse}` : safeResponse;
455
+ if (this.ttsEnabled && typeof ctx.sendVoice === 'function') {
456
+ try {
457
+ const audioPath = await this.voiceManager.generateSpeech(finalResponse);
458
+ await ctx.sendVoice({ source: audioPath }, { caption: finalResponse });
459
+ }
460
+ catch (ttsError) {
461
+ console.log("[GATEWAY] Fallback para texto (Erro no TTS).", ttsError);
462
+ await this.safeReply(ctx, finalResponse);
463
+ }
464
+ }
465
+ else {
466
+ await this.safeReply(ctx, finalResponse);
467
+ }
468
+ }
469
+ catch (err) {
470
+ console.error("[GATEWAY] Erro ao orquestrar a tarefa:", err);
471
+ const errMsg = this.reasoningMode !== 'off'
472
+ ? `${trace.join('\n')}\n\n❌ error: "${err instanceof Error ? err.message : String(err)}"\n\nErro no córtex ao processar a solicitação.`
473
+ : "Erro no córtex ao processar a solicitação.";
474
+ await this.safeReply(ctx, errMsg);
475
+ }
476
+ finally {
477
+ stopTyping();
478
+ }
479
+ }
480
+ startTypingIndicator(ctx) {
481
+ let stopped = false;
482
+ const sendTyping = async () => {
483
+ if (stopped)
484
+ return;
485
+ try {
486
+ await ctx.sendChatAction('typing');
487
+ }
488
+ catch (err) {
489
+ console.error('[GATEWAY] Falha ao enviar indicador de digitação:', err);
490
+ }
491
+ };
492
+ void sendTyping();
493
+ const timer = setInterval(() => { void sendTyping(); }, 4000);
494
+ return () => {
495
+ stopped = true;
496
+ clearInterval(timer);
497
+ };
498
+ }
499
+ async safeReply(ctx, text) {
500
+ try {
501
+ await ctx.reply(text);
502
+ }
503
+ catch (replyErr) {
504
+ console.error('[GATEWAY] Falha ao responder no Telegram:', replyErr);
505
+ }
506
+ }
507
+ }
508
+ exports.Gateway = Gateway;
@@ -0,0 +1,66 @@
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.GovernanceConsentStore = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const AtomicWriter_1 = require("./util/AtomicWriter");
40
+ class GovernanceConsentStore {
41
+ root;
42
+ filePath;
43
+ constructor(root = process.cwd()) {
44
+ this.root = root;
45
+ this.filePath = path.join(this.root, '.openlife', 'governance-consents.json');
46
+ fs.mkdirSync(path.dirname(this.filePath), { recursive: true });
47
+ }
48
+ read() {
49
+ if (!fs.existsSync(this.filePath))
50
+ return [];
51
+ return JSON.parse(fs.readFileSync(this.filePath, 'utf-8'));
52
+ }
53
+ write(records) {
54
+ (0, AtomicWriter_1.writeJsonAtomic)(this.filePath, records);
55
+ }
56
+ approve(userId, scope = 'destructive-action') {
57
+ const records = this.read().filter((record) => record.userId !== userId || record.scope !== scope);
58
+ records.push({ userId, scope, approvedAt: new Date().toISOString() });
59
+ this.write(records);
60
+ }
61
+ hasRecentApproval(userId, scope = 'destructive-action', windowMinutes = 15) {
62
+ const threshold = Date.now() - windowMinutes * 60 * 1000;
63
+ return this.read().some((record) => record.userId === userId && record.scope === scope && new Date(record.approvedAt).getTime() >= threshold);
64
+ }
65
+ }
66
+ exports.GovernanceConsentStore = GovernanceConsentStore;