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.
- package/.claude-plugin/marketplace.json +3 -3
- package/README.md +34 -5
- package/bin/claude-smart.js +295 -5
- package/package.json +22 -3
- package/plugin/.claude-plugin/plugin.json +4 -2
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/README.md +22 -2
- package/plugin/commands/clear-all.md +1 -0
- package/plugin/commands/dashboard.md +1 -0
- package/plugin/commands/learn.md +1 -0
- package/plugin/commands/restart.md +1 -0
- package/plugin/commands/show.md +1 -0
- package/plugin/dashboard/app/configure/env/page.tsx +40 -14
- package/plugin/dashboard/app/configure/server/page.tsx +51 -1
- package/plugin/dashboard/app/preferences/[id]/page.tsx +8 -8
- package/plugin/dashboard/app/skills/project/[id]/page.tsx +7 -3
- package/plugin/dashboard/app/skills/shared/[id]/page.tsx +10 -3
- package/plugin/dashboard/lib/claude-settings-file.ts +20 -10
- package/plugin/dashboard/lib/reflexio-client.ts +16 -0
- package/plugin/dashboard/lib/status.ts +10 -3
- package/plugin/dashboard/lib/types.ts +18 -6
- package/plugin/hooks/codex-hooks.json +0 -1
- package/plugin/opencode/assistant-buffer.ts +108 -0
- package/plugin/opencode/dist/assistant-buffer.js +96 -0
- package/plugin/opencode/dist/internal.js +12 -0
- package/plugin/opencode/dist/payload.js +85 -0
- package/plugin/opencode/dist/server.mjs +158 -0
- package/plugin/opencode/internal.ts +18 -0
- package/plugin/opencode/package.json +3 -0
- package/plugin/opencode/payload.ts +90 -0
- package/plugin/opencode/server.mts +174 -0
- package/plugin/opencode/tsconfig.json +13 -0
- package/plugin/pyproject.toml +20 -3
- package/plugin/scripts/_lib.sh +77 -29
- package/plugin/scripts/backend-service.sh +27 -5
- package/plugin/scripts/dashboard-service.sh +7 -5
- package/plugin/scripts/ensure-plugin-root.sh +4 -4
- package/plugin/scripts/hook_entry.sh +3 -3
- package/plugin/scripts/opencode-claude-compat +4 -0
- package/plugin/scripts/opencode-claude-compat.cmd +3 -0
- package/plugin/scripts/opencode-claude-compat.js +225 -0
- package/plugin/scripts/smart-install.sh +10 -8
- package/plugin/src/README.md +1 -1
- package/plugin/src/claude_smart/cli.py +304 -6
- package/plugin/src/claude_smart/env_config.py +12 -4
- package/plugin/src/claude_smart/events/session_start.py +26 -7
- package/plugin/src/claude_smart/events/stop.py +1 -1
- package/plugin/src/claude_smart/ids.py +1 -1
- package/plugin/src/claude_smart/reflexio_adapter.py +5 -5
- package/plugin/src/claude_smart/runtime.py +7 -1
- package/plugin/uv.lock +1 -1
- package/plugin/vendor/reflexio/.env.example +54 -30
- package/plugin/vendor/reflexio/README.md +14 -8
- package/plugin/vendor/reflexio/pyproject.toml +13 -1
- package/plugin/vendor/reflexio/reflexio/README.md +1 -0
- package/plugin/vendor/reflexio/reflexio/cli/README.md +9 -7
- package/plugin/vendor/reflexio/reflexio/cli/__main__.py +10 -1
- package/plugin/vendor/reflexio/reflexio/cli/bootstrap_config.py +22 -5
- package/plugin/vendor/reflexio/reflexio/cli/commands/interactions.py +34 -4
- package/plugin/vendor/reflexio/reflexio/cli/commands/profiles.py +12 -7
- package/plugin/vendor/reflexio/reflexio/cli/commands/services.py +13 -6
- package/plugin/vendor/reflexio/reflexio/cli/commands/setup_cmd.py +210 -50
- package/plugin/vendor/reflexio/reflexio/cli/commands/shortcuts.py +15 -2
- package/plugin/vendor/reflexio/reflexio/cli/env_loader.py +292 -22
- package/plugin/vendor/reflexio/reflexio/cli/log_format.py +29 -4
- package/plugin/vendor/reflexio/reflexio/cli/run_services.py +17 -8
- package/plugin/vendor/reflexio/reflexio/cli/stop_services.py +13 -10
- package/plugin/vendor/reflexio/reflexio/client/client.py +57 -13
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/README.md +135 -257
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/npm/openclaw-smart/bin/openclaw-smart.js +13 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/npm/openclaw-smart/package.json +15 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/README.md +38 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/index.ts +151 -110
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/openclaw.plugin.json +20 -10
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/package.json +28 -6
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/pyproject.toml +42 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/_lib.sh +371 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/backend-log-runner.sh +33 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/backend-service.sh +271 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/cli.sh +68 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/dashboard-open.sh +15 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/ensure-plugin-root.sh +84 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/hook_entry.sh +106 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/npm-cli.js +219 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/smart-install.sh +269 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/clear-all/SKILL.md +8 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/dashboard/SKILL.md +8 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/learn/SKILL.md +10 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/reflexio/SKILL.md +15 -44
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/restart/SKILL.md +6 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/show/SKILL.md +8 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/cli.py +634 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/context_format.py +224 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/context_inject.py +79 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/after_tool_call.py +160 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/agent_end.py +187 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/before_prompt_build.py +69 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/before_tool_call.py +30 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/session_end.py +36 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/session_start.py +130 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/hook.py +131 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/ids.py +94 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/internal_call.py +75 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/oc_cite.py +196 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/optimizer_assistant.py +272 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/publish.py +96 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/query_compose.py +66 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/reflexio_adapter.py +336 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/runtime.py +47 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/stall_banner.py +61 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/state.py +323 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_e2e_session_loop.py +190 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_publish_to_local_reflexio_integration.py +112 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_recursion_guard_integration.py +86 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_search_inject_integration.py +144 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_cli.py +184 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_after_tool_call.py +142 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_agent_end.py +233 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_before_prompt_build.py +116 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_before_tool_call.py +35 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_session_end.py +47 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_session_start.py +109 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_hook_dispatch.py +117 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_ids.py +41 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_internal_call.py +50 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_oc_cite.py +88 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_publish.py +48 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_query_compose.py +48 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_reflexio_adapter.py +188 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_runtime.py +41 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_state.py +235 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests-ts/__mocks__/plugin-entry-stub.ts +6 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests-ts/test_npm_cli.test.ts +56 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests-ts/test_shim_dispatch.test.ts +171 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tsconfig.build.json +18 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/{tsconfig.json → plugin/tsconfig.json} +2 -2
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/uv.lock +3835 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/vitest.config.ts +18 -0
- package/plugin/vendor/reflexio/reflexio/lib/_agent_playbook.py +238 -10
- package/plugin/vendor/reflexio/reflexio/lib/_config.py +11 -4
- package/plugin/vendor/reflexio/reflexio/lib/_generation.py +16 -5
- package/plugin/vendor/reflexio/reflexio/lib/_lineage_parity_readers.py +187 -0
- package/plugin/vendor/reflexio/reflexio/lib/_profiles.py +198 -6
- package/plugin/vendor/reflexio/reflexio/lib/_reflection.py +1 -1
- package/plugin/vendor/reflexio/reflexio/lib/_search.py +29 -20
- package/plugin/vendor/reflexio/reflexio/lib/_user_playbook.py +2 -1
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/entities.py +127 -38
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/enums.py +4 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/eval_overview_schema.py +64 -41
- package/plugin/vendor/reflexio/reflexio/models/api_schema/internal_schema.py +19 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/pending_tool_call_schema.py +12 -5
- package/plugin/vendor/reflexio/reflexio/models/api_schema/retriever_schema.py +52 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/converters.py +5 -1
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/entities.py +5 -1
- package/plugin/vendor/reflexio/reflexio/models/config_schema.py +88 -7
- package/plugin/vendor/reflexio/reflexio/models/structured_output.py +148 -0
- package/plugin/vendor/reflexio/reflexio/server/OVERVIEW.md +3 -3
- package/plugin/vendor/reflexio/reflexio/server/README.md +45 -32
- package/plugin/vendor/reflexio/reflexio/server/__init__.py +29 -5
- package/plugin/vendor/reflexio/reflexio/server/__main__.py +2 -2
- package/plugin/vendor/reflexio/reflexio/server/_auth.py +65 -2
- package/plugin/vendor/reflexio/reflexio/server/api.py +734 -85
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/precondition_checks.py +7 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/request_context.py +3 -1
- package/plugin/vendor/reflexio/reflexio/server/billing_meter.py +173 -0
- package/plugin/vendor/reflexio/reflexio/server/billing_signals.py +64 -0
- package/plugin/vendor/reflexio/reflexio/server/cache/reflexio_cache.py +46 -16
- package/plugin/vendor/reflexio/reflexio/server/env_utils.py +65 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/embedding_service.py +19 -4
- package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +264 -77
- package/plugin/vendor/reflexio/reflexio/server/llm/llm_utils.py +69 -7
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/embedding_service_provider.py +75 -16
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/openclaw_provider.py +280 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/token_accounting.py +48 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/tools.py +107 -17
- package/plugin/vendor/reflexio/reflexio/server/operation_limiter.py +360 -4
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.6.0.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.7.0.prompt.md +85 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.2.0.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.3.0.prompt.md +253 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.2.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.3.prompt.md +74 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.3.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.3.0.prompt.md +266 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.4.0.prompt.md +266 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.3.0.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.4.0.prompt.md +137 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.2.0.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.3.0.prompt.md +34 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.0.0.prompt.md +5 -12
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.1.0.prompt.md +5 -12
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.2.0.prompt.md +155 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/tagging/v1.0.0.prompt.md +23 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_manager.py +89 -32
- package/plugin/vendor/reflexio/reflexio/server/services/README.md +26 -11
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/README.md +22 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_constants.py +4 -2
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_utils.py +1 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/components/__init__.py +7 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{agent_success_evaluator.py → components/evaluator.py} +3 -16
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/regen_jobs.py +28 -72
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{group_evaluation_runner.py → runner.py} +12 -10
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{delayed_group_evaluator.py → scheduler.py} +10 -2
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{agent_success_evaluation_service.py → service.py} +36 -1
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +160 -0
- package/plugin/vendor/reflexio/reflexio/server/services/configurator/base_configurator.py +5 -0
- package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +1 -1
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/README.md +9 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/components/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{rule_attribution.py → components/rule_attribution.py} +10 -9
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/eval_sampler.py +15 -24
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/service.py +238 -164
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/README.md +31 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/outcome.py +13 -3
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/pending_tool_call_dispatch.py +3 -2
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resumable_agent.py +32 -118
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_worker.py +39 -16
- package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +105 -23
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/gc_scheduler.py +193 -0
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/resolve.py +98 -0
- package/plugin/vendor/reflexio/reflexio/server/services/operation_state_utils.py +26 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/README.md +11 -12
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/__init__.py +5 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_aggregator.py → components/aggregator.py} +316 -178
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_consolidator.py → components/consolidator.py} +168 -62
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_extractor.py → components/extractor.py} +5 -1
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_edit_apply.py +74 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_utils.py +33 -3
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_generation_service.py → service.py} +121 -19
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/user_detail_stripping.py +84 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/README.md +10 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/models.py +2 -1
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/optimizer.py +178 -30
- package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/README.md +9 -0
- package/plugin/vendor/reflexio/reflexio/server/services/profile/components/__init__.py +17 -0
- package/plugin/vendor/reflexio/reflexio/server/services/profile/{profile_deduplicator.py → components/consolidator.py} +7 -6
- package/plugin/vendor/reflexio/reflexio/server/services/profile/{profile_extractor.py → components/extractor.py} +30 -22
- package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service_utils.py +6 -13
- package/plugin/vendor/reflexio/reflexio/server/services/profile/{profile_generation_service.py → service.py} +32 -50
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/__init__.py +4 -8
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/components/__init__.py +7 -0
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service_utils.py +12 -1
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/{reflection_service.py → service.py} +36 -16
- package/plugin/vendor/reflexio/reflexio/server/services/retrieval/relevance_floor.py +83 -6
- package/plugin/vendor/reflexio/reflexio/server/services/service_utils.py +36 -1
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/README.md +8 -0
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/outcome.py +1 -2
- package/plugin/vendor/reflexio/reflexio/server/services/storage/error.py +27 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/retention.py +9 -9
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +2 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_agent_run.py +4 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +642 -197
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +61 -104
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_lineage.py +628 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_operations.py +38 -6
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_playbook.py +978 -184
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +519 -128
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +77 -3
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_shadow_verdicts.py +23 -9
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_stall_state.py +5 -2
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +131 -20
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_agent_run.py +2 -8
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_base.py +5 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_extras.py +36 -53
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_lineage.py +215 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_operations.py +20 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_playbook.py +243 -7
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_profiles.py +121 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_requests.py +60 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_retrieval_log.py +51 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_shadow_verdicts.py +17 -0
- package/plugin/vendor/reflexio/reflexio/server/services/tagging/README.md +8 -0
- package/plugin/vendor/reflexio/reflexio/server/services/tagging/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/server/services/tagging/service.py +200 -0
- package/plugin/vendor/reflexio/reflexio/server/services/tagging/tagging_scheduler.py +149 -0
- package/plugin/vendor/reflexio/reflexio/server/services/unified_search_service.py +229 -32
- package/plugin/vendor/reflexio/reflexio/server/site_var/README.md +2 -1
- package/plugin/vendor/reflexio/reflexio/server/site_var/feature_flags.py +120 -1
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/feature_flags.json +4 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/search_settings.json +5 -0
- package/plugin/vendor/reflexio/reflexio/server/tracing.py +30 -0
- package/plugin/vendor/reflexio/reflexio/server/usage_metrics.py +18 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_mock.py +61 -26
- package/plugin/vendor/reflexio/reflexio/test_support/llm_model_registry.py +41 -4
- package/scripts/setup-claude-smart.sh +8 -3
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/TESTING.md +0 -517
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/hook/handler.js +0 -473
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package-lock.json +0 -2156
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package.json +0 -18
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/handler.ts +0 -241
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/setup.ts +0 -140
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/publish.ts +0 -113
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/search.ts +0 -52
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/server.ts +0 -103
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/sqlite-buffer.ts +0 -156
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/user-id.ts +0 -134
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/rules/reflexio.md +0 -24
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/publish_clawhub.sh +0 -278
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/references/HOOK.md +0 -164
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/install.sh +0 -36
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/uninstall.sh +0 -35
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/publish.test.ts +0 -27
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/search.test.ts +0 -31
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/server.test.ts +0 -42
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/setup.test.ts +0 -49
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/sqlite-buffer.test.ts +0 -91
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/user-id.test.ts +0 -50
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/vitest.config.ts +0 -13
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/group_aggregation.py +0 -192
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/invariants.py +0 -303
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/plan.py +0 -138
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/tools.py +0 -1125
- /package/plugin/vendor/reflexio/reflexio/integrations/{__init__.py → openclaw/plugin/src/openclaw_smart/__init__.py} +0 -0
- /package/plugin/vendor/reflexio/reflexio/integrations/openclaw/{types → plugin/types}/openclaw.d.ts +0 -0
- /package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{distribution.py → components/distribution.py} +0 -0
- /package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{hero_state.py → components/hero_state.py} +0 -0
- /package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{shadow_aggregation.py → components/shadow_aggregation.py} +0 -0
- /package/plugin/vendor/reflexio/reflexio/server/services/reflection/{reflection_extractor.py → components/extractor.py} +0 -0
package/plugin/scripts/_lib.sh
CHANGED
|
@@ -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
|
|
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="$(
|
|
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/.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
531
|
-
#
|
|
532
|
-
#
|
|
533
|
-
#
|
|
534
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
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}" = "
|
|
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
|
|
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
|
-
|
|
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 ~/.
|
|
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/.
|
|
39
|
-
FOLLOW="$(grep -E '^CLAUDE_SMART_PLUGIN_ROOT_FOLLOW_SESSION=' "$HOME/.
|
|
40
|
-
| tail -n1 |
|
|
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,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/.
|
|
112
|
-
grep -qE '^(export[[:space:]]+)?CLAUDE_SMART_USE_LOCAL_CLI=' "$HOME/.
|
|
113
|
-
grep -qE '^(export[[:space:]]+)?CLAUDE_SMART_USE_LOCAL_EMBEDDING=' "$HOME/.
|
|
114
|
-
grep -qE '^(export[[:space:]]+)?CLAUDE_SMART_READ_ONLY=' "$HOME/.
|
|
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
|
-
#
|
|
484
|
-
#
|
|
485
|
-
#
|
|
486
|
-
|
|
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
|
}
|
package/plugin/src/README.md
CHANGED
|
@@ -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 `~/.
|
|
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. |
|