claude-smart 0.2.45 → 0.2.47
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 +47 -10
- package/bin/claude-smart.js +535 -23
- 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 +27 -6
- 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/layout.tsx +20 -0
- 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 +232 -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 +251 -0
- package/plugin/opencode/tsconfig.json +13 -0
- package/plugin/pyproject.toml +25 -4
- package/plugin/scripts/_lib.sh +5 -1
- package/plugin/scripts/backend-service.sh +22 -2
- package/plugin/scripts/ensure-plugin-root.sh +4 -4
- package/plugin/scripts/hook_entry.sh +1 -1
- 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 +17 -9
- package/plugin/src/README.md +1 -1
- package/plugin/src/claude_smart/cli.py +498 -12
- package/plugin/src/claude_smart/context_format.py +9 -9
- package/plugin/src/claude_smart/cs_cite.py +66 -19
- 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 +5 -5
- package/plugin/vendor/reflexio/.env.example +54 -30
- package/plugin/vendor/reflexio/README.md +17 -11
- package/plugin/vendor/reflexio/pyproject.toml +13 -1
- package/plugin/vendor/reflexio/reflexio/README.md +4 -1
- 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 +212 -52
- 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/cli/utils.py +44 -1
- package/plugin/vendor/reflexio/reflexio/client/client.py +154 -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 +246 -10
- package/plugin/vendor/reflexio/reflexio/lib/_base.py +15 -0
- package/plugin/vendor/reflexio/reflexio/lib/_config.py +11 -4
- package/plugin/vendor/reflexio/reflexio/lib/_generation.py +17 -5
- package/plugin/vendor/reflexio/reflexio/lib/_lineage_parity_readers.py +187 -0
- package/plugin/vendor/reflexio/reflexio/lib/_profiles.py +224 -21
- package/plugin/vendor/reflexio/reflexio/lib/_reflection.py +1 -1
- package/plugin/vendor/reflexio/reflexio/lib/_search.py +52 -25
- package/plugin/vendor/reflexio/reflexio/lib/_user_playbook.py +11 -1
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/__init__.py +1 -0
- 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/domain/governance.py +117 -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 +97 -3
- 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 +104 -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 +58 -33
- 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/api.py +899 -103
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/precondition_checks.py +7 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/request_context.py +4 -2
- package/plugin/vendor/reflexio/reflexio/server/auth.py +90 -0
- 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/extensions.py +213 -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/model_defaults.py +4 -4
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_provider.py +1 -1
- 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/rerank/cross_encoder_reranker.py +12 -1
- 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 +278 -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 +28 -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 +47 -16
- package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +105 -23
- package/plugin/vendor/reflexio/reflexio/server/services/governance/config.py +52 -0
- package/plugin/vendor/reflexio/reflexio/server/services/governance/service.py +378 -0
- package/plugin/vendor/reflexio/reflexio/server/services/governance/subject_refs.py +34 -0
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/gc_scheduler.py +219 -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 +18 -11
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/aggregation_prompt_processing.py +100 -0
- 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} +334 -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_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} +31 -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/recency.py +211 -0
- package/plugin/vendor/reflexio/reflexio/server/services/retrieval/relevance_floor.py +99 -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 +31 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/governance_validation.py +681 -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 +16 -2
- 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 +644 -197
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +106 -119
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_governance.py +1965 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_lineage.py +630 -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 +31 -1369
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +756 -210
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +148 -34
- 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/sqlite_storage/playbook/__init__.py +13 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_agent.py +952 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_eval_results.py +189 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_optimization.py +247 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_source_linkage.py +145 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_user.py +838 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +150 -23
- 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 +40 -57
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_governance.py +148 -0
- 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 +4 -677
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_profiles.py +134 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_requests.py +62 -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/storage/storage_base/playbook/__init__.py +13 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_agent.py +365 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_eval_results.py +124 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_optimization.py +85 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_source_linkage.py +47 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_user.py +333 -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 +372 -34
- 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/_auth.py +0 -25
- 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/bin/claude-smart.js
CHANGED
|
@@ -17,13 +17,17 @@ const { execSync, spawn, spawnSync } = require("child_process");
|
|
|
17
17
|
const crypto = require("crypto");
|
|
18
18
|
const {
|
|
19
19
|
chmodSync,
|
|
20
|
+
constants,
|
|
20
21
|
cpSync,
|
|
21
22
|
existsSync,
|
|
23
|
+
accessSync,
|
|
22
24
|
lstatSync,
|
|
23
25
|
mkdirSync,
|
|
24
26
|
readFileSync,
|
|
25
27
|
readdirSync,
|
|
28
|
+
realpathSync,
|
|
26
29
|
renameSync,
|
|
30
|
+
rmdirSync,
|
|
27
31
|
rmSync,
|
|
28
32
|
statSync,
|
|
29
33
|
symlinkSync,
|
|
@@ -31,12 +35,15 @@ const {
|
|
|
31
35
|
} = require("fs");
|
|
32
36
|
const https = require("https");
|
|
33
37
|
const { arch, homedir, platform, release, tmpdir } = require("os");
|
|
34
|
-
const { dirname, join } = require("path");
|
|
38
|
+
const { dirname, join, resolve } = require("path");
|
|
39
|
+
const { fileURLToPath, pathToFileURL } = require("url");
|
|
35
40
|
|
|
36
41
|
const PLUGIN_SPEC = "claude-smart@reflexioai";
|
|
37
42
|
const CODEX_MARKETPLACE_NAME = "reflexioai";
|
|
38
43
|
const CODEX_MARKETPLACE_DISPLAY_NAME = "ReflexioAI";
|
|
39
44
|
const CODEX_PLUGIN_ID = `claude-smart@${CODEX_MARKETPLACE_NAME}`;
|
|
45
|
+
const OPENCODE_BARE_PLUGIN_SPEC = "claude-smart";
|
|
46
|
+
const OPENCODE_CONFIG_NAMES = ["opencode.json", "opencode.jsonc"];
|
|
40
47
|
const REFLEXIO_ENV_PATH = join(homedir(), ".reflexio", ".env");
|
|
41
48
|
const MANAGED_REFLEXIO_URL = "https://www.reflexio.ai/";
|
|
42
49
|
const MANAGED_SETUP_ENV = "CLAUDE_SMART_MANAGED_SETUP";
|
|
@@ -46,6 +53,9 @@ const CLAUDE_SMART_USE_LOCAL_EMBEDDING_ENV = "CLAUDE_SMART_USE_LOCAL_EMBEDDING";
|
|
|
46
53
|
const REFLEXIO_USER_ID_ENV = "REFLEXIO_USER_ID";
|
|
47
54
|
const REFLEXIO_DIR = join(homedir(), ".reflexio");
|
|
48
55
|
const CLAUDE_SMART_STATE_DIR = join(homedir(), ".claude-smart");
|
|
56
|
+
const OPENCODE_LOCAL_PACKAGE_DIR = join(CLAUDE_SMART_STATE_DIR, "opencode", "claude-smart");
|
|
57
|
+
const OPENCODE_PACKAGE_LOCK_TIMEOUT_MS = 120_000;
|
|
58
|
+
const OPENCODE_PACKAGE_LOCK_STALE_MS = 10 * 60_000;
|
|
49
59
|
const CODEX_CONFIG_PATH = join(homedir(), ".codex", "config.toml");
|
|
50
60
|
const PACKAGE_ROOT = dirname(dirname(__filename));
|
|
51
61
|
const CODEX_MARKETPLACE_DIR = join(
|
|
@@ -79,6 +89,9 @@ const CODEX_REQUIRED_FILES = [
|
|
|
79
89
|
"plugin/scripts/codex-claude-compat",
|
|
80
90
|
"plugin/scripts/codex-claude-compat.cmd",
|
|
81
91
|
"plugin/scripts/codex-claude-compat.js",
|
|
92
|
+
"plugin/scripts/opencode-claude-compat",
|
|
93
|
+
"plugin/scripts/opencode-claude-compat.cmd",
|
|
94
|
+
"plugin/scripts/opencode-claude-compat.js",
|
|
82
95
|
"plugin/scripts/codex-hook.js",
|
|
83
96
|
"plugin/scripts/_codex_env.sh",
|
|
84
97
|
];
|
|
@@ -89,6 +102,7 @@ const COPYTREE_IGNORE_NAMES = new Set([
|
|
|
89
102
|
".venv",
|
|
90
103
|
".pytest_cache",
|
|
91
104
|
".ruff_cache",
|
|
105
|
+
".git",
|
|
92
106
|
"node_modules",
|
|
93
107
|
".next",
|
|
94
108
|
]);
|
|
@@ -342,6 +356,200 @@ function configureReflexioSetup() {
|
|
|
342
356
|
return loadReflexioSetupEnv();
|
|
343
357
|
}
|
|
344
358
|
|
|
359
|
+
function stripJsonc(text) {
|
|
360
|
+
let out = "";
|
|
361
|
+
let inString = false;
|
|
362
|
+
let escaped = false;
|
|
363
|
+
const skipTrivia = (index) => {
|
|
364
|
+
while (index < text.length) {
|
|
365
|
+
while (index < text.length && /\s/.test(text[index])) index += 1;
|
|
366
|
+
if (text[index] === "/" && text[index + 1] === "/") {
|
|
367
|
+
index += 2;
|
|
368
|
+
while (index < text.length && !"\r\n".includes(text[index])) index += 1;
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
if (text[index] === "/" && text[index + 1] === "*") {
|
|
372
|
+
index += 2;
|
|
373
|
+
while (index + 1 < text.length && !(text[index] === "*" && text[index + 1] === "/")) index += 1;
|
|
374
|
+
index = Math.min(index + 2, text.length);
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
return index;
|
|
380
|
+
};
|
|
381
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
382
|
+
const ch = text[i];
|
|
383
|
+
const next = text[i + 1] || "";
|
|
384
|
+
if (inString) {
|
|
385
|
+
out += ch;
|
|
386
|
+
if (escaped) escaped = false;
|
|
387
|
+
else if (ch === "\\") escaped = true;
|
|
388
|
+
else if (ch === '"') inString = false;
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
if (ch === '"') {
|
|
392
|
+
inString = true;
|
|
393
|
+
out += ch;
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
if (ch === "/" && next === "/") {
|
|
397
|
+
while (i < text.length && !"\r\n".includes(text[i])) i += 1;
|
|
398
|
+
i -= 1;
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
if (ch === "/" && next === "*") {
|
|
402
|
+
i += 2;
|
|
403
|
+
while (i + 1 < text.length && !(text[i] === "*" && text[i + 1] === "/")) i += 1;
|
|
404
|
+
i += 1;
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
if (ch === ",") {
|
|
408
|
+
const j = skipTrivia(i + 1);
|
|
409
|
+
if (text[j] === "}" || text[j] === "]") continue;
|
|
410
|
+
}
|
|
411
|
+
out += ch;
|
|
412
|
+
}
|
|
413
|
+
return out;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function readJsoncObject(path) {
|
|
417
|
+
const text = existsSync(path) ? readFileSync(path, "utf8") : "{}";
|
|
418
|
+
const parsed = JSON.parse(stripJsonc(text || "{}"));
|
|
419
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
420
|
+
throw new Error(`OpenCode config ${path} must be a JSON object`);
|
|
421
|
+
}
|
|
422
|
+
return parsed;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function parseGlobalFlag(args) {
|
|
426
|
+
return args.includes("--global");
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function opencodeGlobalConfigDir() {
|
|
430
|
+
const xdg = (process.env.XDG_CONFIG_HOME || "").trim();
|
|
431
|
+
const base = xdg ? xdg : join(homedir(), ".config");
|
|
432
|
+
return join(base, "opencode");
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
function opencodeConfigPath(args = [], cwd = process.cwd()) {
|
|
436
|
+
if (parseGlobalFlag(args)) {
|
|
437
|
+
const configDir = opencodeGlobalConfigDir();
|
|
438
|
+
for (const name of OPENCODE_CONFIG_NAMES) {
|
|
439
|
+
const candidate = join(configDir, name);
|
|
440
|
+
if (existsSync(candidate)) return candidate;
|
|
441
|
+
}
|
|
442
|
+
return join(configDir, "opencode.json");
|
|
443
|
+
}
|
|
444
|
+
const candidates = [
|
|
445
|
+
...OPENCODE_CONFIG_NAMES.map((name) => join(cwd, name)),
|
|
446
|
+
...OPENCODE_CONFIG_NAMES.map((name) => join(cwd, ".opencode", name)),
|
|
447
|
+
];
|
|
448
|
+
for (const candidate of candidates) {
|
|
449
|
+
if (existsSync(candidate)) return candidate;
|
|
450
|
+
}
|
|
451
|
+
return join(cwd, "opencode.json");
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
function opencodePluginSpec(entry) {
|
|
455
|
+
if (typeof entry === "string") return entry;
|
|
456
|
+
if (Array.isArray(entry) && typeof entry[0] === "string") return entry[0];
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
function opencodeLocalPluginSpec(packageRoot = OPENCODE_LOCAL_PACKAGE_DIR) {
|
|
461
|
+
return pathToFileURL(packageRoot).href;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function isOpenCodeLocalPackagePath(packagePath) {
|
|
465
|
+
return (
|
|
466
|
+
sameRealPath(packagePath, OPENCODE_LOCAL_PACKAGE_DIR) ||
|
|
467
|
+
resolve(packagePath) === resolve(OPENCODE_LOCAL_PACKAGE_DIR)
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
function isOpenCodeClaudeSmartSpec(spec) {
|
|
472
|
+
if (!spec) return false;
|
|
473
|
+
if (spec === OPENCODE_BARE_PLUGIN_SPEC || spec.startsWith(`${OPENCODE_BARE_PLUGIN_SPEC}@`)) {
|
|
474
|
+
return true;
|
|
475
|
+
}
|
|
476
|
+
if (!spec.startsWith("file://")) return false;
|
|
477
|
+
let packagePath = null;
|
|
478
|
+
try {
|
|
479
|
+
packagePath = fileURLToPath(spec);
|
|
480
|
+
} catch {
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
483
|
+
if (isOpenCodeLocalPackagePath(packagePath)) return true;
|
|
484
|
+
try {
|
|
485
|
+
const manifest = JSON.parse(readFileSync(join(packagePath, "package.json"), "utf8"));
|
|
486
|
+
if (manifest && manifest.name === OPENCODE_BARE_PLUGIN_SPEC) return true;
|
|
487
|
+
} catch {
|
|
488
|
+
// Missing or malformed manifests are not enough to identify arbitrary file specs.
|
|
489
|
+
}
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
function patchOpenCodePluginConfig(configPath, { install, pluginSpec = null }) {
|
|
494
|
+
const resolvedPluginSpec = install ? (pluginSpec || opencodeLocalPluginSpec()) : pluginSpec;
|
|
495
|
+
const data = readJsoncObject(configPath);
|
|
496
|
+
for (const field of ["plugins", "plugin"]) {
|
|
497
|
+
if (data[field] !== undefined && !Array.isArray(data[field])) {
|
|
498
|
+
throw new Error(`OpenCode config ${configPath} field "${field}" must be a JSON array`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
const current = [
|
|
502
|
+
...(Array.isArray(data.plugin) ? data.plugin : []),
|
|
503
|
+
...(Array.isArray(data.plugins) ? data.plugins : []),
|
|
504
|
+
];
|
|
505
|
+
const kept = current.filter((entry) => !isOpenCodeClaudeSmartSpec(opencodePluginSpec(entry)));
|
|
506
|
+
const next = install ? [...kept, resolvedPluginSpec] : kept;
|
|
507
|
+
const changed =
|
|
508
|
+
data.plugins !== undefined ||
|
|
509
|
+
(Array.isArray(data.plugin)
|
|
510
|
+
? next.length !== data.plugin.length || next.some((entry, index) => entry !== data.plugin[index])
|
|
511
|
+
: install && next.length > 0);
|
|
512
|
+
if (!changed) return { changed: false, configPath };
|
|
513
|
+
let backupPath = null;
|
|
514
|
+
if (existsSync(configPath)) {
|
|
515
|
+
const original = readFileSync(configPath, "utf8");
|
|
516
|
+
if (original.trim() && original !== stripJsonc(original)) {
|
|
517
|
+
backupPath = `${configPath}.bak`;
|
|
518
|
+
writeFileSync(backupPath, original);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
data.plugin = next;
|
|
522
|
+
delete data.plugins;
|
|
523
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
524
|
+
writeFileSync(configPath, JSON.stringify(data, null, 2) + "\n");
|
|
525
|
+
return { changed: true, configPath, backupPath };
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
function hasExtractionProvider() {
|
|
529
|
+
if ((process.env.REFLEXIO_API_KEY || "").trim()) return true;
|
|
530
|
+
const cliPath = (process.env.CLAUDE_SMART_CLI_PATH || "").trim();
|
|
531
|
+
if (cliPath && isExecutableFile(cliPath)) return true;
|
|
532
|
+
return hasCli("claude") || hasCli("codex") || hasCli("opencode");
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
function isExecutableFile(path) {
|
|
536
|
+
try {
|
|
537
|
+
if (!statSync(path).isFile()) return false;
|
|
538
|
+
accessSync(path, constants.X_OK);
|
|
539
|
+
return true;
|
|
540
|
+
} catch {
|
|
541
|
+
return false;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
function extractionProviderError() {
|
|
546
|
+
return (
|
|
547
|
+
"error: OpenCode support needs a working learning/extraction provider.\n" +
|
|
548
|
+
"Run `npx claude-smart setup` to configure Reflexio, or install " +
|
|
549
|
+
"OpenCode, Claude Code, or Codex so local extraction can use a supported CLI.\n"
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
|
|
345
553
|
function findClaudeCodePluginRoot() {
|
|
346
554
|
const cacheRoot = join(homedir(), ".claude", "plugins", "cache", CODEX_MARKETPLACE_NAME, "claude-smart");
|
|
347
555
|
const candidates = [];
|
|
@@ -429,6 +637,130 @@ function forcePluginRoot(pluginRoot) {
|
|
|
429
637
|
}
|
|
430
638
|
}
|
|
431
639
|
|
|
640
|
+
function sameRealPath(left, right) {
|
|
641
|
+
try {
|
|
642
|
+
return realpathSync(left) === realpathSync(right);
|
|
643
|
+
} catch {
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
function pathEntryExists(path) {
|
|
649
|
+
try {
|
|
650
|
+
lstatSync(path);
|
|
651
|
+
return true;
|
|
652
|
+
} catch {
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
function fileSha256(path) {
|
|
658
|
+
return crypto.createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
function verifyOpenCodePluginPackage(packageRoot) {
|
|
662
|
+
const sourceScript = join(PACKAGE_ROOT, "plugin", "scripts", "smart-install.sh");
|
|
663
|
+
const copiedScript = join(packageRoot, "plugin", "scripts", "smart-install.sh");
|
|
664
|
+
for (const file of [join(packageRoot, "package.json"), copiedScript]) {
|
|
665
|
+
if (!existsSync(file)) {
|
|
666
|
+
throw new Error(`OpenCode local plugin package is missing ${file}`);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
if (fileSha256(sourceScript) !== fileSha256(copiedScript)) {
|
|
670
|
+
throw new Error(
|
|
671
|
+
"OpenCode local plugin package does not match the installed claude-smart package",
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
function sleepSync(ms) {
|
|
677
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
function withOpenCodePackageInstallLock(fn) {
|
|
681
|
+
const lockDir = join(dirname(OPENCODE_LOCAL_PACKAGE_DIR), ".install.lock");
|
|
682
|
+
mkdirSync(dirname(OPENCODE_LOCAL_PACKAGE_DIR), { recursive: true });
|
|
683
|
+
const deadline = Date.now() + OPENCODE_PACKAGE_LOCK_TIMEOUT_MS;
|
|
684
|
+
while (true) {
|
|
685
|
+
try {
|
|
686
|
+
mkdirSync(lockDir);
|
|
687
|
+
break;
|
|
688
|
+
} catch (err) {
|
|
689
|
+
if (!err || err.code !== "EEXIST") throw err;
|
|
690
|
+
try {
|
|
691
|
+
if (Date.now() - statSync(lockDir).mtimeMs > OPENCODE_PACKAGE_LOCK_STALE_MS) {
|
|
692
|
+
rmSync(lockDir, { recursive: true, force: true });
|
|
693
|
+
continue;
|
|
694
|
+
}
|
|
695
|
+
} catch (statErr) {
|
|
696
|
+
if (statErr && statErr.code !== "ENOENT") throw statErr;
|
|
697
|
+
}
|
|
698
|
+
if (Date.now() >= deadline) {
|
|
699
|
+
throw new Error(`timed out waiting for OpenCode package install lock at ${lockDir}`);
|
|
700
|
+
}
|
|
701
|
+
sleepSync(100);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
try {
|
|
705
|
+
return fn();
|
|
706
|
+
} finally {
|
|
707
|
+
rmSync(lockDir, { recursive: true, force: true });
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
function uniqueOpenCodePackagePath(prefix) {
|
|
712
|
+
return join(
|
|
713
|
+
dirname(OPENCODE_LOCAL_PACKAGE_DIR),
|
|
714
|
+
`${prefix}-${process.pid}-${Date.now()}-${crypto.randomBytes(4).toString("hex")}`,
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
function replaceOpenCodePluginPackage(stagedPackage, packageRoot) {
|
|
719
|
+
const backupPackage = uniqueOpenCodePackagePath(".claude-smart-previous");
|
|
720
|
+
let backupCreated = false;
|
|
721
|
+
try {
|
|
722
|
+
if (pathEntryExists(packageRoot)) {
|
|
723
|
+
renameSync(packageRoot, backupPackage);
|
|
724
|
+
backupCreated = true;
|
|
725
|
+
}
|
|
726
|
+
renameSync(stagedPackage, packageRoot);
|
|
727
|
+
if (backupCreated) {
|
|
728
|
+
rmSync(backupPackage, { recursive: true, force: true });
|
|
729
|
+
}
|
|
730
|
+
} catch (err) {
|
|
731
|
+
if (backupCreated && !existsSync(packageRoot) && existsSync(backupPackage)) {
|
|
732
|
+
renameSync(backupPackage, packageRoot);
|
|
733
|
+
}
|
|
734
|
+
throw err;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
function installOpenCodePluginPackage() {
|
|
739
|
+
const packageRoot = OPENCODE_LOCAL_PACKAGE_DIR;
|
|
740
|
+
if (sameRealPath(PACKAGE_ROOT, packageRoot)) {
|
|
741
|
+
verifyOpenCodePluginPackage(packageRoot);
|
|
742
|
+
return packageRoot;
|
|
743
|
+
}
|
|
744
|
+
return withOpenCodePackageInstallLock(() => {
|
|
745
|
+
const stagedPackage = uniqueOpenCodePackagePath(".claude-smart-copy");
|
|
746
|
+
rmSync(stagedPackage, { recursive: true, force: true });
|
|
747
|
+
try {
|
|
748
|
+
cpSync(PACKAGE_ROOT, stagedPackage, {
|
|
749
|
+
recursive: true,
|
|
750
|
+
force: true,
|
|
751
|
+
verbatimSymlinks: false,
|
|
752
|
+
filter: shouldCopyPath,
|
|
753
|
+
});
|
|
754
|
+
verifyOpenCodePluginPackage(stagedPackage);
|
|
755
|
+
replaceOpenCodePluginPackage(stagedPackage, packageRoot);
|
|
756
|
+
verifyOpenCodePluginPackage(packageRoot);
|
|
757
|
+
return packageRoot;
|
|
758
|
+
} finally {
|
|
759
|
+
rmSync(stagedPackage, { recursive: true, force: true });
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
|
|
432
764
|
async function bootstrapClaudeCodeInstall() {
|
|
433
765
|
const pluginRoot = findClaudeCodePluginRoot();
|
|
434
766
|
if (!pluginRoot) {
|
|
@@ -523,6 +855,18 @@ function runChecked(command, args, options = {}) {
|
|
|
523
855
|
});
|
|
524
856
|
}
|
|
525
857
|
|
|
858
|
+
function runSilentStatus(command, args, options = {}) {
|
|
859
|
+
const result = spawnSync(command, args, {
|
|
860
|
+
cwd: options.cwd,
|
|
861
|
+
env: options.env || process.env,
|
|
862
|
+
shell: isWindows() && /\.(?:cmd|bat)$/i.test(command),
|
|
863
|
+
stdio: "ignore",
|
|
864
|
+
windowsHide: true,
|
|
865
|
+
});
|
|
866
|
+
if (result.error || result.signal) return 1;
|
|
867
|
+
return typeof result.status === "number" ? result.status : 1;
|
|
868
|
+
}
|
|
869
|
+
|
|
526
870
|
function runPluginService(pluginRoot, scriptName, subcommand, envOverrides = {}) {
|
|
527
871
|
const script = join(pluginRoot, "scripts", scriptName);
|
|
528
872
|
if (!existsSync(script)) return false;
|
|
@@ -921,11 +1265,66 @@ async function installVendoredReflexio(pluginRoot, uv, env) {
|
|
|
921
1265
|
if (code !== 0) throw new Error(`vendored Reflexio install failed in ${pluginRoot}`);
|
|
922
1266
|
}
|
|
923
1267
|
|
|
1268
|
+
async function syncPluginPythonEnv(pluginRoot, uv, env) {
|
|
1269
|
+
let code = await runChecked(
|
|
1270
|
+
uv,
|
|
1271
|
+
["sync", "--locked", "--python", "3.12", "--quiet"],
|
|
1272
|
+
{ cwd: pluginRoot, env },
|
|
1273
|
+
);
|
|
1274
|
+
if (code === 0) return;
|
|
1275
|
+
|
|
1276
|
+
const lockIsFresh = runSilentStatus(
|
|
1277
|
+
uv,
|
|
1278
|
+
["lock", "--check", "--python", "3.12"],
|
|
1279
|
+
{ cwd: pluginRoot, env },
|
|
1280
|
+
) === 0;
|
|
1281
|
+
if (lockIsFresh) {
|
|
1282
|
+
process.stderr.write(
|
|
1283
|
+
`warning: quiet uv sync failed in ${pluginRoot}; retrying with full output.\n`,
|
|
1284
|
+
);
|
|
1285
|
+
code = await runChecked(
|
|
1286
|
+
uv,
|
|
1287
|
+
["sync", "--locked", "--python", "3.12"],
|
|
1288
|
+
{ cwd: pluginRoot, env },
|
|
1289
|
+
);
|
|
1290
|
+
if (code !== 0) throw new Error(`uv sync failed in ${pluginRoot}`);
|
|
1291
|
+
return;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
process.stderr.write(
|
|
1295
|
+
"warning: plugin/uv.lock is out of sync; refreshing local lockfile and retrying uv sync.\n",
|
|
1296
|
+
);
|
|
1297
|
+
code = await runChecked(
|
|
1298
|
+
uv,
|
|
1299
|
+
["lock", "--python", "3.12"],
|
|
1300
|
+
{ cwd: pluginRoot, env },
|
|
1301
|
+
);
|
|
1302
|
+
if (code !== 0) throw new Error(`uv lock failed in ${pluginRoot}`);
|
|
1303
|
+
code = await runChecked(
|
|
1304
|
+
uv,
|
|
1305
|
+
["sync", "--python", "3.12", "--quiet"],
|
|
1306
|
+
{ cwd: pluginRoot, env },
|
|
1307
|
+
);
|
|
1308
|
+
if (code !== 0) {
|
|
1309
|
+
process.stderr.write(
|
|
1310
|
+
`warning: quiet uv sync failed in ${pluginRoot} after refreshing plugin/uv.lock; retrying with full output.\n`,
|
|
1311
|
+
);
|
|
1312
|
+
code = await runChecked(
|
|
1313
|
+
uv,
|
|
1314
|
+
["sync", "--python", "3.12"],
|
|
1315
|
+
{ cwd: pluginRoot, env },
|
|
1316
|
+
);
|
|
1317
|
+
}
|
|
1318
|
+
if (code !== 0) throw new Error(`uv sync failed in ${pluginRoot}`);
|
|
1319
|
+
}
|
|
1320
|
+
|
|
924
1321
|
async function bootstrapPluginRuntime(pluginRoot, options = {}) {
|
|
925
1322
|
assertSupportedRuntimePlatform();
|
|
926
1323
|
process.stdout.write("Preparing claude-smart runtime for hooks...\n");
|
|
927
1324
|
const nodeRuntime = await ensurePrivateNode();
|
|
928
|
-
|
|
1325
|
+
if (options.patchCodexHooks !== false) {
|
|
1326
|
+
patchCodexHooksForNode(pluginRoot, nodeRuntime.node);
|
|
1327
|
+
}
|
|
929
1328
|
if (options.readOnly) prunePublishHooksForReadOnly(pluginRoot);
|
|
930
1329
|
ensurePluginRoot(pluginRoot);
|
|
931
1330
|
const uv = await ensureUv();
|
|
@@ -940,27 +1339,12 @@ async function bootstrapPluginRuntime(pluginRoot, options = {}) {
|
|
|
940
1339
|
);
|
|
941
1340
|
if (lockCode !== 0) throw new Error(`uv lock failed in ${pluginRoot}`);
|
|
942
1341
|
}
|
|
943
|
-
|
|
944
|
-
uv,
|
|
945
|
-
["sync", "--locked", "--python", "3.12", "--quiet"],
|
|
946
|
-
{ cwd: pluginRoot, env },
|
|
947
|
-
);
|
|
948
|
-
if (code !== 0) {
|
|
949
|
-
process.stderr.write(
|
|
950
|
-
`warning: quiet uv sync failed in ${pluginRoot}; retrying with full output.\n`,
|
|
951
|
-
);
|
|
952
|
-
code = await runChecked(
|
|
953
|
-
uv,
|
|
954
|
-
["sync", "--locked", "--python", "3.12"],
|
|
955
|
-
{ cwd: pluginRoot, env },
|
|
956
|
-
);
|
|
957
|
-
}
|
|
958
|
-
if (code !== 0) throw new Error(`uv sync failed in ${pluginRoot}`);
|
|
1342
|
+
await syncPluginPythonEnv(pluginRoot, uv, env);
|
|
959
1343
|
await installVendoredReflexio(pluginRoot, uv, env);
|
|
960
1344
|
|
|
961
1345
|
const dashboardDir = join(pluginRoot, "dashboard");
|
|
962
1346
|
if (existsSync(dashboardDir)) {
|
|
963
|
-
code = await runChecked(nodeRuntime.npm, ["ci"], { cwd: dashboardDir, env });
|
|
1347
|
+
let code = await runChecked(nodeRuntime.npm, ["ci"], { cwd: dashboardDir, env });
|
|
964
1348
|
if (code !== 0) throw new Error(`npm ci failed in ${dashboardDir}`);
|
|
965
1349
|
code = await runChecked(nodeRuntime.npm, ["run", "build"], { cwd: dashboardDir, env });
|
|
966
1350
|
if (code !== 0) throw new Error(`npm run build failed in ${dashboardDir}`);
|
|
@@ -970,13 +1354,15 @@ async function bootstrapPluginRuntime(pluginRoot, options = {}) {
|
|
|
970
1354
|
function printHelp() {
|
|
971
1355
|
process.stdout.write(
|
|
972
1356
|
[
|
|
973
|
-
"claude-smart — install helper for Claude Code and
|
|
1357
|
+
"claude-smart — install helper for Claude Code, Codex, and OpenCode",
|
|
974
1358
|
"",
|
|
975
1359
|
"Usage:",
|
|
976
1360
|
" npx claude-smart install Install the plugin into Claude Code",
|
|
977
1361
|
" npx claude-smart install --host codex Register the plugin marketplace for Codex",
|
|
1362
|
+
" npx claude-smart install --host opencode Add claude-smart to OpenCode config",
|
|
978
1363
|
" npx claude-smart setup Configure managed/read-only/global setup",
|
|
979
1364
|
" npx claude-smart uninstall --host codex Remove the Codex marketplace registration",
|
|
1365
|
+
" npx claude-smart uninstall --host opencode Remove claude-smart from OpenCode config",
|
|
980
1366
|
" npx claude-smart --help Show this help",
|
|
981
1367
|
"",
|
|
982
1368
|
"Claude Code install:",
|
|
@@ -993,9 +1379,16 @@ function printHelp() {
|
|
|
993
1379
|
" 6. Trusts and enables claude-smart hook entries in ~/.codex/config.toml",
|
|
994
1380
|
" 7. Restart Codex.",
|
|
995
1381
|
"",
|
|
1382
|
+
"OpenCode install:",
|
|
1383
|
+
` 1. Copies this package to ${OPENCODE_LOCAL_PACKAGE_DIR}`,
|
|
1384
|
+
" 2. Adds that local file:// package to OpenCode's plugin list in opencode.json",
|
|
1385
|
+
" 3. Prepares local services now from the copied plugin runtime",
|
|
1386
|
+
" 4. Restart OpenCode.",
|
|
1387
|
+
"",
|
|
996
1388
|
"Update:",
|
|
997
1389
|
" npx claude-smart update Reinstall Claude Code support from this package",
|
|
998
1390
|
" npx claude-smart update --host codex Reinstall Codex support from this package",
|
|
1391
|
+
" npx claude-smart update --host opencode Reinstall OpenCode support from this package",
|
|
999
1392
|
" npx claude-smart setup Configure managed/read-only/global setup",
|
|
1000
1393
|
"",
|
|
1001
1394
|
"Uninstall:",
|
|
@@ -1010,11 +1403,11 @@ function parseHost(args) {
|
|
|
1010
1403
|
if (idx === -1) return "claude-code";
|
|
1011
1404
|
const value = args[idx + 1];
|
|
1012
1405
|
if (!value) {
|
|
1013
|
-
process.stderr.write("error: --host requires a value: claude-code or
|
|
1406
|
+
process.stderr.write("error: --host requires a value: claude-code, codex, or opencode\n");
|
|
1014
1407
|
process.exit(1);
|
|
1015
1408
|
}
|
|
1016
|
-
if (value !== "claude-code" && value !== "codex") {
|
|
1017
|
-
process.stderr.write("error: --host must be claude-code or
|
|
1409
|
+
if (value !== "claude-code" && value !== "codex" && value !== "opencode") {
|
|
1410
|
+
process.stderr.write("error: --host must be claude-code, codex, or opencode\n");
|
|
1018
1411
|
process.exit(1);
|
|
1019
1412
|
}
|
|
1020
1413
|
return value;
|
|
@@ -1433,6 +1826,10 @@ async function runUpdate(args) {
|
|
|
1433
1826
|
await runUpdateCodex(args);
|
|
1434
1827
|
return;
|
|
1435
1828
|
}
|
|
1829
|
+
if (parseHost(args) === "opencode") {
|
|
1830
|
+
await runUpdateOpenCode(args);
|
|
1831
|
+
return;
|
|
1832
|
+
}
|
|
1436
1833
|
|
|
1437
1834
|
const pluginRoot = findClaudeCodePluginRoot();
|
|
1438
1835
|
if (pluginRoot) {
|
|
@@ -1449,11 +1846,22 @@ async function runUpdateCodex(args) {
|
|
|
1449
1846
|
await runInstallCodex(args);
|
|
1450
1847
|
}
|
|
1451
1848
|
|
|
1849
|
+
async function runUpdateOpenCode(args) {
|
|
1850
|
+
const pluginRoot = join(PACKAGE_ROOT, "plugin");
|
|
1851
|
+
stopClaudeSmartServices(pluginRoot);
|
|
1852
|
+
process.stdout.write("Updating claude-smart OpenCode support by reinstalling from this package...\n");
|
|
1853
|
+
await runInstallOpenCode(args);
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1452
1856
|
async function runUninstall(args) {
|
|
1453
1857
|
if (parseHost(args) === "codex") {
|
|
1454
1858
|
await runUninstallCodex();
|
|
1455
1859
|
return;
|
|
1456
1860
|
}
|
|
1861
|
+
if (parseHost(args) === "opencode") {
|
|
1862
|
+
await runUninstallOpenCode(args);
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1457
1865
|
|
|
1458
1866
|
if (!hasClaudeCli()) {
|
|
1459
1867
|
process.stderr.write(
|
|
@@ -1504,6 +1912,10 @@ async function runInstall(args, options = {}) {
|
|
|
1504
1912
|
await runInstallCodex(args);
|
|
1505
1913
|
return;
|
|
1506
1914
|
}
|
|
1915
|
+
if (parseHost(args) === "opencode") {
|
|
1916
|
+
await runInstallOpenCode(args);
|
|
1917
|
+
return;
|
|
1918
|
+
}
|
|
1507
1919
|
|
|
1508
1920
|
if (!hasClaudeCli()) {
|
|
1509
1921
|
process.stderr.write(
|
|
@@ -1686,6 +2098,68 @@ async function runInstallCodex(args) {
|
|
|
1686
2098
|
);
|
|
1687
2099
|
}
|
|
1688
2100
|
|
|
2101
|
+
async function runInstallOpenCode(args) {
|
|
2102
|
+
const setup = configureReflexioSetup();
|
|
2103
|
+
const readOnly = setup.readOnly;
|
|
2104
|
+
if (!hasExtractionProvider()) {
|
|
2105
|
+
process.stderr.write(extractionProviderError());
|
|
2106
|
+
process.exit(1);
|
|
2107
|
+
}
|
|
2108
|
+
|
|
2109
|
+
let packageRoot;
|
|
2110
|
+
try {
|
|
2111
|
+
packageRoot = installOpenCodePluginPackage();
|
|
2112
|
+
} catch (err) {
|
|
2113
|
+
process.stderr.write(
|
|
2114
|
+
`error: could not prepare claude-smart OpenCode package: ${err && err.message ? err.message : err}\n`,
|
|
2115
|
+
);
|
|
2116
|
+
process.exit(1);
|
|
2117
|
+
}
|
|
2118
|
+
const pluginRoot = join(packageRoot, "plugin");
|
|
2119
|
+
const pluginSpec = opencodeLocalPluginSpec(packageRoot);
|
|
2120
|
+
let result;
|
|
2121
|
+
try {
|
|
2122
|
+
await bootstrapPluginRuntime(pluginRoot, { readOnly, patchCodexHooks: false });
|
|
2123
|
+
} catch (err) {
|
|
2124
|
+
process.stderr.write(
|
|
2125
|
+
`error: claude-smart OpenCode setup failed during dependency bootstrap: ${err && err.message ? err.message : err}\n`,
|
|
2126
|
+
);
|
|
2127
|
+
process.exit(1);
|
|
2128
|
+
}
|
|
2129
|
+
try {
|
|
2130
|
+
result = patchOpenCodePluginConfig(opencodeConfigPath(args), {
|
|
2131
|
+
install: true,
|
|
2132
|
+
pluginSpec,
|
|
2133
|
+
});
|
|
2134
|
+
} catch (err) {
|
|
2135
|
+
process.stderr.write(`error: could not update OpenCode config: ${err && err.message ? err.message : err}\n`);
|
|
2136
|
+
stopClaudeSmartServices(pluginRoot);
|
|
2137
|
+
process.exit(1);
|
|
2138
|
+
}
|
|
2139
|
+
if (readOnly) {
|
|
2140
|
+
process.stdout.write("Installed read-only hook manifest; publish interactions hooks are disabled.\n");
|
|
2141
|
+
}
|
|
2142
|
+
if (startBackendService(pluginRoot, "opencode")) {
|
|
2143
|
+
process.stdout.write("Started claude-smart backend service.\n");
|
|
2144
|
+
}
|
|
2145
|
+
if (refreshDashboardService(pluginRoot)) {
|
|
2146
|
+
process.stdout.write("Refreshed claude-smart dashboard service.\n");
|
|
2147
|
+
}
|
|
2148
|
+
if (result.backupPath) {
|
|
2149
|
+
process.stdout.write(`Saved a comment-preserving backup of your previous config at ${result.backupPath}.\n`);
|
|
2150
|
+
}
|
|
2151
|
+
process.stdout.write(
|
|
2152
|
+
[
|
|
2153
|
+
"",
|
|
2154
|
+
`${result.changed ? "Updated" : "OpenCode config already includes"} "${pluginSpec}" in ${result.configPath}.`,
|
|
2155
|
+
`Prepared claude-smart OpenCode package at ${packageRoot}.`,
|
|
2156
|
+
"claude-smart OpenCode support is installed.",
|
|
2157
|
+
"Restart OpenCode in your project so it loads the plugin.",
|
|
2158
|
+
"",
|
|
2159
|
+
].join("\n"),
|
|
2160
|
+
);
|
|
2161
|
+
}
|
|
2162
|
+
|
|
1689
2163
|
async function runUninstallCodex() {
|
|
1690
2164
|
stopClaudeSmartServices(join(PACKAGE_ROOT, "plugin"));
|
|
1691
2165
|
if (!hasCli("codex")) {
|
|
@@ -1713,6 +2187,38 @@ async function runUninstallCodex() {
|
|
|
1713
2187
|
);
|
|
1714
2188
|
}
|
|
1715
2189
|
|
|
2190
|
+
async function runUninstallOpenCode(args) {
|
|
2191
|
+
stopClaudeSmartServices(join(PACKAGE_ROOT, "plugin"));
|
|
2192
|
+
stopClaudeSmartServices(join(OPENCODE_LOCAL_PACKAGE_DIR, "plugin"));
|
|
2193
|
+
let result;
|
|
2194
|
+
try {
|
|
2195
|
+
result = patchOpenCodePluginConfig(opencodeConfigPath(args), { install: false });
|
|
2196
|
+
} catch (err) {
|
|
2197
|
+
process.stderr.write(`error: could not update OpenCode config: ${err && err.message ? err.message : err}\n`);
|
|
2198
|
+
process.exit(1);
|
|
2199
|
+
}
|
|
2200
|
+
if (result.backupPath) {
|
|
2201
|
+
process.stdout.write(`Saved a comment-preserving backup of your previous config at ${result.backupPath}.\n`);
|
|
2202
|
+
}
|
|
2203
|
+
rmSync(OPENCODE_LOCAL_PACKAGE_DIR, { recursive: true, force: true });
|
|
2204
|
+
try {
|
|
2205
|
+
rmdirSync(dirname(OPENCODE_LOCAL_PACKAGE_DIR));
|
|
2206
|
+
} catch {
|
|
2207
|
+
// Keep the parent when it still contains future OpenCode state.
|
|
2208
|
+
}
|
|
2209
|
+
process.stdout.write(
|
|
2210
|
+
[
|
|
2211
|
+
"",
|
|
2212
|
+
result.changed
|
|
2213
|
+
? `Removed claude-smart OpenCode plugin entries from ${result.configPath}.`
|
|
2214
|
+
: "OpenCode config did not include claude-smart.",
|
|
2215
|
+
"Restart OpenCode to apply.",
|
|
2216
|
+
...LOCAL_DATA_NOTICE,
|
|
2217
|
+
"",
|
|
2218
|
+
].join("\n"),
|
|
2219
|
+
);
|
|
2220
|
+
}
|
|
2221
|
+
|
|
1716
2222
|
async function main() {
|
|
1717
2223
|
const args = process.argv.slice(2);
|
|
1718
2224
|
const cmd = args[0] || "install";
|
|
@@ -1764,7 +2270,13 @@ module.exports = {
|
|
|
1764
2270
|
ensureUv,
|
|
1765
2271
|
configureReflexioSetup,
|
|
1766
2272
|
patchCodexHooksForNode,
|
|
2273
|
+
opencodeConfigPath,
|
|
2274
|
+
opencodeLocalPluginSpec,
|
|
2275
|
+
installOpenCodePluginPackage,
|
|
2276
|
+
patchOpenCodePluginConfig,
|
|
2277
|
+
hasExtractionProvider,
|
|
1767
2278
|
platformSupportError,
|
|
1768
2279
|
prunePublishHooksForReadOnly,
|
|
1769
2280
|
restorePublishHooksFromSource,
|
|
2281
|
+
stripJsonc,
|
|
1770
2282
|
};
|