claude-smart 0.2.41 → 0.2.43

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 (396) hide show
  1. package/.claude-plugin/marketplace.json +17 -0
  2. package/README.md +1 -1
  3. package/bin/claude-smart.js +86 -48
  4. package/package.json +10 -3
  5. package/plugin/.claude-plugin/plugin.json +9 -3
  6. package/plugin/.codex-plugin/plugin.json +1 -1
  7. package/plugin/README.md +2 -2
  8. package/plugin/dashboard/next.config.ts +9 -1
  9. package/plugin/pyproject.toml +2 -2
  10. package/plugin/scripts/_lib.sh +91 -0
  11. package/plugin/scripts/backend-service.sh +46 -15
  12. package/plugin/scripts/cli.sh +29 -1
  13. package/plugin/scripts/codex-hook.js +72 -4
  14. package/plugin/scripts/dashboard-build.sh +1 -0
  15. package/plugin/scripts/dashboard-service.sh +1 -0
  16. package/plugin/scripts/ensure-plugin-root.sh +7 -14
  17. package/plugin/scripts/hook_entry.sh +1 -0
  18. package/plugin/scripts/smart-install.sh +18 -2
  19. package/plugin/src/claude_smart/cli.py +72 -38
  20. package/plugin/src/claude_smart/context_format.py +11 -12
  21. package/plugin/src/claude_smart/cs_cite.py +26 -12
  22. package/plugin/src/claude_smart/ids.py +13 -5
  23. package/plugin/uv.lock +1 -1
  24. package/plugin/vendor/reflexio/.env.example +53 -0
  25. package/plugin/vendor/reflexio/LICENSE +201 -0
  26. package/plugin/vendor/reflexio/README.md +338 -0
  27. package/plugin/vendor/reflexio/pyproject.toml +271 -0
  28. package/plugin/vendor/reflexio/reflexio/README.md +184 -0
  29. package/plugin/vendor/reflexio/reflexio/__init__.py +166 -0
  30. package/plugin/vendor/reflexio/reflexio/benchmarks/__init__.py +1 -0
  31. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/README.md +109 -0
  32. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/__init__.py +1 -0
  33. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/backends.py +175 -0
  34. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/bench.py +642 -0
  35. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/embed_cache.py +330 -0
  36. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/report.py +317 -0
  37. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/results/report.md +43 -0
  38. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/results/results.json +4478 -0
  39. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/scenarios.py +134 -0
  40. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/seed.py +255 -0
  41. package/plugin/vendor/reflexio/reflexio/cli/README.md +287 -0
  42. package/plugin/vendor/reflexio/reflexio/cli/__init__.py +0 -0
  43. package/plugin/vendor/reflexio/reflexio/cli/__main__.py +56 -0
  44. package/plugin/vendor/reflexio/reflexio/cli/_client.py +86 -0
  45. package/plugin/vendor/reflexio/reflexio/cli/app.py +127 -0
  46. package/plugin/vendor/reflexio/reflexio/cli/bootstrap_config.py +266 -0
  47. package/plugin/vendor/reflexio/reflexio/cli/codex_auth.py +503 -0
  48. package/plugin/vendor/reflexio/reflexio/cli/commands/__init__.py +0 -0
  49. package/plugin/vendor/reflexio/reflexio/cli/commands/admin_cmd.py +65 -0
  50. package/plugin/vendor/reflexio/reflexio/cli/commands/agent_playbooks.py +503 -0
  51. package/plugin/vendor/reflexio/reflexio/cli/commands/api.py +114 -0
  52. package/plugin/vendor/reflexio/reflexio/cli/commands/auth.py +109 -0
  53. package/plugin/vendor/reflexio/reflexio/cli/commands/config_cmd.py +511 -0
  54. package/plugin/vendor/reflexio/reflexio/cli/commands/doctor.py +127 -0
  55. package/plugin/vendor/reflexio/reflexio/cli/commands/embeddings.py +53 -0
  56. package/plugin/vendor/reflexio/reflexio/cli/commands/interactions.py +478 -0
  57. package/plugin/vendor/reflexio/reflexio/cli/commands/profiles.py +303 -0
  58. package/plugin/vendor/reflexio/reflexio/cli/commands/services.py +289 -0
  59. package/plugin/vendor/reflexio/reflexio/cli/commands/setup_cmd.py +961 -0
  60. package/plugin/vendor/reflexio/reflexio/cli/commands/shortcuts.py +285 -0
  61. package/plugin/vendor/reflexio/reflexio/cli/commands/status_cmd.py +143 -0
  62. package/plugin/vendor/reflexio/reflexio/cli/commands/user_playbooks.py +373 -0
  63. package/plugin/vendor/reflexio/reflexio/cli/env_loader.py +284 -0
  64. package/plugin/vendor/reflexio/reflexio/cli/errors.py +217 -0
  65. package/plugin/vendor/reflexio/reflexio/cli/log_format.py +247 -0
  66. package/plugin/vendor/reflexio/reflexio/cli/output.py +867 -0
  67. package/plugin/vendor/reflexio/reflexio/cli/paths.py +41 -0
  68. package/plugin/vendor/reflexio/reflexio/cli/run_services.py +391 -0
  69. package/plugin/vendor/reflexio/reflexio/cli/state.py +204 -0
  70. package/plugin/vendor/reflexio/reflexio/cli/stop_services.py +96 -0
  71. package/plugin/vendor/reflexio/reflexio/cli/utils.py +329 -0
  72. package/plugin/vendor/reflexio/reflexio/client/__init__.py +3 -0
  73. package/plugin/vendor/reflexio/reflexio/client/cache.py +150 -0
  74. package/plugin/vendor/reflexio/reflexio/client/client.py +2613 -0
  75. package/plugin/vendor/reflexio/reflexio/defaults.py +23 -0
  76. package/plugin/vendor/reflexio/reflexio/integrations/__init__.py +0 -0
  77. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/.clawhubignore +7 -0
  78. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/README.md +274 -0
  79. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/TESTING.md +517 -0
  80. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/hook/handler.js +473 -0
  81. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package-lock.json +2156 -0
  82. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package.json +18 -0
  83. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/handler.ts +241 -0
  84. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/setup.ts +140 -0
  85. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/index.ts +130 -0
  86. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/publish.ts +113 -0
  87. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/search.ts +52 -0
  88. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/server.ts +103 -0
  89. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/sqlite-buffer.ts +156 -0
  90. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/user-id.ts +134 -0
  91. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/openclaw.plugin.json +41 -0
  92. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/package.json +17 -0
  93. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/rules/reflexio.md +24 -0
  94. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/reflexio/SKILL.md +48 -0
  95. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/publish_clawhub.sh +278 -0
  96. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/references/HOOK.md +164 -0
  97. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/install.sh +36 -0
  98. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/uninstall.sh +35 -0
  99. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/publish.test.ts +27 -0
  100. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/search.test.ts +31 -0
  101. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/server.test.ts +42 -0
  102. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/setup.test.ts +49 -0
  103. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/sqlite-buffer.test.ts +91 -0
  104. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/user-id.test.ts +50 -0
  105. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tsconfig.json +16 -0
  106. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/types/openclaw.d.ts +230 -0
  107. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/vitest.config.ts +13 -0
  108. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/README.md +120 -0
  109. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/TESTING.md +168 -0
  110. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/package-lock.json +1657 -0
  111. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/package.json +16 -0
  112. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/HEARTBEAT.md +6 -0
  113. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/README.md +84 -0
  114. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/SKILL.md +194 -0
  115. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/_meta.json +6 -0
  116. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/agents/reflexio-extractor.md +45 -0
  117. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/hook/handler.ts +214 -0
  118. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/hook/setup.ts +55 -0
  119. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/index.ts +327 -0
  120. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/consolidate.ts +233 -0
  121. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/dedup.ts +80 -0
  122. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/io.ts +155 -0
  123. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/openclaw-cli.ts +67 -0
  124. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/search.ts +33 -0
  125. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/write-playbook.ts +76 -0
  126. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/write-profile.ts +79 -0
  127. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/openclaw.plugin.json +46 -0
  128. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/package.json +18 -0
  129. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/README.md +36 -0
  130. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/full_consolidation.md +56 -0
  131. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/playbook_extraction.md +217 -0
  132. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/profile_extraction.md +132 -0
  133. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/skills/reflexio-consolidate/SKILL.md +33 -0
  134. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/skills/reflexio-embedded/SKILL.md +194 -0
  135. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/HOOK.md +18 -0
  136. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/architecture.md +49 -0
  137. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/comparison.md +31 -0
  138. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/future-work.md +47 -0
  139. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/porting-notes.md +52 -0
  140. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/scripts/install.sh +52 -0
  141. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/scripts/uninstall.sh +36 -0
  142. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/consolidate.test.ts +135 -0
  143. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/dedup.test.ts +104 -0
  144. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/io.test.ts +175 -0
  145. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/search.test.ts +66 -0
  146. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/smoke-test.ts +140 -0
  147. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/write-playbook.test.ts +93 -0
  148. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/write-profile.test.ts +174 -0
  149. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tsconfig.json +16 -0
  150. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/types/openclaw.d.ts +230 -0
  151. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/vitest.config.ts +7 -0
  152. package/plugin/vendor/reflexio/reflexio/lib/__init__.py +23 -0
  153. package/plugin/vendor/reflexio/reflexio/lib/_agent_playbook.py +310 -0
  154. package/plugin/vendor/reflexio/reflexio/lib/_base.py +225 -0
  155. package/plugin/vendor/reflexio/reflexio/lib/_config.py +83 -0
  156. package/plugin/vendor/reflexio/reflexio/lib/_dashboard.py +266 -0
  157. package/plugin/vendor/reflexio/reflexio/lib/_generation.py +176 -0
  158. package/plugin/vendor/reflexio/reflexio/lib/_interactions.py +334 -0
  159. package/plugin/vendor/reflexio/reflexio/lib/_operations.py +153 -0
  160. package/plugin/vendor/reflexio/reflexio/lib/_profiles.py +545 -0
  161. package/plugin/vendor/reflexio/reflexio/lib/_reflection.py +52 -0
  162. package/plugin/vendor/reflexio/reflexio/lib/_search.py +167 -0
  163. package/plugin/vendor/reflexio/reflexio/lib/_storage_labels.py +103 -0
  164. package/plugin/vendor/reflexio/reflexio/lib/_user_playbook.py +288 -0
  165. package/plugin/vendor/reflexio/reflexio/lib/reflexio_lib.py +27 -0
  166. package/plugin/vendor/reflexio/reflexio/models/__init__.py +0 -0
  167. package/plugin/vendor/reflexio/reflexio/models/api_schema/__init__.py +0 -0
  168. package/plugin/vendor/reflexio/reflexio/models/api_schema/braintrust_schema.py +141 -0
  169. package/plugin/vendor/reflexio/reflexio/models/api_schema/common.py +41 -0
  170. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/__init__.py +3 -0
  171. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/entities.py +1103 -0
  172. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/enums.py +63 -0
  173. package/plugin/vendor/reflexio/reflexio/models/api_schema/eval_overview_schema.py +487 -0
  174. package/plugin/vendor/reflexio/reflexio/models/api_schema/internal_schema.py +28 -0
  175. package/plugin/vendor/reflexio/reflexio/models/api_schema/pending_tool_call_schema.py +83 -0
  176. package/plugin/vendor/reflexio/reflexio/models/api_schema/retriever_schema.py +766 -0
  177. package/plugin/vendor/reflexio/reflexio/models/api_schema/service_schemas.py +9 -0
  178. package/plugin/vendor/reflexio/reflexio/models/api_schema/stall_state_schema.py +32 -0
  179. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/__init__.py +3 -0
  180. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/converters.py +177 -0
  181. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/entities.py +129 -0
  182. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/enums.py +25 -0
  183. package/plugin/vendor/reflexio/reflexio/models/api_schema/validators.py +280 -0
  184. package/plugin/vendor/reflexio/reflexio/models/config_schema.py +908 -0
  185. package/plugin/vendor/reflexio/reflexio/models/py.typed +0 -0
  186. package/plugin/vendor/reflexio/reflexio/server/OVERVIEW.md +90 -0
  187. package/plugin/vendor/reflexio/reflexio/server/README.md +616 -0
  188. package/plugin/vendor/reflexio/reflexio/server/__init__.py +210 -0
  189. package/plugin/vendor/reflexio/reflexio/server/__main__.py +132 -0
  190. package/plugin/vendor/reflexio/reflexio/server/_auth.py +25 -0
  191. package/plugin/vendor/reflexio/reflexio/server/api.py +2714 -0
  192. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/account_api.py +143 -0
  193. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/health_api.py +91 -0
  194. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/pending_tool_call_api.py +572 -0
  195. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/precondition_checks.py +66 -0
  196. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/publisher_api.py +540 -0
  197. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/request_context.py +50 -0
  198. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/stall_state_api.py +100 -0
  199. package/plugin/vendor/reflexio/reflexio/server/cache/__init__.py +15 -0
  200. package/plugin/vendor/reflexio/reflexio/server/cache/reflexio_cache.py +208 -0
  201. package/plugin/vendor/reflexio/reflexio/server/correlation.py +46 -0
  202. package/plugin/vendor/reflexio/reflexio/server/llm/__init__.py +30 -0
  203. package/plugin/vendor/reflexio/reflexio/server/llm/embedding_service.py +110 -0
  204. package/plugin/vendor/reflexio/reflexio/server/llm/image_utils.py +55 -0
  205. package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +1595 -0
  206. package/plugin/vendor/reflexio/reflexio/server/llm/llm_utils.py +112 -0
  207. package/plugin/vendor/reflexio/reflexio/server/llm/model_defaults.py +469 -0
  208. package/plugin/vendor/reflexio/reflexio/server/llm/providers/__init__.py +1 -0
  209. package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_provider.py +1122 -0
  210. package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_stream_parser.py +197 -0
  211. package/plugin/vendor/reflexio/reflexio/server/llm/providers/embedding_service_provider.py +210 -0
  212. package/plugin/vendor/reflexio/reflexio/server/llm/providers/local_embedding_provider.py +213 -0
  213. package/plugin/vendor/reflexio/reflexio/server/llm/providers/nomic_embedding_provider.py +255 -0
  214. package/plugin/vendor/reflexio/reflexio/server/llm/rerank/__init__.py +6 -0
  215. package/plugin/vendor/reflexio/reflexio/server/llm/rerank/cross_encoder_reranker.py +177 -0
  216. package/plugin/vendor/reflexio/reflexio/server/llm/rerank/llm_reranker.py +148 -0
  217. package/plugin/vendor/reflexio/reflexio/server/llm/tools.py +699 -0
  218. package/plugin/vendor/reflexio/reflexio/server/operation_limiter.py +179 -0
  219. package/plugin/vendor/reflexio/reflexio/server/prompt/__init__.py +0 -0
  220. package/plugin/vendor/reflexio/reflexio/server/prompt/_dispatchers.py +54 -0
  221. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/README.md +121 -0
  222. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/agent_success_evaluation/v1.0.0.prompt.md +58 -0
  223. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/agent_success_evaluation_with_comparison/v1.0.0.prompt.md +76 -0
  224. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/answer_synthesis/v1.5.2.prompt.md +88 -0
  225. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/compress_session_for_query/v1.3.0.prompt.md +31 -0
  226. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/document_expansion/v1.0.0.prompt.md +20 -0
  227. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.0.0.prompt.md +53 -0
  228. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.1.0.prompt.md +57 -0
  229. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.2.0.prompt.md +68 -0
  230. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.3.0.prompt.md +70 -0
  231. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.4.0.prompt.md +77 -0
  232. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.5.0.prompt.md +82 -0
  233. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.6.0.prompt.md +83 -0
  234. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.1.0.prompt.md +193 -0
  235. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.2.0.prompt.md +206 -0
  236. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.0.0-deprecated.prompt.md +66 -0
  237. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.0.0.prompt.md +43 -0
  238. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.1.0.prompt.md +46 -0
  239. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.0.0-deprecated.prompt.md +64 -0
  240. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.0.0.prompt.md +39 -0
  241. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.1.0.prompt.md +39 -0
  242. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.2.0.prompt.md +47 -0
  243. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.0.prompt.md +58 -0
  244. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.0.2.prompt.md +254 -0
  245. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.1.0.prompt.md +274 -0
  246. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.0.prompt.md +279 -0
  247. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v1.0.0.prompt.md +73 -0
  248. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v2.0.0.prompt.md +86 -0
  249. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.0.0.prompt.md +97 -0
  250. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.1.0.prompt.md +119 -0
  251. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.2.0.prompt.md +123 -0
  252. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.3.0.prompt.md +127 -0
  253. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.0.0.prompt.md +14 -0
  254. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.1.0.prompt.md +24 -0
  255. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.2.0.prompt.md +29 -0
  256. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.0.0.prompt.md +11 -0
  257. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.1.0.prompt.md +21 -0
  258. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.2.0.prompt.md +25 -0
  259. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.0.0.prompt.md +37 -0
  260. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.1.0.prompt.md +40 -0
  261. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.2.0.prompt.md +36 -0
  262. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v1.0.0.prompt.md +45 -0
  263. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v2.0.0.prompt.md +81 -0
  264. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v3.0.0.prompt.md +80 -0
  265. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate_expert/v1.0.0.prompt.md +34 -0
  266. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_deduplication/v1.0.0.prompt.md +116 -0
  267. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_should_generate/v1.0.0.prompt.md +33 -0
  268. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_should_generate_override/v1.0.0.prompt.md +16 -0
  269. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.0.0.prompt.md +140 -0
  270. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.1.0.prompt.md +160 -0
  271. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_main/v1.0.0.prompt.md +14 -0
  272. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/query_reformulation/v1.0.0.prompt.md +19 -0
  273. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/rerank_relevance/v1.1.0.prompt.md +44 -0
  274. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_comparison/v1.0.0.prompt.md +43 -0
  275. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_content_evaluation/v1.0.0.prompt.md +33 -0
  276. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_evaluation/prompt_evaluation_dataset/feedback_extraction_main_v1.jsonl +10 -0
  277. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_evaluation/prompt_evaluation_dataset/profile_update_main_v1.jsonl +10 -0
  278. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_manager.py +280 -0
  279. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_schema.py +11 -0
  280. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/_eval_health.py +131 -0
  281. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_constants.py +60 -0
  282. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_service.py +228 -0
  283. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_utils.py +87 -0
  284. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluator.py +372 -0
  285. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/delayed_group_evaluator.py +156 -0
  286. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/group_evaluation_runner.py +340 -0
  287. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/regen_jobs.py +471 -0
  288. package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +1626 -0
  289. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/__init__.py +0 -0
  290. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/_cron.py +196 -0
  291. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/_encryption.py +101 -0
  292. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/client.py +167 -0
  293. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/service.py +281 -0
  294. package/plugin/vendor/reflexio/reflexio/server/services/configurator/base_configurator.py +179 -0
  295. package/plugin/vendor/reflexio/reflexio/server/services/configurator/config_storage.py +62 -0
  296. package/plugin/vendor/reflexio/reflexio/server/services/configurator/configurator.py +87 -0
  297. package/plugin/vendor/reflexio/reflexio/server/services/configurator/local_file_config_storage.py +187 -0
  298. package/plugin/vendor/reflexio/reflexio/server/services/configurator/test_config_storage.py +162 -0
  299. package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +112 -0
  300. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/__init__.py +0 -0
  301. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/distribution.py +33 -0
  302. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/eval_sampler.py +126 -0
  303. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/group_aggregation.py +192 -0
  304. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/hero_state.py +75 -0
  305. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/rule_attribution.py +97 -0
  306. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/service.py +515 -0
  307. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/shadow_aggregation.py +90 -0
  308. package/plugin/vendor/reflexio/reflexio/server/services/extraction/__init__.py +0 -0
  309. package/plugin/vendor/reflexio/reflexio/server/services/extraction/agent_run_records.py +91 -0
  310. package/plugin/vendor/reflexio/reflexio/server/services/extraction/invariants.py +303 -0
  311. package/plugin/vendor/reflexio/reflexio/server/services/extraction/outcome.py +25 -0
  312. package/plugin/vendor/reflexio/reflexio/server/services/extraction/pending_tool_call_dispatch.py +351 -0
  313. package/plugin/vendor/reflexio/reflexio/server/services/extraction/plan.py +138 -0
  314. package/plugin/vendor/reflexio/reflexio/server/services/extraction/prior_answer_search.py +217 -0
  315. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resumable_agent.py +468 -0
  316. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_scheduler.py +171 -0
  317. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_worker.py +777 -0
  318. package/plugin/vendor/reflexio/reflexio/server/services/extraction/tools.py +1125 -0
  319. package/plugin/vendor/reflexio/reflexio/server/services/extractor_config_utils.py +91 -0
  320. package/plugin/vendor/reflexio/reflexio/server/services/extractor_interaction_utils.py +251 -0
  321. package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +689 -0
  322. package/plugin/vendor/reflexio/reflexio/server/services/operation_state_utils.py +835 -0
  323. package/plugin/vendor/reflexio/reflexio/server/services/playbook/README.md +89 -0
  324. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_aggregator.py +1388 -0
  325. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_consolidator.py +960 -0
  326. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_extractor.py +436 -0
  327. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_generation_service.py +808 -0
  328. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_constants.py +28 -0
  329. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_utils.py +362 -0
  330. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/__init__.py +24 -0
  331. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/assistant_webhook.py +246 -0
  332. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/gepa_adapter.py +291 -0
  333. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/judge.py +97 -0
  334. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/models.py +96 -0
  335. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/optimizer.py +645 -0
  336. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/rollout.py +35 -0
  337. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scenario_resolver.py +93 -0
  338. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scheduler.py +174 -0
  339. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/__init__.py +26 -0
  340. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_document_expander.py +179 -0
  341. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_query_reformulator.py +297 -0
  342. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_deduplicator.py +741 -0
  343. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_extractor.py +462 -0
  344. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service.py +734 -0
  345. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service_utils.py +290 -0
  346. package/plugin/vendor/reflexio/reflexio/server/services/reflection/__init__.py +17 -0
  347. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_extractor.py +247 -0
  348. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service.py +800 -0
  349. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service_utils.py +146 -0
  350. package/plugin/vendor/reflexio/reflexio/server/services/retrieval/__init__.py +0 -0
  351. package/plugin/vendor/reflexio/reflexio/server/services/retrieval/relevance_floor.py +70 -0
  352. package/plugin/vendor/reflexio/reflexio/server/services/search/__init__.py +0 -0
  353. package/plugin/vendor/reflexio/reflexio/server/services/service_utils.py +671 -0
  354. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/__init__.py +1 -0
  355. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/judge.py +184 -0
  356. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/outcome.py +81 -0
  357. package/plugin/vendor/reflexio/reflexio/server/services/storage/constants.py +2 -0
  358. package/plugin/vendor/reflexio/reflexio/server/services/storage/error.py +11 -0
  359. package/plugin/vendor/reflexio/reflexio/server/services/storage/retention.py +154 -0
  360. package/plugin/vendor/reflexio/reflexio/server/services/storage/retention_mixin.py +155 -0
  361. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +59 -0
  362. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_agent_run.py +1253 -0
  363. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +1945 -0
  364. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +600 -0
  365. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_operations.py +346 -0
  366. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_playbook.py +1378 -0
  367. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +747 -0
  368. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +263 -0
  369. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_shadow_verdicts.py +193 -0
  370. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_share_links.py +166 -0
  371. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_stall_state.py +217 -0
  372. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +153 -0
  373. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_agent_run.py +372 -0
  374. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_base.py +71 -0
  375. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_extras.py +235 -0
  376. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_operations.py +170 -0
  377. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_playbook.py +677 -0
  378. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_profiles.py +250 -0
  379. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_requests.py +154 -0
  380. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_shadow_verdicts.py +130 -0
  381. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_share_links.py +93 -0
  382. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_stall_state.py +76 -0
  383. package/plugin/vendor/reflexio/reflexio/server/services/unified_search_service.py +568 -0
  384. package/plugin/vendor/reflexio/reflexio/server/site_var/README.md +77 -0
  385. package/plugin/vendor/reflexio/reflexio/server/site_var/feature_flags.py +116 -0
  386. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_manager.py +263 -0
  387. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/feature_flags.json +13 -0
  388. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/llm_model_setting.json +7 -0
  389. package/plugin/vendor/reflexio/reflexio/server/tracing.py +158 -0
  390. package/plugin/vendor/reflexio/reflexio/server/usage_metrics.py +113 -0
  391. package/plugin/vendor/reflexio/reflexio/server/uvicorn_logging.py +76 -0
  392. package/plugin/vendor/reflexio/reflexio/test_support/__init__.py +1 -0
  393. package/plugin/vendor/reflexio/reflexio/test_support/llm_fixtures.py +62 -0
  394. package/plugin/vendor/reflexio/reflexio/test_support/llm_mock.py +242 -0
  395. package/plugin/vendor/reflexio/reflexio/test_support/llm_model_registry.py +129 -0
  396. package/plugin/vendor/reflexio/reflexio/test_support/skip_decorators.py +43 -0
@@ -0,0 +1,373 @@
1
+ """User playbook management commands (list, search, add, delete, regenerate)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Annotated
6
+
7
+ import typer
8
+
9
+ from reflexio.cli.errors import (
10
+ EXIT_VALIDATION,
11
+ CliError,
12
+ handle_errors,
13
+ raise_if_failed,
14
+ )
15
+ from reflexio.cli.output import (
16
+ pagination_meta,
17
+ print_info,
18
+ print_user_playbooks,
19
+ render,
20
+ )
21
+ from reflexio.cli.state import get_client, require_agent_version
22
+
23
+ app = typer.Typer(help="Manage user playbooks.")
24
+
25
+ _STATUS_MAP = {
26
+ "current": "current",
27
+ "pending": "pending",
28
+ "archived": "archived",
29
+ }
30
+
31
+
32
+ @app.command(name="list")
33
+ @handle_errors
34
+ def list_user_playbooks(
35
+ ctx: typer.Context,
36
+ user_id: Annotated[
37
+ str | None,
38
+ typer.Option("--user-id", help="Filter by user ID"),
39
+ ] = None,
40
+ limit: Annotated[
41
+ int,
42
+ typer.Option("--limit", help="Maximum number of playbooks to return"),
43
+ ] = 20,
44
+ playbook_name: Annotated[
45
+ str | None,
46
+ typer.Option("--playbook-name", help="Filter by playbook name"),
47
+ ] = None,
48
+ agent_version: Annotated[
49
+ str | None,
50
+ typer.Option("--agent-version", help="Filter by agent version"),
51
+ ] = None,
52
+ status: Annotated[
53
+ str | None,
54
+ typer.Option("--status", help="Status filter (current/pending/archived)"),
55
+ ] = None,
56
+ ) -> None:
57
+ """List user playbooks.
58
+
59
+ Args:
60
+ ctx: Typer context with CliState in ctx.obj
61
+ user_id: Optional user ID filter
62
+ limit: Maximum number of playbooks to return
63
+ playbook_name: Optional playbook name filter
64
+ agent_version: Optional agent version filter
65
+ status: Optional status filter (current, pending, archived)
66
+ """
67
+ from reflexio.models.api_schema.service_schemas import Status
68
+
69
+ if status and status not in _STATUS_MAP:
70
+ raise CliError(
71
+ error_type="validation",
72
+ message=f"Invalid status: {status}. Must be current, pending, or archived.",
73
+ exit_code=EXIT_VALIDATION,
74
+ )
75
+
76
+ status_filter: list[Status | None] | None = None
77
+ if status == "current":
78
+ status_filter = [Status.CURRENT]
79
+ elif status == "pending":
80
+ status_filter = [Status.PENDING]
81
+ elif status == "archived":
82
+ status_filter = [Status.ARCHIVED]
83
+
84
+ client = get_client(ctx)
85
+ resp = client.get_user_playbooks(
86
+ limit=limit,
87
+ user_id=user_id,
88
+ playbook_name=playbook_name,
89
+ agent_version=agent_version,
90
+ status_filter=status_filter,
91
+ )
92
+ playbooks = resp.user_playbooks or []
93
+
94
+ json_mode: bool = ctx.obj.json_mode
95
+ if json_mode:
96
+ render(playbooks, json_mode=True, meta=pagination_meta(playbooks, limit))
97
+ else:
98
+ print_info(f"Found {len(playbooks)} user playbook(s)")
99
+ if playbooks:
100
+ print_user_playbooks(playbooks)
101
+
102
+
103
+ @app.command()
104
+ @handle_errors
105
+ def search(
106
+ ctx: typer.Context,
107
+ query: Annotated[
108
+ str,
109
+ typer.Argument(help="Semantic search query for user playbooks"),
110
+ ],
111
+ limit: Annotated[
112
+ int,
113
+ typer.Option("--limit", help="Maximum number of results"),
114
+ ] = 10,
115
+ agent_version: Annotated[
116
+ str | None,
117
+ typer.Option("--agent-version", help="Agent version to filter by"),
118
+ ] = None,
119
+ ) -> None:
120
+ """Search user playbooks by semantic query.
121
+
122
+ Args:
123
+ ctx: Typer context with CliState in ctx.obj
124
+ query: Search query string
125
+ limit: Maximum number of results
126
+ agent_version: Optional agent version filter
127
+ """
128
+ client = get_client(ctx)
129
+
130
+ resp = client.search_user_playbooks(
131
+ query=query,
132
+ agent_version=agent_version,
133
+ top_k=limit,
134
+ )
135
+ playbooks = resp.user_playbooks or []
136
+
137
+ json_mode: bool = ctx.obj.json_mode
138
+ if json_mode:
139
+ render(playbooks, json_mode=True, meta=pagination_meta(playbooks, limit))
140
+ else:
141
+ print_info(f"Found {len(playbooks)} user playbook(s)")
142
+ if playbooks:
143
+ print_user_playbooks(playbooks)
144
+
145
+
146
+ @app.command()
147
+ @handle_errors
148
+ def add(
149
+ ctx: typer.Context,
150
+ content: Annotated[
151
+ str,
152
+ typer.Option("--content", help="Playbook content text"),
153
+ ],
154
+ playbook_name: Annotated[
155
+ str,
156
+ typer.Option("--playbook-name", help="Playbook category name"),
157
+ ] = "agent_corrections",
158
+ trigger: Annotated[
159
+ str | None,
160
+ typer.Option("--trigger", help="When this playbook applies"),
161
+ ] = None,
162
+ rationale: Annotated[
163
+ str | None,
164
+ typer.Option("--rationale", help="Why this playbook matters"),
165
+ ] = None,
166
+ agent_version: Annotated[
167
+ str | None,
168
+ typer.Option(
169
+ "--agent-version",
170
+ help="Agent version to tag this playbook with (defaults to 'cli')",
171
+ ),
172
+ ] = None,
173
+ ) -> None:
174
+ """Add a manual user playbook entry.
175
+
176
+ Args:
177
+ ctx: Typer context with CliState in ctx.obj
178
+ content: Playbook content text
179
+ playbook_name: Playbook category name
180
+ trigger: When this playbook applies
181
+ rationale: Why this playbook matters
182
+ agent_version: Agent version label to scope the playbook to;
183
+ defaults to "cli" so CLI-authored entries stay isolated from
184
+ integration-authored ones (e.g. ``openclaw-agent``).
185
+ """
186
+ from reflexio.models.api_schema.service_schemas import UserPlaybook
187
+
188
+ playbook = UserPlaybook(
189
+ agent_version=agent_version or "cli",
190
+ request_id="cli-manual",
191
+ playbook_name=playbook_name,
192
+ content=content,
193
+ trigger=trigger,
194
+ rationale=rationale,
195
+ )
196
+
197
+ client = get_client(ctx)
198
+ resp = client.add_user_playbook([playbook])
199
+
200
+ json_mode: bool = ctx.obj.json_mode
201
+ if json_mode:
202
+ render(resp, json_mode=True)
203
+ else:
204
+ raise_if_failed(resp, default="Failed to add user playbook")
205
+ print_info(f"User playbook added: {content[:80]}")
206
+
207
+
208
+ @app.command()
209
+ @handle_errors
210
+ def update(
211
+ ctx: typer.Context,
212
+ playbook_id: Annotated[
213
+ int,
214
+ typer.Option("--playbook-id", help="User playbook ID to update"),
215
+ ],
216
+ content: Annotated[
217
+ str | None,
218
+ typer.Option("--content", help="New content text"),
219
+ ] = None,
220
+ playbook_name: Annotated[
221
+ str | None,
222
+ typer.Option("--playbook-name", help="New playbook category name"),
223
+ ] = None,
224
+ ) -> None:
225
+ """Update editable fields of a user playbook.
226
+
227
+ Pass only the fields you want to change. Currently supports
228
+ ``--content`` and ``--playbook-name``.
229
+
230
+ Args:
231
+ ctx: Typer context with CliState in ctx.obj
232
+ playbook_id: User playbook ID to update
233
+ content: New content text
234
+ playbook_name: New playbook category name
235
+ """
236
+ if content is None and playbook_name is None:
237
+ raise CliError(
238
+ error_type="validation",
239
+ message=("Pass at least one of --content/--playbook-name to update."),
240
+ exit_code=EXIT_VALIDATION,
241
+ )
242
+
243
+ client = get_client(ctx)
244
+ resp = client.update_user_playbook(
245
+ user_playbook_id=playbook_id,
246
+ content=content,
247
+ playbook_name=playbook_name,
248
+ )
249
+
250
+ json_mode: bool = ctx.obj.json_mode
251
+ if json_mode:
252
+ render(resp, json_mode=True)
253
+ else:
254
+ raise_if_failed(resp, default="Failed to update user playbook")
255
+ print_info(f"User playbook {playbook_id} updated")
256
+
257
+
258
+ @app.command()
259
+ @handle_errors
260
+ def delete(
261
+ ctx: typer.Context,
262
+ playbook_id: Annotated[
263
+ str,
264
+ typer.Option("--playbook-id", help="User playbook ID"),
265
+ ],
266
+ ) -> None:
267
+ """Delete a user playbook by ID.
268
+
269
+ Args:
270
+ ctx: Typer context with CliState in ctx.obj
271
+ playbook_id: User playbook ID to delete
272
+ """
273
+ client = get_client(ctx)
274
+ resp = client.delete_user_playbook(
275
+ user_playbook_id=int(playbook_id),
276
+ wait_for_response=True,
277
+ )
278
+
279
+ json_mode: bool = ctx.obj.json_mode
280
+ if json_mode:
281
+ render(resp, json_mode=True)
282
+ else:
283
+ print_info(f"Deleted user playbook {playbook_id}")
284
+
285
+
286
+ @app.command(name="delete-all")
287
+ @handle_errors
288
+ def delete_all(
289
+ ctx: typer.Context,
290
+ yes: Annotated[
291
+ bool,
292
+ typer.Option("--yes", "-y", help="Skip confirmation prompt"),
293
+ ] = False,
294
+ ) -> None:
295
+ """Delete all user playbooks (user only, not agent playbooks).
296
+
297
+ Uses the dedicated ``DELETE /api/delete_all_user_playbooks`` endpoint,
298
+ which is scoped strictly to user playbooks. To also wipe agent
299
+ playbooks, run ``reflexio agent-playbooks delete-all`` separately.
300
+
301
+ Args:
302
+ ctx: Typer context with CliState in ctx.obj
303
+ yes: If True, skip confirmation prompt
304
+ """
305
+ if not yes:
306
+ confirmed = typer.confirm("Are you sure you want to delete all user playbooks?")
307
+ if not confirmed:
308
+ raise typer.Abort()
309
+
310
+ client = get_client(ctx)
311
+ resp = client.delete_all_user_playbooks()
312
+
313
+ json_mode: bool = ctx.obj.json_mode
314
+ if json_mode:
315
+ render(resp, json_mode=True)
316
+ else:
317
+ print_info("All user playbooks deleted")
318
+
319
+
320
+ @app.command()
321
+ @handle_errors
322
+ def regenerate(
323
+ ctx: typer.Context,
324
+ wait: Annotated[
325
+ bool,
326
+ typer.Option("--wait", help="Wait for regeneration to complete"),
327
+ ] = False,
328
+ agent_version: Annotated[
329
+ str | None,
330
+ typer.Option(
331
+ "--agent-version", help="Agent version to regenerate playbooks for"
332
+ ),
333
+ ] = None,
334
+ ) -> None:
335
+ """Re-extract user playbooks from published interactions.
336
+
337
+ Re-runs the playbook extraction pipeline over all interactions for the
338
+ given agent version, producing fresh user playbooks.
339
+
340
+ Args:
341
+ ctx: Typer context with CliState in ctx.obj
342
+ wait: If True, wait for regeneration to complete
343
+ agent_version: Agent version to regenerate (required)
344
+ """
345
+ client = get_client(ctx)
346
+ resolved_version = require_agent_version(
347
+ agent_version, command_hint="user-playbook regeneration"
348
+ )
349
+
350
+ resp = client.rerun_playbook_generation(
351
+ agent_version=resolved_version,
352
+ wait_for_response=wait,
353
+ )
354
+
355
+ # When waiting, auto-promote PENDING user playbooks to CURRENT so
356
+ # they're immediately visible in `list` output.
357
+ promoted = 0
358
+ if wait:
359
+ try:
360
+ upgrade_resp = client.upgrade_user_playbooks(
361
+ agent_version=resolved_version,
362
+ )
363
+ promoted = upgrade_resp.user_playbooks_promoted
364
+ except Exception:
365
+ print_info("Warning: promotion failed, but regeneration succeeded")
366
+
367
+ json_mode: bool = ctx.obj.json_mode
368
+ if json_mode:
369
+ render(resp, json_mode=True)
370
+ elif wait:
371
+ print_info(f"Playbook regeneration complete ({promoted} playbook(s) promoted)")
372
+ else:
373
+ print_info("Playbook regeneration started")
@@ -0,0 +1,284 @@
1
+ """Shared .env discovery, loading, and mutation utility.
2
+
3
+ Searches for .env in multiple locations. On first run, auto-creates
4
+ ~/.reflexio/.env from the bundled .env.example template.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import importlib.resources
10
+ import logging
11
+ import re
12
+ import secrets
13
+ import sys
14
+ from pathlib import Path
15
+
16
+ _logger = logging.getLogger(__name__)
17
+
18
+ from dotenv import load_dotenv
19
+
20
+ from .paths import reflexio_home
21
+
22
+ _USER_ENV_DIR = reflexio_home()
23
+ _USER_ENV_FILE = _USER_ENV_DIR / ".env"
24
+
25
+
26
+ # Path to the .env file that load_reflexio_env last resolved — None until
27
+ # load_reflexio_env runs for the first time. Exposed via get_loaded_env_path
28
+ # so the startup banner can show the operator exactly which dotenv was
29
+ # picked (./.env vs ~/.reflexio/.env vs auto-created).
30
+ _loaded_env_path: Path | None = None
31
+
32
+
33
+ def get_env_path() -> Path:
34
+ """Return the canonical path to the user-level .env file.
35
+
36
+ Returns:
37
+ Path: ``~/.reflexio/.env``
38
+ """
39
+ return _USER_ENV_FILE
40
+
41
+
42
+ def get_loaded_env_path() -> Path | None:
43
+ """Return the .env path that the most recent ``load_reflexio_env`` call
44
+ resolved, or None if the loader hasn't run yet.
45
+
46
+ Used by the startup banner so operators can see at a glance which
47
+ dotenv file was actually consumed (``./.env`` wins over
48
+ ``~/.reflexio/.env`` when both exist).
49
+ """
50
+ return _loaded_env_path
51
+
52
+
53
+ def set_env_var(env_path: Path, key: str, value: str) -> None:
54
+ """Write or update an environment variable in a .env file.
55
+
56
+ If the key already exists (active or commented-out), the line is replaced
57
+ in-place. Active (uncommented) lines are prioritized over commented ones.
58
+ Values are always wrapped in double quotes for safe parsing.
59
+
60
+ Args:
61
+ env_path (Path): Path to the .env file.
62
+ key (str): Environment variable name.
63
+ value (str): Environment variable value.
64
+ """
65
+ content = env_path.read_text() if env_path.exists() else ""
66
+ lines = content.splitlines()
67
+ pattern = re.compile(rf"^#?\s*{re.escape(key)}=")
68
+ active_idx: int | None = None
69
+ commented_idx: int | None = None
70
+ for i, line in enumerate(lines):
71
+ if not pattern.match(line):
72
+ continue
73
+ if line.lstrip().startswith("#"):
74
+ if commented_idx is None:
75
+ commented_idx = i
76
+ else:
77
+ active_idx = i
78
+ break
79
+ escaped = value.replace("\\", "\\\\").replace('"', '\\"')
80
+ replacement = f'{key}="{escaped}"'
81
+ target = active_idx if active_idx is not None else commented_idx
82
+ if target is not None:
83
+ lines[target] = replacement
84
+ else:
85
+ lines.append(replacement)
86
+ env_path.write_text("\n".join(lines) + "\n")
87
+ env_path.chmod(0o600)
88
+
89
+
90
+ _ENV_SEARCH_PATHS = [
91
+ Path(".env"), # 1. Current directory (local dev / project-level)
92
+ _USER_ENV_FILE, # 2. User home default (~/.reflexio/.env)
93
+ ]
94
+
95
+
96
+ def load_reflexio_env(
97
+ *,
98
+ package_data_module: str = "reflexio.data",
99
+ auto_generate_keys: list[str] | None = None,
100
+ ) -> Path | None:
101
+ """Load .env from the first location found, or auto-create on first run.
102
+
103
+ Search order:
104
+ 1. ./.env (current directory)
105
+ 2. ~/.reflexio/.env (user home)
106
+ 3. Auto-create from bundled .env.example template
107
+
108
+ Args:
109
+ package_data_module: Module containing bundled .env.example
110
+ (for importlib.resources). OS package uses "reflexio.data",
111
+ enterprise uses "reflexio_ext.data".
112
+ auto_generate_keys: Env var names to auto-generate as hex tokens
113
+ (e.g., ["JWT_SECRET_KEY"]).
114
+
115
+ Returns:
116
+ Path to the loaded .env file, or None if no .env was found/created.
117
+ """
118
+ global _loaded_env_path
119
+ for env_path in _ENV_SEARCH_PATHS:
120
+ if env_path.exists():
121
+ load_dotenv(dotenv_path=env_path)
122
+ resolved = env_path.resolve()
123
+ _logger.debug("Loaded env from: %s", resolved)
124
+ _loaded_env_path = resolved
125
+ # Auto-generate any missing secret keys into the existing .env
126
+ _backfill_missing_keys(env_path, auto_generate_keys or [])
127
+ return env_path
128
+
129
+ # No .env found — auto-create from bundled template
130
+ created = _create_default_env(package_data_module, auto_generate_keys or [])
131
+ if created is not None:
132
+ _loaded_env_path = created.resolve()
133
+ return created
134
+
135
+
136
+ def ensure_user_env_for_setup(
137
+ *,
138
+ package_data_module: str = "reflexio.data",
139
+ auto_generate_keys: list[str] | None = None,
140
+ ) -> Path | None:
141
+ """Return ``~/.reflexio/.env``, creating it from the template if missing.
142
+
143
+ Distinct from :func:`load_reflexio_env`: that function honors a CWD-local
144
+ ``./.env`` (intentional for ``services start``, where a project-level
145
+ override should take precedence). For ``setup init`` we never want to
146
+ write to whatever ``.env`` happens to be in the user's CWD — they may be
147
+ running from a worktree or a project root with an unrelated ``.env``,
148
+ and the resulting writes pollute that file and break the documented
149
+ ``~/.reflexio/.env`` invariant.
150
+
151
+ Args:
152
+ package_data_module: Module containing the bundled ``.env.example``
153
+ template (for ``importlib.resources``). OS uses ``reflexio.data``,
154
+ enterprise uses ``reflexio_ext.data``.
155
+ auto_generate_keys: Env var names to auto-fill with random hex
156
+ tokens when creating from the template.
157
+
158
+ Returns:
159
+ Path to ``~/.reflexio/.env`` (existing or newly created), or
160
+ ``None`` if no template could be found.
161
+ """
162
+ global _loaded_env_path
163
+ if _USER_ENV_FILE.exists():
164
+ load_dotenv(dotenv_path=_USER_ENV_FILE)
165
+ resolved = _USER_ENV_FILE.resolve()
166
+ _logger.debug("Loaded user env from: %s", resolved)
167
+ _loaded_env_path = resolved
168
+ _backfill_missing_keys(_USER_ENV_FILE, auto_generate_keys or [])
169
+ return _USER_ENV_FILE
170
+ created = _create_default_env(package_data_module, auto_generate_keys or [])
171
+ if created is not None:
172
+ _loaded_env_path = created.resolve()
173
+ return created
174
+
175
+
176
+ def _backfill_missing_keys(env_path: Path, keys: list[str]) -> None:
177
+ """Generate and write any missing secret keys into an existing .env file.
178
+
179
+ Called when ``load_reflexio_env`` finds a pre-existing .env (e.g. created
180
+ by ``setup init``) that may be missing keys that ``services start``
181
+ requires (like JWT_SECRET_KEY).
182
+
183
+ Args:
184
+ env_path: Path to the existing .env file.
185
+ keys: Env var names to check/generate.
186
+ """
187
+ import os
188
+
189
+ generated: list[str] = []
190
+ for key in keys:
191
+ if os.environ.get(key):
192
+ continue
193
+ token = secrets.token_hex(32)
194
+ set_env_var(env_path, key, token)
195
+ os.environ[key] = token
196
+ generated.append(key)
197
+ if generated:
198
+ sys.stdout.write(f" Auto-generated missing keys: {', '.join(generated)}\n")
199
+ sys.stdout.flush()
200
+
201
+
202
+ def _find_env_example(package_data_module: str) -> str | None:
203
+ """Find .env.example content from CWD or package data.
204
+
205
+ Args:
206
+ package_data_module: Dotted module path for importlib.resources lookup.
207
+
208
+ Returns:
209
+ The template content as a string, or None if not found anywhere.
210
+ """
211
+ # 1. Current directory (local dev checkout)
212
+ local = Path(".env.example")
213
+ if local.exists():
214
+ return local.read_text()
215
+
216
+ # 2. Package data (installed package)
217
+ try:
218
+ ref = importlib.resources.files(package_data_module).joinpath(".env.example")
219
+ return ref.read_text(encoding="utf-8")
220
+ except (ModuleNotFoundError, FileNotFoundError): # fmt: skip
221
+ pass
222
+
223
+ # 3. Editable install: .env.example lives at project root, two levels above reflexio/
224
+ try:
225
+ import reflexio as _pkg
226
+
227
+ project_root = Path(_pkg.__file__).resolve().parent.parent
228
+ candidate = project_root / ".env.example"
229
+ if candidate.is_file():
230
+ return candidate.read_text()
231
+ except Exception: # noqa: BLE001, S110
232
+ pass
233
+
234
+ return None
235
+
236
+
237
+ def _create_default_env(
238
+ package_data_module: str,
239
+ auto_generate_keys: list[str],
240
+ ) -> Path | None:
241
+ """Create ~/.reflexio/.env from .env.example with auto-generated secrets.
242
+
243
+ Args:
244
+ package_data_module: Module path for finding the .env.example template.
245
+ auto_generate_keys: Env var names to auto-fill with random hex tokens.
246
+
247
+ Returns:
248
+ Path to the newly created .env file, or None if template not found.
249
+ """
250
+ content = _find_env_example(package_data_module)
251
+ if content is None:
252
+ sys.stdout.write(
253
+ "Warning: no .env file found and no .env.example template available.\n"
254
+ " Set required environment variables manually.\n"
255
+ )
256
+ sys.stdout.flush()
257
+ return None
258
+
259
+ created_dir = not _USER_ENV_DIR.exists()
260
+ _USER_ENV_DIR.mkdir(parents=True, exist_ok=True)
261
+ if created_dir:
262
+ sys.stdout.write(f"Created directory: {_USER_ENV_DIR}\n")
263
+
264
+ # Auto-generate secret keys
265
+ for key in auto_generate_keys:
266
+ token = secrets.token_hex(32)
267
+ content = re.sub(
268
+ rf"^{re.escape(key)}=.*$",
269
+ f"{key}={token}",
270
+ content,
271
+ count=1,
272
+ flags=re.MULTILINE,
273
+ )
274
+
275
+ _USER_ENV_FILE.write_text(content)
276
+ _USER_ENV_FILE.chmod(0o600)
277
+ load_dotenv(dotenv_path=_USER_ENV_FILE)
278
+
279
+ sys.stdout.write(f"Created env file: {_USER_ENV_FILE}\n")
280
+ if auto_generate_keys:
281
+ sys.stdout.write(f" Auto-generated: {', '.join(auto_generate_keys)}\n")
282
+ sys.stdout.write(f" Edit {_USER_ENV_FILE} to add your API keys.\n\n")
283
+ sys.stdout.flush()
284
+ return _USER_ENV_FILE