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
@@ -3,11 +3,53 @@
3
3
  # Claude Code hooks run with a minimal non-interactive PATH that often omits
4
4
  # nvm/asdf/brew shims where `npm`, `uv`, etc. live. Pull the user's login-shell
5
5
  # PATH the same way claude-mem does so hook-spawned scripts find them without
6
- # the user having to mutate their global PATH. Best-effort failures silent.
6
+ # the user having to mutate their global PATH. Best-effort and bounded: shell
7
+ # profile startup can be slow or stuck on Windows, so this must never outlive a
8
+ # hook's timeout budget.
9
+ claude_smart_login_path_timeout_seconds() {
10
+ local _VALUE
11
+ _VALUE="${CLAUDE_SMART_LOGIN_PATH_TIMEOUT_SECONDS:-2}"
12
+ case "$_VALUE" in
13
+ ''|*[!0-9]*) printf '%s\n' "2" ;;
14
+ *) printf '%s\n' "$_VALUE" ;;
15
+ esac
16
+ }
17
+
18
+ claude_smart_capture_login_path() {
19
+ local _TIMEOUT _TMP _PID _WAITED _LINE
20
+ _TIMEOUT="$(claude_smart_login_path_timeout_seconds)"
21
+ [ "$_TIMEOUT" -gt 0 ] || return 1
22
+
23
+ _TMP="${TMPDIR:-/tmp}/claude-smart-login-path.$$"
24
+ rm -f "$_TMP" 2>/dev/null || true
25
+ "$SHELL" -lc 'printf %s "$PATH"' >"$_TMP" 2>/dev/null &
26
+ _PID=$!
27
+ _WAITED=0
28
+ while kill -0 "$_PID" 2>/dev/null; do
29
+ if [ "$_WAITED" -ge "$_TIMEOUT" ]; then
30
+ kill "$_PID" 2>/dev/null || true
31
+ wait "$_PID" 2>/dev/null || true
32
+ rm -f "$_TMP" 2>/dev/null || true
33
+ return 1
34
+ fi
35
+ sleep 1
36
+ _WAITED=$((_WAITED + 1))
37
+ done
38
+ if wait "$_PID" 2>/dev/null; then
39
+ while IFS= read -r _LINE || [ -n "$_LINE" ]; do
40
+ printf '%s' "$_LINE"
41
+ done <"$_TMP"
42
+ rm -f "$_TMP" 2>/dev/null || true
43
+ return 0
44
+ fi
45
+ rm -f "$_TMP" 2>/dev/null || true
46
+ return 1
47
+ }
48
+
7
49
  claude_smart_source_login_path() {
8
50
  local _SHELL_PATH
9
51
  if [ -n "${SHELL:-}" ] && [ -x "$SHELL" ]; then
10
- if _SHELL_PATH="$("$SHELL" -lc 'printf %s "$PATH"' 2>/dev/null)"; then
52
+ if _SHELL_PATH="$(claude_smart_capture_login_path)"; then
11
53
  [ -n "$_SHELL_PATH" ] && export PATH="$_SHELL_PATH:$PATH"
12
54
  fi
13
55
  fi
@@ -45,8 +87,12 @@ claude_smart_env_unquote() {
45
87
  }
46
88
 
47
89
  claude_smart_source_reflexio_env() {
90
+ # claude-smart's env lives at ~/.claude-smart/.env (kept separate from the OSS
91
+ # reflexio default ~/.reflexio/.env). Stays in sync with
92
+ # env_config.REFLEXIO_ENV_PATH and the REFLEXIO_ENV_FILE export in
93
+ # backend-service.sh.
48
94
  local env_file line key value
49
- env_file="$HOME/.reflexio/.env"
95
+ env_file="$HOME/.claude-smart/.env"
50
96
  [ -f "$env_file" ] || return 0
51
97
  while IFS= read -r line || [ -n "$line" ]; do
52
98
  line="${line#"${line%%[![:space:]]*}"}"
@@ -116,30 +162,24 @@ claude_smart_dashboard_unavailable_marker() {
116
162
  }
117
163
 
118
164
  claude_smart_node_recovery_hint() {
119
- cat <<'EOF'
120
- Recovery:
121
- 1. Restart Claude Code to let claude-smart retry its private Node.js install.
122
- 2. If the retry is blocked by your network or OS policy, install Node.js 20.9+ manually:
123
- EOF
165
+ printf '%s\n' \
166
+ "Recovery:" \
167
+ " 1. Restart Claude Code to let claude-smart retry its private Node.js install." \
168
+ " 2. If the retry is blocked by your network or OS policy, install Node.js 20.9+ manually:"
124
169
  if claude_smart_is_windows; then
125
- cat <<'EOF'
126
- - winget install OpenJS.NodeJS.LTS
127
- - or download the LTS installer from https://nodejs.org/
128
- EOF
170
+ printf '%s\n' \
171
+ " - winget install OpenJS.NodeJS.LTS" \
172
+ " - or download the LTS installer from https://nodejs.org/"
129
173
  elif [ "$(uname -s 2>/dev/null)" = "Darwin" ]; then
130
- cat <<'EOF'
131
- - brew install node
132
- - or download the LTS installer from https://nodejs.org/
133
- EOF
174
+ printf '%s\n' \
175
+ " - brew install node" \
176
+ " - or download the LTS installer from https://nodejs.org/"
134
177
  else
135
- cat <<'EOF'
136
- - use your distro package manager for nodejs/npm
137
- - or download the LTS archive from https://nodejs.org/
138
- EOF
178
+ printf '%s\n' \
179
+ " - use your distro package manager for nodejs/npm" \
180
+ " - or download the LTS archive from https://nodejs.org/"
139
181
  fi
140
- cat <<'EOF'
141
- 3. Run /claude-smart:restart, then /claude-smart:dashboard.
142
- EOF
182
+ printf '%s\n' " 3. Run /claude-smart:restart, then /claude-smart:dashboard."
143
183
  }
144
184
 
145
185
  claude_smart_write_dashboard_unavailable() {
@@ -527,14 +567,22 @@ claude_smart_append_capped_log() {
527
567
  # POSIX: setsid → python3 os.setsid → nohup (in that order of strength).
528
568
  # Windows: nohup alone — Git Bash has no setsid, no process groups, and
529
569
  # `os.setsid()` is POSIX-only; nohup ignores SIGHUP which is enough to
530
- # survive the parent console closing. The python3 fallback is gated on a
531
- # real-interpreter probe (-V) so the Windows App Execution Alias stub
532
- # doesn't get invoked. Caller is responsible for redirecting stdout/stderr;
533
- # we do not impose a log destination here. Stdin is closed so the child
534
- # cannot inherit a tty. Use `$!` after this call to capture the pid.
570
+ # survive the parent console closing. On Windows, stdout/stderr are also
571
+ # closed here so hook-runner pipes cannot be kept alive by long-lived
572
+ # background children after the hook script exits unless the caller explicitly
573
+ # opts into preserving stdout/stderr for a file redirection. The python3
574
+ # fallback is gated on a real-interpreter probe (-V) so the Windows App
575
+ # Execution Alias stub doesn't get invoked. POSIX callers are responsible for
576
+ # redirecting stdout/stderr; we do not impose a log destination there. Stdin is
577
+ # closed so the child cannot inherit a tty. Use `$!` after this call to capture
578
+ # the pid.
535
579
  claude_smart_spawn_detached() {
536
580
  if claude_smart_is_windows; then
537
- nohup "$@" < /dev/null &
581
+ if [ "${CLAUDE_SMART_SPAWN_KEEP_OUTPUT:-}" = "1" ]; then
582
+ nohup "$@" < /dev/null &
583
+ else
584
+ nohup "$@" < /dev/null > /dev/null 2>&1 &
585
+ fi
538
586
  return 0
539
587
  fi
540
588
  if command -v setsid >/dev/null 2>&1; then
@@ -20,11 +20,13 @@ set -eu
20
20
  HERE="$(cd "$(dirname "$0")" && pwd)"
21
21
  # shellcheck source=_lib.sh
22
22
  . "$HERE/_lib.sh"
23
- claude_smart_source_login_path
23
+ CMD="${1:-start}"
24
+ if [ "$CMD" != "session-end" ]; then
25
+ claude_smart_source_login_path
26
+ fi
24
27
  claude_smart_prepend_astral_bins
25
28
  claude_smart_source_reflexio_env
26
29
 
27
- CMD="${1:-start}"
28
30
  PORT=8071
29
31
  EMBEDDING_PORT="${EMBEDDING_PORT:-8072}"
30
32
  # Pass through to `reflexio services start/stop` so the spawned backend
@@ -32,6 +34,21 @@ EMBEDDING_PORT="${EMBEDDING_PORT:-8072}"
32
34
  export BACKEND_PORT="$PORT"
33
35
  export EMBEDDING_PORT
34
36
 
37
+ # Run claude-smart's backend under its own org id. The reflexio no-auth resolver
38
+ # reads REFLEXIO_DEFAULT_ORG_ID, which scopes the request org -> config file
39
+ # name (config_<org>.json) and SQLite data. Hard-set (not :-defaulted) so a
40
+ # value in the shared ~/.reflexio/.env can't drag claude-smart back onto
41
+ # "self-host-org" and collide with the enterprise self-host backend over
42
+ # config_self-host-org.json. Must stay in sync with cli.py's config path.
43
+ export REFLEXIO_DEFAULT_ORG_ID="claude-smart"
44
+
45
+ # Load claude-smart's env from ~/.claude-smart/.env instead of the reflexio
46
+ # default ~/.reflexio/.env, so an OSS reflexio backend's .env on this machine
47
+ # can't leak in. The data dir is independent (LOCAL_STORAGE_PATH), so both still
48
+ # share ~/.reflexio/data. Must stay in sync with env_config.REFLEXIO_ENV_PATH and
49
+ # the source path in _lib.sh (claude_smart_source_reflexio_env).
50
+ export REFLEXIO_ENV_FILE="$HOME/.claude-smart/.env"
51
+
35
52
  # Default: route extraction through the active host CLI + ONNX embedder
36
53
  # so claude-smart works without any LLM API key. Users can opt out by
37
54
  # pre-exporting these to 0.
@@ -48,7 +65,12 @@ PLUGIN_ROOT="$(cd "$HERE/.." && pwd)"
48
65
  claude_smart_reexec_stable_plugin_root_if_needed "$PLUGIN_ROOT" "backend-service.sh" "$@"
49
66
 
50
67
  if [ -z "${CLAUDE_SMART_CLI_PATH:-}" ]; then
51
- if [ "${CLAUDE_SMART_HOST:-claude-code}" = "codex" ]; then
68
+ if [ "${CLAUDE_SMART_HOST:-claude-code}" = "opencode" ] && command -v opencode >/dev/null 2>&1; then
69
+ # Preserve Reflexio's Claude CLI provider contract while routing
70
+ # generation through the user's authenticated OpenCode setup.
71
+ claude_smart_prepend_node_bins
72
+ export CLAUDE_SMART_CLI_PATH="$PLUGIN_ROOT/scripts/opencode-claude-compat"
73
+ elif [ "${CLAUDE_SMART_HOST:-claude-code}" = "codex" ]; then
52
74
  # Reflexio's provider still calls CLAUDE_SMART_CLI_PATH with Claude CLI
53
75
  # flags. Use a small compatibility executable that translates that narrow
54
76
  # contract to `codex exec`.
@@ -262,7 +284,7 @@ case "$CMD" in
262
284
  if ! command -v uv >/dev/null 2>&1; then
263
285
  if [ "${CLAUDE_SMART_BOOTSTRAPPING:-}" != "1" ] && [ -x "$PLUGIN_ROOT/scripts/smart-install.sh" ]; then
264
286
  claude_smart_append_capped_log "$LOG_FILE" "$LOG_MAX_BYTES" "[claude-smart] backend: uv not on PATH; starting installer in background"
265
- claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
287
+ CLAUDE_SMART_SPAWN_KEEP_OUTPUT=1 claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
266
288
  bash "$PLUGIN_ROOT/scripts/smart-install.sh" \
267
289
  >>"$STATE_DIR/install.log" 2>&1 || true
268
290
  fi
@@ -284,7 +306,7 @@ case "$CMD" in
284
306
  # Keep plugin runtime data in ~/.reflexio even when the backend imports
285
307
  # Reflexio from an editable checkout inside a larger repo with its own
286
308
  # .env. python-dotenv respects pre-existing env vars, so this prevents a
287
- # parent REFLEXIO_LOG_DIR from sending claude-smart to enterprise configs.
309
+ # parent REFLEXIO_LOG_DIR from sending claude-smart to unrelated configs.
288
310
  export REFLEXIO_LOG_DIR="${REFLEXIO_LOG_DIR:-$HOME}"
289
311
 
290
312
  # Force sqlite: the plugin venv ships only the open-source reflexio
@@ -21,11 +21,13 @@ set -eu
21
21
  HERE="$(cd "$(dirname "$0")" && pwd)"
22
22
  # shellcheck source=_lib.sh
23
23
  . "$HERE/_lib.sh"
24
- claude_smart_source_login_path
24
+ CMD="${1:-start}"
25
+ if [ "$CMD" != "session-end" ]; then
26
+ claude_smart_source_login_path
27
+ fi
25
28
  claude_smart_prepend_node_bins
26
29
  claude_smart_source_reflexio_env
27
30
 
28
- CMD="${1:-start}"
29
31
  PORT=3001
30
32
 
31
33
  PLUGIN_ROOT="$(cd "$HERE/.." && pwd)"
@@ -192,7 +194,7 @@ case "$CMD" in
192
194
  if [ -z "$NPM_BIN" ] || ! "$NPM_BIN" --version >/dev/null 2>&1; then
193
195
  if [ "${CLAUDE_SMART_BOOTSTRAPPING:-}" != "1" ] && [ -x "$PLUGIN_ROOT/scripts/smart-install.sh" ]; then
194
196
  echo "[claude-smart] dashboard: npm is not on PATH; starting installer in background" >>"$LOG_FILE"
195
- claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
197
+ CLAUDE_SMART_SPAWN_KEEP_OUTPUT=1 claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
196
198
  bash "$PLUGIN_ROOT/scripts/smart-install.sh" \
197
199
  >>"$STATE_DIR/install.log" 2>&1 || true
198
200
  fi
@@ -214,7 +216,7 @@ case "$CMD" in
214
216
  BUILD_PID_FILE="$STATE_DIR/dashboard-build.pid"
215
217
  if ! claude_smart_pid_alive_file "$BUILD_PID_FILE"; then
216
218
  echo "[claude-smart] dashboard: .next missing — starting background build (~1-2 min)" >>"$LOG_FILE"
217
- claude_smart_spawn_detached bash "$HERE/dashboard-build.sh" >>"$LOG_FILE" 2>&1
219
+ CLAUDE_SMART_SPAWN_KEEP_OUTPUT=1 claude_smart_spawn_detached bash "$HERE/dashboard-build.sh" >>"$LOG_FILE" 2>&1
218
220
  fi
219
221
  emit_ok; exit 0
220
222
  fi
@@ -229,7 +231,7 @@ case "$CMD" in
229
231
  # Caller-side `>>file 2>&1` redirection is honoured before the child
230
232
  # detaches, so per-OS log paths stay identical.
231
233
  export CLAUDE_SMART_DASHBOARD_WORKSPACE="$WORKSPACE_CWD"
232
- claude_smart_spawn_detached "$NPM_BIN" run start >>"$LOG_FILE" 2>&1
234
+ CLAUDE_SMART_SPAWN_KEEP_OUTPUT=1 claude_smart_spawn_detached "$NPM_BIN" run start >>"$LOG_FILE" 2>&1
233
235
  dash_pid=$!
234
236
  # Record the spawned pid, not a pgid sampled with ps. On POSIX,
235
237
  # setsid/python os.setsid make this pid the new process group leader;
@@ -32,12 +32,12 @@ if [ "$FORCE" = "--force" ]; then
32
32
  fi
33
33
 
34
34
  # Opt-in: when CLAUDE_SMART_PLUGIN_ROOT_FOLLOW_SESSION=1 (set in the
35
- # environment or in ~/.reflexio/.env), always relink to $TARGET so the
35
+ # environment or in ~/.claude-smart/.env), always relink to $TARGET so the
36
36
  # symlink tracks the currently loaded plugin.
37
37
  FOLLOW="${CLAUDE_SMART_PLUGIN_ROOT_FOLLOW_SESSION:-}"
38
- if [ -z "$FOLLOW" ] && [ -f "$HOME/.reflexio/.env" ]; then
39
- FOLLOW="$(grep -E '^CLAUDE_SMART_PLUGIN_ROOT_FOLLOW_SESSION=' "$HOME/.reflexio/.env" \
40
- | tail -n1 | cut -d= -f2-)"
38
+ if [ -z "$FOLLOW" ] && [ -f "$HOME/.claude-smart/.env" ]; then
39
+ FOLLOW="$(grep -E '^(export[[:space:]]+)?CLAUDE_SMART_PLUGIN_ROOT_FOLLOW_SESSION=' "$HOME/.claude-smart/.env" \
40
+ | tail -n1 | sed -E 's/^(export[[:space:]]+)?CLAUDE_SMART_PLUGIN_ROOT_FOLLOW_SESSION=//')"
41
41
  # Strip a single pair of surrounding double or single quotes, if present.
42
42
  FOLLOW="${FOLLOW#\"}"; FOLLOW="${FOLLOW%\"}"
43
43
  FOLLOW="${FOLLOW#\'}"; FOLLOW="${FOLLOW%\'}"
@@ -15,7 +15,7 @@ set -eu
15
15
  HOST="claude-code"
16
16
  EVENT="${1:-}"
17
17
  case "$EVENT" in
18
- claude-code|codex)
18
+ claude-code|codex|opencode)
19
19
  HOST="$EVENT"
20
20
  EVENT="${2:-}"
21
21
  ;;
@@ -96,7 +96,7 @@ if ! command -v uv >/dev/null 2>&1; then
96
96
  fi
97
97
  if [ -x "$PLUGIN_ROOT/scripts/smart-install.sh" ]; then
98
98
  mkdir -p "$STATE_DIR"
99
- claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
99
+ CLAUDE_SMART_SPAWN_KEEP_OUTPUT=1 claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
100
100
  bash "$PLUGIN_ROOT/scripts/smart-install.sh" \
101
101
  >>"$STATE_DIR/install.log" 2>&1 || true
102
102
  fi
@@ -123,7 +123,7 @@ ensure_hook_package_importable() {
123
123
  printf '%s\n' "[claude-smart] hook: claude_smart.hook is not importable; retrying install in background"
124
124
  date 2>/dev/null || true
125
125
  } >>"$STATE_DIR/install.log" 2>&1
126
- claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
126
+ CLAUDE_SMART_SPAWN_KEEP_OUTPUT=1 claude_smart_spawn_detached env CLAUDE_SMART_BOOTSTRAPPING=1 \
127
127
  bash "$PLUGIN_ROOT/scripts/smart-install.sh" \
128
128
  >>"$STATE_DIR/install.log" 2>&1 || true
129
129
 
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env sh
2
+ set -eu
3
+ SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)/"
4
+ exec node "$SCRIPT_DIR/opencode-claude-compat.js" "$@"
@@ -0,0 +1,3 @@
1
+ @echo off
2
+ set SCRIPT_DIR=%~dp0
3
+ node "%SCRIPT_DIR%opencode-claude-compat.js" %*
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ /*
5
+ * Translate Reflexio's Claude CLI provider contract to `opencode run`.
6
+ *
7
+ * Reflexio shells out to CLAUDE_SMART_CLI_PATH as if it were Claude Code:
8
+ *
9
+ * <path> -p --output-format stream-json --model <model> ...
10
+ *
11
+ * Under OpenCode, this bridge preserves that executable contract while routing
12
+ * generation through the user's authenticated OpenCode CLI/provider setup.
13
+ */
14
+
15
+ const { spawnSync } = require("node:child_process");
16
+ const fs = require("node:fs");
17
+ const os = require("node:os");
18
+ const path = require("node:path");
19
+
20
+ const DEFAULT_TIMEOUT_MS = 120_000;
21
+ const AGENT_NAME = "claude-smart-extractor";
22
+
23
+ function main(argv) {
24
+ let workDir = null;
25
+ try {
26
+ const { outputFormat, systemPrompt, model } = parseSupportedArgs(argv);
27
+ const prompt = fs.readFileSync(0, "utf8");
28
+ workDir = prepareWorkDir();
29
+ const content = runOpenCode({
30
+ prompt: combinedPrompt({ prompt, systemPrompt }),
31
+ model,
32
+ workDir,
33
+ });
34
+ const payload =
35
+ outputFormat === "stream-json"
36
+ ? { type: "result", subtype: "success", result: content }
37
+ : { result: content };
38
+ process.stdout.write(`${JSON.stringify(payload)}\n`);
39
+ return 0;
40
+ } catch (error) {
41
+ const message = error instanceof Error ? error.message : String(error);
42
+ process.stderr.write(`opencode-claude-compat: ${message}\n`);
43
+ return 1;
44
+ } finally {
45
+ if (workDir) {
46
+ try {
47
+ fs.rmSync(workDir, { recursive: true, force: true });
48
+ } catch {
49
+ // Best effort cleanup only.
50
+ }
51
+ }
52
+ }
53
+ }
54
+
55
+ function parseSupportedArgs(argv) {
56
+ let outputFormat = "json";
57
+ let systemPrompt = "";
58
+ let model = "";
59
+ let idx = 0;
60
+ while (idx < argv.length) {
61
+ const arg = argv[idx];
62
+ if (arg === "-p") {
63
+ idx += 1;
64
+ } else if (arg === "--output-format") {
65
+ outputFormat = requireValue(argv, idx, arg);
66
+ idx += 2;
67
+ } else if (arg === "--model") {
68
+ model = requireValue(argv, idx, arg);
69
+ idx += 2;
70
+ } else if (arg === "--verbose" || arg === "--include-partial-messages") {
71
+ idx += 1;
72
+ } else if (arg === "--append-system-prompt") {
73
+ systemPrompt = requireValue(argv, idx, arg);
74
+ idx += 2;
75
+ } else {
76
+ throw new Error(`unsupported Claude CLI argument: ${arg}`);
77
+ }
78
+ }
79
+ if (outputFormat !== "json" && outputFormat !== "stream-json") {
80
+ throw new Error(`unsupported --output-format: ${outputFormat}`);
81
+ }
82
+ return { outputFormat, systemPrompt, model };
83
+ }
84
+
85
+ function requireValue(argv, idx, name) {
86
+ if (idx + 1 >= argv.length) {
87
+ throw new Error(`${name} requires a value`);
88
+ }
89
+ return argv[idx + 1];
90
+ }
91
+
92
+ function prepareWorkDir() {
93
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-smart-opencode-"));
94
+ const config = {
95
+ agent: {
96
+ [AGENT_NAME]: {
97
+ description: "Internal claude-smart learning extraction",
98
+ prompt:
99
+ "You are running as an internal claude-smart extraction subprocess. " +
100
+ "Return only the requested text or JSON. Do not use tools, edit files, " +
101
+ "search the workspace, or ask follow-up questions.",
102
+ steps: 2,
103
+ permission: "deny",
104
+ },
105
+ },
106
+ };
107
+ const opencodeDir = path.join(dir, ".opencode");
108
+ fs.mkdirSync(opencodeDir, { recursive: true });
109
+ fs.writeFileSync(path.join(opencodeDir, "opencode.json"), `${JSON.stringify(config, null, 2)}\n`);
110
+ return dir;
111
+ }
112
+
113
+ function runOpenCode({ prompt, model, workDir }) {
114
+ const opencodePath = process.env.CLAUDE_SMART_OPENCODE_PATH || commandPath(opencodeNames());
115
+ if (!opencodePath) {
116
+ throw new Error("opencode CLI not found on PATH");
117
+ }
118
+
119
+ const args = [
120
+ "run",
121
+ "--pure",
122
+ "--format",
123
+ "json",
124
+ "--agent",
125
+ AGENT_NAME,
126
+ "--dir",
127
+ workDir,
128
+ ];
129
+ const selectedModel = opencodeModel(model);
130
+ if (selectedModel) {
131
+ args.push("--model", selectedModel);
132
+ }
133
+ const variant = (process.env.CLAUDE_SMART_OPENCODE_VARIANT || "").trim();
134
+ if (variant) {
135
+ args.push("--variant", variant);
136
+ }
137
+
138
+ const proc = spawnSync(opencodePath, args, {
139
+ input: prompt,
140
+ cwd: workDir,
141
+ encoding: "utf8",
142
+ env: {
143
+ ...process.env,
144
+ CLAUDE_SMART_HOST: "opencode",
145
+ CLAUDE_SMART_INTERNAL: "1",
146
+ CLAUDE_CODE_ENTRYPOINT: "optimizer",
147
+ },
148
+ timeout: timeoutMs(),
149
+ windowsHide: true,
150
+ shell: process.platform === "win32" && /\.(?:cmd|bat)$/i.test(opencodePath),
151
+ });
152
+ if (proc.error) {
153
+ if (proc.error.code === "ETIMEDOUT") {
154
+ throw new Error(`opencode CLI timed out after ${timeoutMs() / 1000}s`);
155
+ }
156
+ throw proc.error;
157
+ }
158
+ if (proc.status !== 0) {
159
+ const stderr = String(proc.stderr || "").trim().slice(0, 500);
160
+ throw new Error(`opencode CLI exited ${proc.status}: ${stderr}`);
161
+ }
162
+ const content = parseOpenCodeJson(proc.stdout);
163
+ if (!content) {
164
+ throw new Error("opencode CLI returned empty output");
165
+ }
166
+ return content;
167
+ }
168
+
169
+ function opencodeModel(modelFromArgs) {
170
+ const explicit = (process.env.CLAUDE_SMART_OPENCODE_MODEL || "").trim();
171
+ if (explicit) return explicit;
172
+ const candidate = (modelFromArgs || "").trim();
173
+ return candidate.includes("/") ? candidate : "";
174
+ }
175
+
176
+ function parseOpenCodeJson(stdout) {
177
+ const chunks = [];
178
+ for (const line of String(stdout || "").split(/\r?\n/)) {
179
+ const trimmed = line.trim();
180
+ if (!trimmed) continue;
181
+ let event;
182
+ try {
183
+ event = JSON.parse(trimmed);
184
+ } catch {
185
+ continue;
186
+ }
187
+ const part = event && typeof event === "object" ? event.part : null;
188
+ if (part && part.type === "text" && typeof part.text === "string") {
189
+ chunks.push(part.text);
190
+ } else if (event.type === "text" && typeof event.text === "string") {
191
+ chunks.push(event.text);
192
+ } else if (event.type === "result" && typeof event.result === "string") {
193
+ chunks.push(event.result);
194
+ }
195
+ }
196
+ return chunks.join("").trim();
197
+ }
198
+
199
+ function timeoutMs() {
200
+ const raw = Number(process.env.CLAUDE_SMART_CLI_TIMEOUT || "");
201
+ if (Number.isFinite(raw) && raw > 0) return raw * 1000;
202
+ return DEFAULT_TIMEOUT_MS;
203
+ }
204
+
205
+ function opencodeNames() {
206
+ return process.platform === "win32" ? ["opencode.cmd", "opencode.exe", "opencode"] : ["opencode"];
207
+ }
208
+
209
+ function commandPath(names) {
210
+ const pathParts = (process.env.PATH || "").split(path.delimiter).filter(Boolean);
211
+ for (const dir of pathParts) {
212
+ for (const name of names) {
213
+ const candidate = path.join(dir, name);
214
+ if (fs.existsSync(candidate)) return candidate;
215
+ }
216
+ }
217
+ return null;
218
+ }
219
+
220
+ function combinedPrompt({ prompt, systemPrompt }) {
221
+ if (!systemPrompt) return prompt;
222
+ return `${systemPrompt}\n\n## Task\n${prompt}`;
223
+ }
224
+
225
+ process.exitCode = main(process.argv.slice(2));
@@ -108,10 +108,10 @@ install_complete() {
108
108
  [ -d "$PLUGIN_ROOT/.venv" ] || return 1
109
109
  claude_smart_python_imports "$PLUGIN_ROOT" claude_smart.hook || return 1
110
110
  if [ -z "${REFLEXIO_API_KEY:-}" ]; then
111
- [ -f "$HOME/.reflexio/.env" ] || return 1
112
- grep -qE '^(export[[:space:]]+)?CLAUDE_SMART_USE_LOCAL_CLI=' "$HOME/.reflexio/.env" || return 1
113
- grep -qE '^(export[[:space:]]+)?CLAUDE_SMART_USE_LOCAL_EMBEDDING=' "$HOME/.reflexio/.env" || return 1
114
- grep -qE '^(export[[:space:]]+)?CLAUDE_SMART_READ_ONLY=' "$HOME/.reflexio/.env" || return 1
111
+ [ -f "$HOME/.claude-smart/.env" ] || return 1
112
+ grep -qE '^(export[[:space:]]+)?CLAUDE_SMART_USE_LOCAL_CLI=' "$HOME/.claude-smart/.env" || return 1
113
+ grep -qE '^(export[[:space:]]+)?CLAUDE_SMART_USE_LOCAL_EMBEDDING=' "$HOME/.claude-smart/.env" || return 1
114
+ grep -qE '^(export[[:space:]]+)?CLAUDE_SMART_READ_ONLY=' "$HOME/.claude-smart/.env" || return 1
115
115
  fi
116
116
  if [ -d "$PLUGIN_ROOT/dashboard" ]; then
117
117
  [ -d "$PLUGIN_ROOT/dashboard/.next" ] || [ -f "$MARKER_DIR/dashboard-build.pid" ] || [ -f "$(claude_smart_dashboard_unavailable_marker)" ] || return 1
@@ -480,10 +480,12 @@ if ! claude_smart_python_imports "$PLUGIN_ROOT" claude_smart.hook; then
480
480
  write_failure "claude-smart package is not importable after vendored Reflexio install in $PLUGIN_ROOT/.venv"
481
481
  fi
482
482
 
483
- # Reflexio's CLI reads ~/.reflexio/.env (see reflexio/cli/env_loader.py);
484
- # append our two opt-in flags there so `reflexio services start` picks
485
- # them up regardless of which directory the user runs it from.
486
- REFLEXIO_ENV="$HOME/.reflexio/.env"
483
+ # claude-smart's backend loads ~/.claude-smart/.env (backend-service.sh exports
484
+ # REFLEXIO_ENV_FILE so reflexio's CLI reads it instead of ~/.reflexio/.env);
485
+ # append our opt-in flags there so `reflexio services start` picks them up. Keep
486
+ # this path in sync with env_config.REFLEXIO_ENV_PATH and backend-service.sh.
487
+ REFLEXIO_ENV="$HOME/.claude-smart/.env"
488
+ mkdir -p "$(dirname "$REFLEXIO_ENV")"
487
489
  claude_smart_env_quote() {
488
490
  printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g'
489
491
  }
@@ -28,7 +28,7 @@ Description: Python package powering the claude-smart plugin — hook handlers t
28
28
 
29
29
  | File | Purpose |
30
30
  |------|---------|
31
- | `env_config.py` | Parses `~/.reflexio/.env` (`REFLEXIO_URL`, `REFLEXIO_API_KEY`, `CLAUDE_SMART_READ_ONLY`, local embedding/CLI flags). |
31
+ | `env_config.py` | Parses `~/.claude-smart/.env` (`REFLEXIO_URL`, `REFLEXIO_API_KEY`, `CLAUDE_SMART_READ_ONLY`, local embedding/CLI flags). |
32
32
  | `runtime.py` | Host detection (Claude Code vs Codex); shared agent version. |
33
33
  | `ids.py` | Session / project ID generation and resolution. |
34
34
  | `context_inject.py`, `context_format.py`, `query_compose.py`, `cs_cite.py` | Build search queries, format learned skills as markdown, inject into context, format citations. |