claude-smart 0.2.44 → 0.2.46

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 (323) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/README.md +34 -5
  3. package/bin/claude-smart.js +295 -5
  4. package/package.json +22 -3
  5. package/plugin/.claude-plugin/plugin.json +4 -2
  6. package/plugin/.codex-plugin/plugin.json +1 -1
  7. package/plugin/README.md +22 -2
  8. package/plugin/commands/clear-all.md +1 -0
  9. package/plugin/commands/dashboard.md +1 -0
  10. package/plugin/commands/learn.md +1 -0
  11. package/plugin/commands/restart.md +1 -0
  12. package/plugin/commands/show.md +1 -0
  13. package/plugin/dashboard/app/configure/env/page.tsx +40 -14
  14. package/plugin/dashboard/app/configure/server/page.tsx +51 -1
  15. package/plugin/dashboard/app/preferences/[id]/page.tsx +8 -8
  16. package/plugin/dashboard/app/skills/project/[id]/page.tsx +7 -3
  17. package/plugin/dashboard/app/skills/shared/[id]/page.tsx +10 -3
  18. package/plugin/dashboard/lib/claude-settings-file.ts +20 -10
  19. package/plugin/dashboard/lib/reflexio-client.ts +16 -0
  20. package/plugin/dashboard/lib/status.ts +10 -3
  21. package/plugin/dashboard/lib/types.ts +18 -6
  22. package/plugin/hooks/codex-hooks.json +0 -1
  23. package/plugin/opencode/assistant-buffer.ts +108 -0
  24. package/plugin/opencode/dist/assistant-buffer.js +96 -0
  25. package/plugin/opencode/dist/internal.js +12 -0
  26. package/plugin/opencode/dist/payload.js +85 -0
  27. package/plugin/opencode/dist/server.mjs +158 -0
  28. package/plugin/opencode/internal.ts +18 -0
  29. package/plugin/opencode/package.json +3 -0
  30. package/plugin/opencode/payload.ts +90 -0
  31. package/plugin/opencode/server.mts +174 -0
  32. package/plugin/opencode/tsconfig.json +13 -0
  33. package/plugin/pyproject.toml +20 -3
  34. package/plugin/scripts/_lib.sh +77 -29
  35. package/plugin/scripts/backend-service.sh +27 -5
  36. package/plugin/scripts/dashboard-service.sh +7 -5
  37. package/plugin/scripts/ensure-plugin-root.sh +4 -4
  38. package/plugin/scripts/hook_entry.sh +3 -3
  39. package/plugin/scripts/opencode-claude-compat +4 -0
  40. package/plugin/scripts/opencode-claude-compat.cmd +3 -0
  41. package/plugin/scripts/opencode-claude-compat.js +225 -0
  42. package/plugin/scripts/smart-install.sh +10 -8
  43. package/plugin/src/README.md +1 -1
  44. package/plugin/src/claude_smart/cli.py +304 -6
  45. package/plugin/src/claude_smart/env_config.py +12 -4
  46. package/plugin/src/claude_smart/events/session_start.py +26 -7
  47. package/plugin/src/claude_smart/events/stop.py +1 -1
  48. package/plugin/src/claude_smart/ids.py +1 -1
  49. package/plugin/src/claude_smart/reflexio_adapter.py +5 -5
  50. package/plugin/src/claude_smart/runtime.py +7 -1
  51. package/plugin/uv.lock +1 -1
  52. package/plugin/vendor/reflexio/.env.example +54 -30
  53. package/plugin/vendor/reflexio/README.md +14 -8
  54. package/plugin/vendor/reflexio/pyproject.toml +13 -1
  55. package/plugin/vendor/reflexio/reflexio/README.md +1 -0
  56. package/plugin/vendor/reflexio/reflexio/cli/README.md +9 -7
  57. package/plugin/vendor/reflexio/reflexio/cli/__main__.py +10 -1
  58. package/plugin/vendor/reflexio/reflexio/cli/bootstrap_config.py +22 -5
  59. package/plugin/vendor/reflexio/reflexio/cli/commands/interactions.py +34 -4
  60. package/plugin/vendor/reflexio/reflexio/cli/commands/profiles.py +12 -7
  61. package/plugin/vendor/reflexio/reflexio/cli/commands/services.py +13 -6
  62. package/plugin/vendor/reflexio/reflexio/cli/commands/setup_cmd.py +210 -50
  63. package/plugin/vendor/reflexio/reflexio/cli/commands/shortcuts.py +15 -2
  64. package/plugin/vendor/reflexio/reflexio/cli/env_loader.py +292 -22
  65. package/plugin/vendor/reflexio/reflexio/cli/log_format.py +29 -4
  66. package/plugin/vendor/reflexio/reflexio/cli/run_services.py +17 -8
  67. package/plugin/vendor/reflexio/reflexio/cli/stop_services.py +13 -10
  68. package/plugin/vendor/reflexio/reflexio/client/client.py +57 -13
  69. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/README.md +135 -257
  70. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/npm/openclaw-smart/bin/openclaw-smart.js +13 -0
  71. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/npm/openclaw-smart/package.json +15 -0
  72. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/README.md +38 -0
  73. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/index.ts +151 -110
  74. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/openclaw.plugin.json +20 -10
  75. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/package.json +28 -6
  76. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/pyproject.toml +42 -0
  77. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/_lib.sh +371 -0
  78. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/backend-log-runner.sh +33 -0
  79. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/backend-service.sh +271 -0
  80. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/cli.sh +68 -0
  81. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/dashboard-open.sh +15 -0
  82. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/ensure-plugin-root.sh +84 -0
  83. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/hook_entry.sh +106 -0
  84. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/npm-cli.js +219 -0
  85. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/smart-install.sh +269 -0
  86. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/clear-all/SKILL.md +8 -0
  87. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/dashboard/SKILL.md +8 -0
  88. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/learn/SKILL.md +10 -0
  89. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/reflexio/SKILL.md +15 -44
  90. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/restart/SKILL.md +6 -0
  91. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/show/SKILL.md +8 -0
  92. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/cli.py +634 -0
  93. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/context_format.py +224 -0
  94. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/context_inject.py +79 -0
  95. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/__init__.py +0 -0
  96. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/after_tool_call.py +160 -0
  97. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/agent_end.py +187 -0
  98. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/before_prompt_build.py +69 -0
  99. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/before_tool_call.py +30 -0
  100. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/session_end.py +36 -0
  101. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/session_start.py +130 -0
  102. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/hook.py +131 -0
  103. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/ids.py +94 -0
  104. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/internal_call.py +75 -0
  105. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/oc_cite.py +196 -0
  106. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/optimizer_assistant.py +272 -0
  107. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/publish.py +96 -0
  108. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/query_compose.py +66 -0
  109. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/reflexio_adapter.py +336 -0
  110. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/runtime.py +47 -0
  111. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/stall_banner.py +61 -0
  112. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/state.py +323 -0
  113. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/__init__.py +0 -0
  114. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/__init__.py +0 -0
  115. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_e2e_session_loop.py +190 -0
  116. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_publish_to_local_reflexio_integration.py +112 -0
  117. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_recursion_guard_integration.py +86 -0
  118. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_search_inject_integration.py +144 -0
  119. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_cli.py +184 -0
  120. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_after_tool_call.py +142 -0
  121. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_agent_end.py +233 -0
  122. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_before_prompt_build.py +116 -0
  123. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_before_tool_call.py +35 -0
  124. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_session_end.py +47 -0
  125. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_session_start.py +109 -0
  126. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_hook_dispatch.py +117 -0
  127. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_ids.py +41 -0
  128. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_internal_call.py +50 -0
  129. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_oc_cite.py +88 -0
  130. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_publish.py +48 -0
  131. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_query_compose.py +48 -0
  132. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_reflexio_adapter.py +188 -0
  133. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_runtime.py +41 -0
  134. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_state.py +235 -0
  135. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests-ts/__mocks__/plugin-entry-stub.ts +6 -0
  136. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests-ts/test_npm_cli.test.ts +56 -0
  137. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests-ts/test_shim_dispatch.test.ts +171 -0
  138. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tsconfig.build.json +18 -0
  139. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/{tsconfig.json → plugin/tsconfig.json} +2 -2
  140. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/uv.lock +3835 -0
  141. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/vitest.config.ts +18 -0
  142. package/plugin/vendor/reflexio/reflexio/lib/_agent_playbook.py +238 -10
  143. package/plugin/vendor/reflexio/reflexio/lib/_config.py +11 -4
  144. package/plugin/vendor/reflexio/reflexio/lib/_generation.py +16 -5
  145. package/plugin/vendor/reflexio/reflexio/lib/_lineage_parity_readers.py +187 -0
  146. package/plugin/vendor/reflexio/reflexio/lib/_profiles.py +198 -6
  147. package/plugin/vendor/reflexio/reflexio/lib/_reflection.py +1 -1
  148. package/plugin/vendor/reflexio/reflexio/lib/_search.py +29 -20
  149. package/plugin/vendor/reflexio/reflexio/lib/_user_playbook.py +2 -1
  150. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/entities.py +127 -38
  151. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/enums.py +4 -0
  152. package/plugin/vendor/reflexio/reflexio/models/api_schema/eval_overview_schema.py +64 -41
  153. package/plugin/vendor/reflexio/reflexio/models/api_schema/internal_schema.py +19 -0
  154. package/plugin/vendor/reflexio/reflexio/models/api_schema/pending_tool_call_schema.py +12 -5
  155. package/plugin/vendor/reflexio/reflexio/models/api_schema/retriever_schema.py +52 -0
  156. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/converters.py +5 -1
  157. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/entities.py +5 -1
  158. package/plugin/vendor/reflexio/reflexio/models/config_schema.py +88 -7
  159. package/plugin/vendor/reflexio/reflexio/models/structured_output.py +148 -0
  160. package/plugin/vendor/reflexio/reflexio/server/OVERVIEW.md +3 -3
  161. package/plugin/vendor/reflexio/reflexio/server/README.md +45 -32
  162. package/plugin/vendor/reflexio/reflexio/server/__init__.py +29 -5
  163. package/plugin/vendor/reflexio/reflexio/server/__main__.py +2 -2
  164. package/plugin/vendor/reflexio/reflexio/server/_auth.py +65 -2
  165. package/plugin/vendor/reflexio/reflexio/server/api.py +734 -85
  166. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/precondition_checks.py +7 -0
  167. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/request_context.py +3 -1
  168. package/plugin/vendor/reflexio/reflexio/server/billing_meter.py +173 -0
  169. package/plugin/vendor/reflexio/reflexio/server/billing_signals.py +64 -0
  170. package/plugin/vendor/reflexio/reflexio/server/cache/reflexio_cache.py +46 -16
  171. package/plugin/vendor/reflexio/reflexio/server/env_utils.py +65 -0
  172. package/plugin/vendor/reflexio/reflexio/server/llm/embedding_service.py +19 -4
  173. package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +264 -77
  174. package/plugin/vendor/reflexio/reflexio/server/llm/llm_utils.py +69 -7
  175. package/plugin/vendor/reflexio/reflexio/server/llm/providers/embedding_service_provider.py +75 -16
  176. package/plugin/vendor/reflexio/reflexio/server/llm/providers/openclaw_provider.py +280 -0
  177. package/plugin/vendor/reflexio/reflexio/server/llm/token_accounting.py +48 -0
  178. package/plugin/vendor/reflexio/reflexio/server/llm/tools.py +107 -17
  179. package/plugin/vendor/reflexio/reflexio/server/operation_limiter.py +360 -4
  180. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.6.0.prompt.md +1 -1
  181. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.7.0.prompt.md +85 -0
  182. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.2.0.prompt.md +1 -1
  183. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.3.0.prompt.md +253 -0
  184. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.2.prompt.md +1 -1
  185. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.3.prompt.md +74 -0
  186. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.3.prompt.md +1 -1
  187. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.3.0.prompt.md +266 -0
  188. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.4.0.prompt.md +266 -0
  189. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.3.0.prompt.md +1 -1
  190. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.4.0.prompt.md +137 -0
  191. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.2.0.prompt.md +1 -1
  192. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.3.0.prompt.md +34 -0
  193. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.0.0.prompt.md +5 -12
  194. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.1.0.prompt.md +5 -12
  195. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.2.0.prompt.md +155 -0
  196. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/tagging/v1.0.0.prompt.md +23 -0
  197. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_manager.py +89 -32
  198. package/plugin/vendor/reflexio/reflexio/server/services/README.md +26 -11
  199. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/README.md +22 -0
  200. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/__init__.py +1 -0
  201. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_constants.py +4 -2
  202. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_utils.py +1 -0
  203. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/components/__init__.py +7 -0
  204. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{agent_success_evaluator.py → components/evaluator.py} +3 -16
  205. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/regen_jobs.py +28 -72
  206. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{group_evaluation_runner.py → runner.py} +12 -10
  207. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{delayed_group_evaluator.py → scheduler.py} +10 -2
  208. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{agent_success_evaluation_service.py → service.py} +36 -1
  209. package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +160 -0
  210. package/plugin/vendor/reflexio/reflexio/server/services/configurator/base_configurator.py +5 -0
  211. package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +1 -1
  212. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/README.md +9 -0
  213. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/components/__init__.py +0 -0
  214. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{rule_attribution.py → components/rule_attribution.py} +10 -9
  215. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/eval_sampler.py +15 -24
  216. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/service.py +238 -164
  217. package/plugin/vendor/reflexio/reflexio/server/services/extraction/README.md +31 -0
  218. package/plugin/vendor/reflexio/reflexio/server/services/extraction/outcome.py +13 -3
  219. package/plugin/vendor/reflexio/reflexio/server/services/extraction/pending_tool_call_dispatch.py +3 -2
  220. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resumable_agent.py +32 -118
  221. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_worker.py +39 -16
  222. package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +105 -23
  223. package/plugin/vendor/reflexio/reflexio/server/services/lineage/__init__.py +0 -0
  224. package/plugin/vendor/reflexio/reflexio/server/services/lineage/gc_scheduler.py +193 -0
  225. package/plugin/vendor/reflexio/reflexio/server/services/lineage/resolve.py +98 -0
  226. package/plugin/vendor/reflexio/reflexio/server/services/operation_state_utils.py +26 -0
  227. package/plugin/vendor/reflexio/reflexio/server/services/playbook/README.md +11 -12
  228. package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/__init__.py +5 -0
  229. package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_aggregator.py → components/aggregator.py} +316 -178
  230. package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_consolidator.py → components/consolidator.py} +168 -62
  231. package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_extractor.py → components/extractor.py} +5 -1
  232. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_edit_apply.py +74 -0
  233. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_utils.py +33 -3
  234. package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_generation_service.py → service.py} +121 -19
  235. package/plugin/vendor/reflexio/reflexio/server/services/playbook/user_detail_stripping.py +84 -0
  236. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/README.md +10 -0
  237. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/models.py +2 -1
  238. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/optimizer.py +178 -30
  239. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/README.md +9 -0
  240. package/plugin/vendor/reflexio/reflexio/server/services/profile/components/__init__.py +17 -0
  241. package/plugin/vendor/reflexio/reflexio/server/services/profile/{profile_deduplicator.py → components/consolidator.py} +7 -6
  242. package/plugin/vendor/reflexio/reflexio/server/services/profile/{profile_extractor.py → components/extractor.py} +30 -22
  243. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service_utils.py +6 -13
  244. package/plugin/vendor/reflexio/reflexio/server/services/profile/{profile_generation_service.py → service.py} +32 -50
  245. package/plugin/vendor/reflexio/reflexio/server/services/reflection/__init__.py +4 -8
  246. package/plugin/vendor/reflexio/reflexio/server/services/reflection/components/__init__.py +7 -0
  247. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service_utils.py +12 -1
  248. package/plugin/vendor/reflexio/reflexio/server/services/reflection/{reflection_service.py → service.py} +36 -16
  249. package/plugin/vendor/reflexio/reflexio/server/services/retrieval/relevance_floor.py +83 -6
  250. package/plugin/vendor/reflexio/reflexio/server/services/service_utils.py +36 -1
  251. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/README.md +8 -0
  252. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/outcome.py +1 -2
  253. package/plugin/vendor/reflexio/reflexio/server/services/storage/error.py +27 -0
  254. package/plugin/vendor/reflexio/reflexio/server/services/storage/retention.py +9 -9
  255. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +2 -0
  256. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_agent_run.py +4 -1
  257. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +642 -197
  258. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +61 -104
  259. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_lineage.py +628 -0
  260. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_operations.py +38 -6
  261. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_playbook.py +978 -184
  262. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +519 -128
  263. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +77 -3
  264. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_shadow_verdicts.py +23 -9
  265. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_stall_state.py +5 -2
  266. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +131 -20
  267. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_agent_run.py +2 -8
  268. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_base.py +5 -0
  269. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_extras.py +36 -53
  270. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_lineage.py +215 -0
  271. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_operations.py +20 -0
  272. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_playbook.py +243 -7
  273. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_profiles.py +121 -1
  274. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_requests.py +60 -0
  275. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_retrieval_log.py +51 -0
  276. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_shadow_verdicts.py +17 -0
  277. package/plugin/vendor/reflexio/reflexio/server/services/tagging/README.md +8 -0
  278. package/plugin/vendor/reflexio/reflexio/server/services/tagging/__init__.py +1 -0
  279. package/plugin/vendor/reflexio/reflexio/server/services/tagging/service.py +200 -0
  280. package/plugin/vendor/reflexio/reflexio/server/services/tagging/tagging_scheduler.py +149 -0
  281. package/plugin/vendor/reflexio/reflexio/server/services/unified_search_service.py +229 -32
  282. package/plugin/vendor/reflexio/reflexio/server/site_var/README.md +2 -1
  283. package/plugin/vendor/reflexio/reflexio/server/site_var/feature_flags.py +120 -1
  284. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/feature_flags.json +4 -0
  285. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/search_settings.json +5 -0
  286. package/plugin/vendor/reflexio/reflexio/server/tracing.py +30 -0
  287. package/plugin/vendor/reflexio/reflexio/server/usage_metrics.py +18 -0
  288. package/plugin/vendor/reflexio/reflexio/test_support/llm_mock.py +61 -26
  289. package/plugin/vendor/reflexio/reflexio/test_support/llm_model_registry.py +41 -4
  290. package/scripts/setup-claude-smart.sh +8 -3
  291. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/TESTING.md +0 -517
  292. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/hook/handler.js +0 -473
  293. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package-lock.json +0 -2156
  294. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package.json +0 -18
  295. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/handler.ts +0 -241
  296. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/setup.ts +0 -140
  297. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/publish.ts +0 -113
  298. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/search.ts +0 -52
  299. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/server.ts +0 -103
  300. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/sqlite-buffer.ts +0 -156
  301. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/user-id.ts +0 -134
  302. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/rules/reflexio.md +0 -24
  303. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/publish_clawhub.sh +0 -278
  304. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/references/HOOK.md +0 -164
  305. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/install.sh +0 -36
  306. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/uninstall.sh +0 -35
  307. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/publish.test.ts +0 -27
  308. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/search.test.ts +0 -31
  309. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/server.test.ts +0 -42
  310. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/setup.test.ts +0 -49
  311. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/sqlite-buffer.test.ts +0 -91
  312. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/user-id.test.ts +0 -50
  313. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/vitest.config.ts +0 -13
  314. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/group_aggregation.py +0 -192
  315. package/plugin/vendor/reflexio/reflexio/server/services/extraction/invariants.py +0 -303
  316. package/plugin/vendor/reflexio/reflexio/server/services/extraction/plan.py +0 -138
  317. package/plugin/vendor/reflexio/reflexio/server/services/extraction/tools.py +0 -1125
  318. /package/plugin/vendor/reflexio/reflexio/integrations/{__init__.py → openclaw/plugin/src/openclaw_smart/__init__.py} +0 -0
  319. /package/plugin/vendor/reflexio/reflexio/integrations/openclaw/{types → plugin/types}/openclaw.d.ts +0 -0
  320. /package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{distribution.py → components/distribution.py} +0 -0
  321. /package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{hero_state.py → components/hero_state.py} +0 -0
  322. /package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{shadow_aggregation.py → components/shadow_aggregation.py} +0 -0
  323. /package/plugin/vendor/reflexio/reflexio/server/services/reflection/{reflection_extractor.py → components/extractor.py} +0 -0
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env bash
2
+ # Wrapper for slash commands that invoke the openclaw_smart CLI via uv.
3
+ # openClaw runs `!` bash directives in slash command .md files in a
4
+ # non-interactive, non-login shell that does NOT source ~/.zshrc or
5
+ # ~/.bash_profile. As a result, binaries installed by smart-install.sh
6
+ # at ~/.local/bin (e.g. uv from the astral.sh installer) are invisible
7
+ # to those directives until the user manually re-sources their shell rc.
8
+ # This wrapper bootstraps PATH the same way hook_entry.sh does so the
9
+ # slash commands work on a fresh install.
10
+ set -eu
11
+
12
+ HERE="$(cd "$(dirname "$0")" && pwd)"
13
+ # shellcheck source=_lib.sh
14
+ . "$HERE/_lib.sh"
15
+ openclaw_smart_source_login_path
16
+ openclaw_smart_prepend_astral_bins
17
+ openclaw_smart_prepend_node_bins
18
+
19
+ PLUGIN_ROOT="$(cd "$HERE/.." && pwd)"
20
+
21
+ # If the Setup hook recorded an install failure, surface that reason
22
+ # instead of falling through to a generic "uv not found" — mirrors the
23
+ # branch at hook_entry.sh so slash commands and hooks behave consistently
24
+ # on a broken install.
25
+ FAILURE_MARKER="$HOME/.openclaw-smart/install-failed"
26
+ if [ -f "$FAILURE_MARKER" ]; then
27
+ msg="$(cat "$FAILURE_MARKER" 2>/dev/null || echo "")"
28
+ [ -n "$msg" ] || msg="unknown error"
29
+ echo "openclaw-smart is not installed correctly: $msg" >&2
30
+ echo "Re-run the plugin's Setup (restart openClaw) or fix the underlying issue and delete $FAILURE_MARKER to retry." >&2
31
+ exit 1
32
+ fi
33
+
34
+ if ! command -v uv >/dev/null 2>&1; then
35
+ # Self-heal: the Setup/SessionStart hook may have been skipped (trust
36
+ # prompt declined, plugin enabled mid-session, etc.) leaving the install
37
+ # half-done. Run smart-install.sh inline so the user does not have to
38
+ # restart openClaw just to recover.
39
+ # Guard against recursion: if smart-install.sh ever shells back through
40
+ # this wrapper (e.g. a future migration step) we must not loop forever.
41
+ if [ "${OPENCLAW_SMART_BOOTSTRAPPING:-}" = "1" ]; then
42
+ echo "openclaw-smart: bootstrap recursion detected; aborting." >&2
43
+ exit 1
44
+ fi
45
+ if [ -x "$PLUGIN_ROOT/scripts/smart-install.sh" ]; then
46
+ echo "openclaw-smart: 'uv' not found — bootstrapping dependencies (~1-3 min on first install)..." >&2
47
+ # ``set -e`` would short-circuit on a non-zero installer exit and skip
48
+ # the structured failure-marker checks below. Capture the failure
49
+ # explicitly so the wrapper continues to the unified error reporting.
50
+ OPENCLAW_SMART_BOOTSTRAPPING=1 bash "$PLUGIN_ROOT/scripts/smart-install.sh" >&2 || \
51
+ echo "openclaw-smart: smart-install.sh exited non-zero; continuing to error report" >&2
52
+ openclaw_smart_prepend_astral_bins
53
+ openclaw_smart_prepend_node_bins
54
+ fi
55
+ if ! command -v uv >/dev/null 2>&1; then
56
+ if [ -f "$FAILURE_MARKER" ]; then
57
+ msg="$(cat "$FAILURE_MARKER" 2>/dev/null || echo "unknown error")"
58
+ echo "openclaw-smart: install failed: $msg" >&2
59
+ echo "Fix the underlying issue and delete $FAILURE_MARKER to retry." >&2
60
+ else
61
+ echo "openclaw-smart: 'uv' not found on PATH after bootstrap attempt." >&2
62
+ echo "Install it from https://docs.astral.sh/uv/ or rerun $PLUGIN_ROOT/scripts/smart-install.sh manually." >&2
63
+ fi
64
+ exit 1
65
+ fi
66
+ fi
67
+
68
+ exec uv run --project "$PLUGIN_ROOT" --quiet python -m openclaw_smart.cli "$@"
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env bash
2
+ # Open the reflexio dashboard in the user's browser. The dashboard itself
3
+ # (Next.js app) is provided by the claude-smart sibling plugin and listens
4
+ # on http://localhost:3001 by default — both plugins target the same URL.
5
+ # We only need the "open browser" hop here.
6
+ set -eu
7
+
8
+ URL="${REFLEXIO_DASHBOARD_URL:-http://localhost:3001}"
9
+ if command -v xdg-open >/dev/null 2>&1; then
10
+ xdg-open "$URL" >/dev/null 2>&1 || true
11
+ elif command -v open >/dev/null 2>&1; then
12
+ open "$URL" >/dev/null 2>&1 || true
13
+ else
14
+ echo "Open this URL in your browser: $URL"
15
+ fi
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env bash
2
+ # Maintain ~/.reflexio/openclaw-plugin-root as a symlink to the active plugin
3
+ # install dir so slash commands can reference one short path regardless
4
+ # of whether the user is on the remote marketplace or the local-dev install.
5
+ #
6
+ # Usage: ensure-plugin-root.sh <target-dir> [--force]
7
+ # --force overwrite any existing link (used by setup scripts)
8
+ # default self-heal only if the link is missing or points at an
9
+ # invalid target
10
+ set -eu
11
+
12
+ TARGET="${1:-}"
13
+ FORCE="${2:-}"
14
+
15
+ if [ -z "$TARGET" ]; then
16
+ echo "[openclaw-smart] ensure-plugin-root: usage: $0 <target-dir> [--force]" >&2
17
+ exit 1
18
+ fi
19
+
20
+ if [ ! -f "$TARGET/pyproject.toml" ]; then
21
+ echo "[openclaw-smart] ensure-plugin-root: $TARGET is not a plugin dir (no pyproject.toml)" >&2
22
+ exit 1
23
+ fi
24
+
25
+ LINK="$HOME/.reflexio/openclaw-plugin-root"
26
+ mkdir -p "$(dirname "$LINK")"
27
+
28
+ if [ "$FORCE" = "--force" ]; then
29
+ ln -sfn "$TARGET" "$LINK"
30
+ echo "[openclaw-smart] plugin-root → $TARGET (forced)" >&2
31
+ exit 0
32
+ fi
33
+
34
+ # Opt-in: when OPENCLAW_SMART_PLUGIN_ROOT_FOLLOW_SESSION=1 (set in the
35
+ # environment or in ~/.reflexio/.env), always relink to $TARGET so the
36
+ # symlink tracks the currently loaded plugin. Off by default to preserve
37
+ # a pinned local-dev link across sessions that load the remote plugin.
38
+ FOLLOW="${OPENCLAW_SMART_PLUGIN_ROOT_FOLLOW_SESSION:-}"
39
+ if [ -z "$FOLLOW" ] && [ -f "$HOME/.reflexio/.env" ]; then
40
+ FOLLOW="$(grep -E '^OPENCLAW_SMART_PLUGIN_ROOT_FOLLOW_SESSION=' "$HOME/.reflexio/.env" \
41
+ | tail -n1 | cut -d= -f2-)"
42
+ # Strip a single pair of surrounding double or single quotes, if present.
43
+ FOLLOW="${FOLLOW#\"}"; FOLLOW="${FOLLOW%\"}"
44
+ FOLLOW="${FOLLOW#\'}"; FOLLOW="${FOLLOW%\'}"
45
+ fi
46
+ if [ "$FOLLOW" = "1" ]; then
47
+ ln -sfn "$TARGET" "$LINK"
48
+ echo "[openclaw-smart] plugin-root → $TARGET (follow-session)" >&2
49
+ exit 0
50
+ fi
51
+
52
+ # Cache-tracking: if the link currently resolves to a path under the
53
+ # managed openClaw plugin cache (~/.openclaw/plugins/cache/), always
54
+ # retarget it to $TARGET. Plugin updates leave old version directories
55
+ # behind, so a valid pyproject.toml at the stale target is not proof the
56
+ # link is fresh. Links pointing outside the cache (e.g., a user's
57
+ # local-dev checkout) are left alone here and handled by the self-heal
58
+ # below.
59
+ if [ -L "$LINK" ]; then
60
+ # Literal target string, not realpath: we compare against what was written by ln -s.
61
+ CURRENT="$(readlink "$LINK" 2>/dev/null || true)"
62
+ case "$CURRENT" in
63
+ "$HOME/.openclaw/plugins/cache/"*)
64
+ CURRENT_NORM="${CURRENT%/}"
65
+ TARGET_NORM="${TARGET%/}"
66
+ if [ "$CURRENT_NORM" != "$TARGET_NORM" ]; then
67
+ ln -sfn "$TARGET" "$LINK"
68
+ echo "[openclaw-smart] plugin-root → $TARGET (cache-tracking, was $CURRENT)" >&2
69
+ fi
70
+ exit 0
71
+ ;;
72
+ esac
73
+ fi
74
+
75
+ # Self-heal path: only rewrite the link if it's missing or its target is
76
+ # gone/invalid. This preserves a valid local-dev symlink set earlier by
77
+ # a setup script, so SessionStart hooks on the local install don't
78
+ # clobber the user's repo-pointing link.
79
+ if [ -f "$LINK/pyproject.toml" ]; then
80
+ exit 0
81
+ fi
82
+
83
+ ln -sfn "$TARGET" "$LINK"
84
+ echo "[openclaw-smart] plugin-root → $TARGET" >&2
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env bash
2
+ # Dispatch an openClaw hook event to the openclaw_smart Python package.
3
+ # OPENCLAW_PLUGIN_ROOT points at the plugin dir (dev: <repo>/.../openclaw/plugin;
4
+ # installed: ~/.openclaw/plugins/cache/.../openclaw-smart/<version>),
5
+ # which is also the Python project root with pyproject.toml + uv.lock.
6
+ # We invoke via `uv run --project` so the pinned env from uv.lock is used.
7
+ #
8
+ # If a prior Setup recorded an install failure at
9
+ # ~/.openclaw-smart/install-failed, short-circuit with a user-visible
10
+ # message instead of trying to run uv and failing silently.
11
+ set -eu
12
+
13
+ HOST="openclaw"
14
+ EVENT="${1:-}"
15
+ case "$EVENT" in
16
+ openclaw)
17
+ HOST="$EVENT"
18
+ EVENT="${2:-}"
19
+ ;;
20
+ esac
21
+ if [ -z "$EVENT" ]; then
22
+ echo ''
23
+ exit 0
24
+ fi
25
+
26
+ HERE="$(cd "$(dirname "$0")" && pwd)"
27
+ # shellcheck source=_lib.sh
28
+ . "$HERE/_lib.sh"
29
+ if openclaw_smart_is_internal_invocation_env; then
30
+ echo ''
31
+ exit 0
32
+ fi
33
+ # Pick up uv from the user's login-shell PATH (covers ~/.local/bin populated
34
+ # by the astral.sh installer) so a fresh install works before the user
35
+ # restarts their terminal. Matches the pattern used by smart-install.sh.
36
+ openclaw_smart_source_login_path
37
+ # Explicit fallback for the astral.sh installer's default paths, in case
38
+ # the user's login-shell rc hasn't yet been re-sourced to pick them up.
39
+ openclaw_smart_prepend_astral_bins
40
+
41
+ PLUGIN_ROOT="$(cd "$HERE/.." && pwd)"
42
+
43
+ FAILURE_MARKER="$HOME/.openclaw-smart/install-failed"
44
+ STATE_DIR="$HOME/.openclaw-smart"
45
+ if [ -f "$FAILURE_MARKER" ]; then
46
+ if [ "$EVENT" = "session-start" ] && command -v python3 >/dev/null 2>&1; then
47
+ python3 - "$FAILURE_MARKER" <<'PY'
48
+ import json, pathlib, sys
49
+ msg = pathlib.Path(sys.argv[1]).read_text().strip() or "unknown error"
50
+ print(json.dumps({
51
+ "prependContext": (
52
+ f"> **openclaw-smart is not installed correctly:** {msg}\n"
53
+ "> Re-run the plugin's Setup (restart openClaw) "
54
+ "or fix the underlying issue and delete "
55
+ "`~/.openclaw-smart/install-failed` to retry."
56
+ )
57
+ }))
58
+ PY
59
+ else
60
+ echo ''
61
+ fi
62
+ exit 0
63
+ fi
64
+
65
+ if ! command -v uv >/dev/null 2>&1; then
66
+ # Self-heal from skipped Setup/SessionStart bootstrap. SessionStart can
67
+ # afford to wait because it has the install budget; prompt/tool hooks start
68
+ # the same installer detached so normal work is not blocked by first-run
69
+ # dependency setup.
70
+ if [ "${OPENCLAW_SMART_BOOTSTRAPPING:-}" = "1" ]; then
71
+ echo ''
72
+ exit 0
73
+ fi
74
+ if [ -x "$PLUGIN_ROOT/scripts/smart-install.sh" ]; then
75
+ mkdir -p "$STATE_DIR"
76
+ if [ "$EVENT" = "session-start" ]; then
77
+ OPENCLAW_SMART_BOOTSTRAPPING=1 bash "$PLUGIN_ROOT/scripts/smart-install.sh" >&2
78
+ openclaw_smart_prepend_astral_bins
79
+ openclaw_smart_prepend_node_bins
80
+ if command -v uv >/dev/null 2>&1; then
81
+ bash "$HERE/backend-service.sh" start >/dev/null 2>&1 || true
82
+ fi
83
+ else
84
+ openclaw_smart_spawn_detached env OPENCLAW_SMART_BOOTSTRAPPING=1 \
85
+ bash "$PLUGIN_ROOT/scripts/smart-install.sh" \
86
+ >>"$STATE_DIR/install.log" 2>&1 || true
87
+ fi
88
+ fi
89
+ if ! command -v uv >/dev/null 2>&1; then
90
+ echo ''
91
+ exit 0
92
+ fi
93
+ fi
94
+
95
+ # Re-check the failure marker after the inline bootstrap. ``smart-install.sh``
96
+ # can write ``install-failed`` *after* uv is on PATH (e.g. ``uv sync`` failed),
97
+ # in which case we still have a working ``uv`` but a non-functional plugin.
98
+ # Without this gate we would proceed to ``uv run`` and crash with a confusing
99
+ # downstream error instead of surfacing the recorded failure reason.
100
+ if [ -f "$FAILURE_MARKER" ]; then
101
+ echo ''
102
+ exit 0
103
+ fi
104
+
105
+ # Stdin is the hook payload JSON — stream it through to the Python CLI.
106
+ exec uv run --project "$PLUGIN_ROOT" --quiet python -m openclaw_smart.hook "$HOST" "$EVENT"
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env node
2
+ // npm-facing installer for openclaw-smart.
3
+ //
4
+ // This intentionally mirrors the core non-interactive install steps from
5
+ // `reflexio setup openclaw` so npm and Python installs do not drift.
6
+
7
+ import { spawnSync } from "node:child_process";
8
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
9
+ import { homedir } from "node:os";
10
+ import { dirname, join, resolve } from "node:path";
11
+ import { fileURLToPath } from "node:url";
12
+
13
+ const PLUGIN_ID = "reflexio-openclaw-smart";
14
+ const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
15
+ const PLUGIN_ROOT = resolve(SCRIPT_DIR, "..");
16
+ const REFLEXIO_DIR = join(homedir(), ".reflexio");
17
+ const REFLEXIO_ENV = join(REFLEXIO_DIR, ".env");
18
+ const STALE_EXTENSION_DIR = join(homedir(), ".openclaw", "extensions", PLUGIN_ID);
19
+
20
+ function usage() {
21
+ console.log(`openclaw-smart
22
+
23
+ Usage:
24
+ openclaw-smart install
25
+ openclaw-smart uninstall [--purge]
26
+ openclaw-smart repair
27
+
28
+ Install registers the bundled OpenClaw plugin, enables typed hook access,
29
+ writes OPENCLAW_BIN to ~/.reflexio/.env, warms dependencies, and verifies
30
+ that OpenClaw loaded the plugin.`);
31
+ }
32
+
33
+ function fail(message, code = 1) {
34
+ console.error(`openclaw-smart: ${message}`);
35
+ process.exit(code);
36
+ }
37
+
38
+ function run(argv, opts = {}) {
39
+ const result = spawnSync(argv[0], argv.slice(1), {
40
+ encoding: "utf8",
41
+ stdio: opts.stdio ?? "pipe",
42
+ ...opts,
43
+ });
44
+ if (result.error) {
45
+ return {
46
+ status: 1,
47
+ stdout: result.stdout ?? "",
48
+ stderr: result.error.message,
49
+ };
50
+ }
51
+ return {
52
+ status: result.status ?? 1,
53
+ stdout: result.stdout ?? "",
54
+ stderr: result.stderr ?? "",
55
+ };
56
+ }
57
+
58
+ function findExecutable(name) {
59
+ const candidates = [];
60
+ if (process.env.PATH) {
61
+ for (const dir of process.env.PATH.split(process.platform === "win32" ? ";" : ":")) {
62
+ if (!dir) continue;
63
+ candidates.push(join(dir, name));
64
+ if (process.platform === "win32") candidates.push(join(dir, `${name}.cmd`));
65
+ if (process.platform === "win32") candidates.push(join(dir, `${name}.exe`));
66
+ }
67
+ }
68
+ for (const candidate of candidates) {
69
+ if (existsSync(candidate)) return candidate;
70
+ }
71
+ return null;
72
+ }
73
+
74
+ function resolveOpenClawBin() {
75
+ // Absolutize the result: this value is written to ~/.reflexio/.env and later
76
+ // read by backend subprocesses that may run from a different cwd, so a
77
+ // relative OPENCLAW_BIN or relative PATH entry must not leak through.
78
+ const configured = process.env.OPENCLAW_BIN;
79
+ if (configured && existsSync(configured)) return resolve(configured);
80
+ const found = findExecutable("openclaw");
81
+ return found ? resolve(found) : found;
82
+ }
83
+
84
+ function shellQuote(value) {
85
+ return `"${String(value).replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
86
+ }
87
+
88
+ function upsertEnv(envPath, updates) {
89
+ mkdirSync(dirname(envPath), { recursive: true });
90
+ const existing = existsSync(envPath) ? readFileSync(envPath, "utf8").split(/\r?\n/) : [];
91
+ const remaining = existing.filter((line) => {
92
+ const trimmed = line.trim();
93
+ if (!trimmed || trimmed.startsWith("#")) return true;
94
+ return !Object.keys(updates).some((key) => trimmed.startsWith(`${key}=`));
95
+ });
96
+ for (const [key, value] of Object.entries(updates)) {
97
+ remaining.push(`${key}=${shellQuote(value)}`);
98
+ }
99
+ writeFileSync(envPath, `${remaining.filter((line) => line.length > 0).join("\n")}\n`);
100
+ }
101
+
102
+ function removeEnvKeys(envPath, keys) {
103
+ if (!existsSync(envPath)) return;
104
+ const kept = readFileSync(envPath, "utf8")
105
+ .split(/\r?\n/)
106
+ .filter((line) => !keys.some((key) => line.trim().startsWith(`${key}=`)))
107
+ .filter((line) => line.length > 0);
108
+ writeFileSync(envPath, kept.length ? `${kept.join("\n")}\n` : "");
109
+ }
110
+
111
+ function ensurePluginRoot() {
112
+ if (!existsSync(join(PLUGIN_ROOT, "openclaw.plugin.json"))) {
113
+ fail(`plugin root is incomplete: ${PLUGIN_ROOT}`);
114
+ }
115
+ }
116
+
117
+ function runOpenClaw(cli, args, opts = {}) {
118
+ return run([cli, ...args], opts);
119
+ }
120
+
121
+ function printCommandFailure(label, result) {
122
+ const detail = (result.stderr || result.stdout || "").trim();
123
+ console.error(`openclaw-smart: ${label} failed${detail ? `: ${detail}` : ""}`);
124
+ }
125
+
126
+ function runSmartInstall() {
127
+ const script = join(PLUGIN_ROOT, "scripts", "smart-install.sh");
128
+ if (!existsSync(script)) {
129
+ console.warn(`openclaw-smart: ${script} missing; skipping dependency warmup`);
130
+ return;
131
+ }
132
+ const result = run(["bash", script], { stdio: "inherit" });
133
+ if (result.status !== 0) {
134
+ console.warn(
135
+ `openclaw-smart: smart-install.sh exited ${result.status}; first session may bootstrap dependencies`,
136
+ );
137
+ }
138
+ }
139
+
140
+ function inspectLoaded(cli) {
141
+ const result = runOpenClaw(cli, ["plugins", "inspect", PLUGIN_ID]);
142
+ return result.status === 0 && /Status:\s*loaded\b/.test(result.stdout);
143
+ }
144
+
145
+ function install() {
146
+ ensurePluginRoot();
147
+ const cli = resolveOpenClawBin();
148
+ if (!cli) fail("openclaw CLI not found. Install OpenClaw first or set OPENCLAW_BIN.");
149
+
150
+ upsertEnv(REFLEXIO_ENV, {
151
+ OPENCLAW_BIN: cli,
152
+ OPENCLAW_SMART_USE_LOCAL_CLI: "1",
153
+ });
154
+
155
+ runOpenClaw(cli, ["plugins", "uninstall", "--force", PLUGIN_ID]);
156
+ rmSync(STALE_EXTENSION_DIR, { recursive: true, force: true });
157
+
158
+ const installResult = runOpenClaw(cli, ["plugins", "install", PLUGIN_ROOT]);
159
+ if (installResult.status !== 0) {
160
+ printCommandFailure("plugins install", installResult);
161
+ process.exit(1);
162
+ }
163
+
164
+ const enableResult = runOpenClaw(cli, ["plugins", "enable", PLUGIN_ID]);
165
+ if (enableResult.status !== 0) {
166
+ printCommandFailure("plugins enable", enableResult);
167
+ process.exit(1);
168
+ }
169
+
170
+ const accessResult = runOpenClaw(cli, [
171
+ "config",
172
+ "set",
173
+ `plugins.entries.${PLUGIN_ID}.hooks.allowConversationAccess`,
174
+ "true",
175
+ ]);
176
+ if (accessResult.status !== 0) {
177
+ printCommandFailure("config set allowConversationAccess", accessResult);
178
+ process.exit(1);
179
+ }
180
+
181
+ runSmartInstall();
182
+ runOpenClaw(cli, ["gateway", "restart"]);
183
+
184
+ if (!inspectLoaded(cli)) {
185
+ fail(`plugin not loaded; check 'openclaw plugins inspect ${PLUGIN_ID}'`);
186
+ }
187
+ console.log("openclaw-smart installed and registered.");
188
+ }
189
+
190
+ function uninstall({ purge = false } = {}) {
191
+ const cli = resolveOpenClawBin();
192
+ if (cli) {
193
+ runOpenClaw(cli, ["plugins", "disable", PLUGIN_ID]);
194
+ runOpenClaw(cli, ["plugins", "uninstall", "--force", PLUGIN_ID]);
195
+ } else {
196
+ console.warn("openclaw-smart: openclaw CLI not found; skipping plugin removal");
197
+ }
198
+ removeEnvKeys(REFLEXIO_ENV, ["OPENCLAW_BIN", "OPENCLAW_SMART_USE_LOCAL_CLI"]);
199
+ if (purge) rmSync(join(homedir(), ".openclaw-smart"), { recursive: true, force: true });
200
+ console.log("openclaw-smart uninstalled.");
201
+ }
202
+
203
+ function repair() {
204
+ runSmartInstall();
205
+ console.log("openclaw-smart repair complete.");
206
+ }
207
+
208
+ const [command, ...args] = process.argv.slice(2);
209
+ if (!command || command === "-h" || command === "--help") {
210
+ usage();
211
+ process.exit(0);
212
+ }
213
+ if (command === "install") install();
214
+ else if (command === "uninstall") uninstall({ purge: args.includes("--purge") });
215
+ else if (command === "repair") repair();
216
+ else {
217
+ usage();
218
+ fail(`unknown command: ${command}`);
219
+ }