xrefkit 0.6.0__tar.gz → 0.6.1__tar.gz
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.
- {xrefkit-0.6.0 → xrefkit-0.6.1}/PKG-INFO +15 -1
- {xrefkit-0.6.0 → xrefkit-0.6.1}/README.md +14 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/pyproject.toml +1 -1
- xrefkit-0.6.1/tests/test_legacy_migration.py +231 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/__init__.py +1 -1
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/__init__.py +4 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/catalog.py +4 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/contracts.py +22 -0
- xrefkit-0.6.1/xrefkit/mcp/legacy_migration.py +383 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/schemas.py +2 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/server.py +28 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/setup.py +27 -34
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit.egg-info/PKG-INFO +15 -1
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit.egg-info/SOURCES.txt +2 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/LICENSE +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/setup.cfg +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_artifact_selected_family.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_attention_pet.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_attention_pet_client_protocol.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_attention_pet_codex_session.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_attention_pet_fit.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_boundary_analysis.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_brownfield_csharp_structure_definitions.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_brownfield_file_editing_protocol.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_business_intake_conversation_definitions.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_business_intake_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_calibration_lint.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_catalog_preparation_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_check_skill_knowledge_xids.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_code_constraint_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_collect_analyzer_sarif.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_constraint_derivation_family_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_constraint_derivation_selected_family.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_contribution_returns.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_convert_to_xrefkit_skill.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_cs_scope_probe.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_csharp_commonality.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_csharp_naming_profile.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_ctx.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_cutover_readiness.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_dashboard.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_database_batch_definition_migration.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_decision_trace.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_design_business_intake_selected_family.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_design_planning_definition_migration.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_dotnet_definition_candidate.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_editorial_family_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_editorial_intake_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_editorial_selected_family.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_embedded_startup_pack.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_error_policy_audit.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_error_policy_locator.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_execution_binding.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_existing_skill_definition_batch.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_final_skilldefinition_batch.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_flow_selected_family.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_fm_multiroot.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_gate.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_gateway.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_gateway_mcp.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_gateway_skill_adapter.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_gateway_work_items.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_goal_desired_state.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_host_precheck.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_human_evaluation.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_implementation_flow_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_implementation_review_selected_family.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_inbound_uploads.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_instruction_workflow.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_knowledge_relations_validator.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_language_review_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_mcp_package_routing.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_mcp_setup.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_mcp_subagent_startup.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_mcp_subagent_startup_integration.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_os_family_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_os_knowledge_family_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_os_selected_family.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_ownership.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_packmeta.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_project_quality_baseline.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_qa_report_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_resource_provider.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_runtime_contracts.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_sarif_to_locator.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_security_definition_migration.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_definition_governance.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_definition_mcp.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_definition_runtime.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_edits.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_maturity_return.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_runtime_audit.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skillmeta.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skills_sync.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_structure_catalog.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_subagent_startup.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_subagent_startup_boundaries.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_wbs.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_workflow_family_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_xref.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_xrefkit_instance.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_xrefkit_tools.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_xrefkit_v2_discovery.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_xrefkit_v2_models.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_xrefkit_v2_pipeline.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/__main__.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/__init__.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/__main__.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/client.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/client_protocol.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/codex_session.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/evaluator.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/model.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/presentation.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/profiles.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/scenarios.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/server.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/store.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/boundary_analysis.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/catalog_cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/contracts.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/ctx.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/dashboard.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/decision_trace.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/discovery.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/execution_binding.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/execution_binding_cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/gate.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/gateway.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/goalstate.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/hashing.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/host_precheck.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/import_skill.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/instance.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/loaders.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/audit.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/bootstrap.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/client_cache.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/client_flow.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/context_registry.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/context_token.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/contribution_adoption.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/contribution_returns.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/dist.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/gateway.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/inbound_uploads.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/knowledge_edits.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/ownership.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/repository.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/skill_edits.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/skill_maturity.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/startup_contract_pack.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/subagent_startup.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp_tools.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/__init__.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/common.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/effective_bundle.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/human_evaluation.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/local_manifest.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/package_manifest.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/run_log.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/server_config.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/skill_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/operations_cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/ownership.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/packmeta.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/registry.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resolver.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resource_provider.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/attention_pet/client-state.schema.json +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/attention_pet/pet.css +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/attention_pet/pet.html +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/attention_pet/pet.js +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/contracts.json +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/current.json +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/generations/7a682a5272907354/contracts.json +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/generations/7a682a5272907354/model_body.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/generations/9929294385ccb7b0/contracts.json +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/generations/9929294385ccb7b0/model_body.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/model_body.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/startup_sources/000_agent_entry.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/startup_sources/011_startup_xref_routing.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/startup_sources/015_shared_memory_operations.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/startup_sources/016_uncertainty_protocol.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/startup_sources/017_base_and_xref_layering.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/startup_sources/053_context_direction_security_guard.md +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/runlog.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/skill_definition.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/skill_definition_catalog.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/skill_definition_governance.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/skillmeta.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/skillrun.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/skills_sync.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/structure_catalog.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/subagent_startup.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/tools/__init__.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/tools/__main__.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/v2_cli.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/wbs.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/workspace.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/xref.py +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit.egg-info/dependency_links.txt +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit.egg-info/entry_points.txt +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit.egg-info/requires.txt +0 -0
- {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xrefkit
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Summary: Portable XID, Skill, Knowledge, workflow, and MCP runtime for XRefKit
|
|
5
5
|
Author: synthaicode
|
|
6
6
|
License: MIT License
|
|
@@ -156,6 +156,20 @@ This command starts the optional catalog and runtime MCP adapter. This checkout
|
|
|
156
156
|
does not implement management upload, staging, sealing, review, or adoption of
|
|
157
157
|
uploaded SkillDefinition bytes into the active catalog.
|
|
158
158
|
|
|
159
|
+
To connect VS Code/Copilot, run from your target workspace:
|
|
160
|
+
|
|
161
|
+
```powershell
|
|
162
|
+
python -m pip install "xrefkit[mcp]"
|
|
163
|
+
python -m xrefkit mcp setup --repo . --output .xrefkit/setup-review
|
|
164
|
+
python -m xrefkit mcp setup apply --repo . --source .xrefkit/setup-review
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Review the generated files before applying them, open the workspace in VS Code,
|
|
168
|
+
and start the `xrefkit` MCP server. In Copilot chat, ask: "Call XRefKit's
|
|
169
|
+
get_startup_context and help me get started." The AI receives any needed legacy
|
|
170
|
+
migration guidance; you can describe your goal without specifying Skill names.
|
|
171
|
+
Opening VS Code alone does not guarantee an AI conversation starts.
|
|
172
|
+
|
|
159
173
|
## Where to go next
|
|
160
174
|
|
|
161
175
|
- [Install XRefKit and register Skill Packages](docs/guides/089_xrefkit_package_first_registration.md#xid-4F8C2A7D1E90)
|
|
@@ -117,6 +117,20 @@ This command starts the optional catalog and runtime MCP adapter. This checkout
|
|
|
117
117
|
does not implement management upload, staging, sealing, review, or adoption of
|
|
118
118
|
uploaded SkillDefinition bytes into the active catalog.
|
|
119
119
|
|
|
120
|
+
To connect VS Code/Copilot, run from your target workspace:
|
|
121
|
+
|
|
122
|
+
```powershell
|
|
123
|
+
python -m pip install "xrefkit[mcp]"
|
|
124
|
+
python -m xrefkit mcp setup --repo . --output .xrefkit/setup-review
|
|
125
|
+
python -m xrefkit mcp setup apply --repo . --source .xrefkit/setup-review
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Review the generated files before applying them, open the workspace in VS Code,
|
|
129
|
+
and start the `xrefkit` MCP server. In Copilot chat, ask: "Call XRefKit's
|
|
130
|
+
get_startup_context and help me get started." The AI receives any needed legacy
|
|
131
|
+
migration guidance; you can describe your goal without specifying Skill names.
|
|
132
|
+
Opening VS Code alone does not guarantee an AI conversation starts.
|
|
133
|
+
|
|
120
134
|
## Where to go next
|
|
121
135
|
|
|
122
136
|
- [Install XRefKit and register Skill Packages](docs/guides/089_xrefkit_package_first_registration.md#xid-4F8C2A7D1E90)
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import json
|
|
5
|
+
import sys
|
|
6
|
+
import subprocess
|
|
7
|
+
import os
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
|
|
12
|
+
from xrefkit.mcp.catalog import XRefCatalog
|
|
13
|
+
from xrefkit.mcp.legacy_migration import (
|
|
14
|
+
STATE, dismiss_legacy_migration, import_legacy_assets, migration_context,
|
|
15
|
+
plan_legacy_migration, record_mcp_retrieval,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def legacy(tmp_path: Path) -> tuple[Path, Path]:
|
|
20
|
+
source, root = tmp_path / "legacy", tmp_path / "target"
|
|
21
|
+
root.mkdir()
|
|
22
|
+
(source / "skills" / "nested" / "review").mkdir(parents=True)
|
|
23
|
+
(source / "knowledge").mkdir()
|
|
24
|
+
(source / "skills" / "nested" / "review" / "SKILL.md").write_text(
|
|
25
|
+
"# Review\n\nUse [rules](../../../knowledge/rules.md).\n", encoding="utf-8")
|
|
26
|
+
(source / "knowledge" / "rules.md").write_text("# Rules\n\nKeep evidence.\n", encoding="utf-8")
|
|
27
|
+
(source / "knowledge" / "unlinked.txt").write_text("Independent knowledge.\n", encoding="utf-8")
|
|
28
|
+
return source, root
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def snapshot(root: Path) -> dict[str, bytes]:
|
|
32
|
+
return {p.relative_to(root).as_posix(): p.read_bytes() for p in root.rglob("*") if p.is_file()}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def documents(root: Path) -> list[dict]:
|
|
36
|
+
data = json.loads((root / STATE).read_text(encoding="utf-8"))
|
|
37
|
+
catalog = XRefCatalog.build(root)
|
|
38
|
+
return [catalog.get_document_by_xid(a["xid"]) for unit in data["units"].values()
|
|
39
|
+
for a in unit.get("artifacts", []) if unit["status"] == "installed"]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_first_partial_complete_restart_and_upgrade(tmp_path, monkeypatch):
|
|
43
|
+
source, root = legacy(tmp_path)
|
|
44
|
+
original = snapshot(source)
|
|
45
|
+
catalog = XRefCatalog.build(root)
|
|
46
|
+
first = catalog.get_startup_context()["legacy_migration"]
|
|
47
|
+
assert first["status"] == "not_started"
|
|
48
|
+
assert first["client_instructions"]
|
|
49
|
+
assert not (root / STATE).exists()
|
|
50
|
+
plan = plan_legacy_migration(root, str(source))
|
|
51
|
+
assert "knowledge/unlinked.txt" in plan["targets"]
|
|
52
|
+
assert "skills/nested/review" in plan["targets"]
|
|
53
|
+
assert not (root / STATE).exists() # inventory has no write side effect
|
|
54
|
+
result = import_legacy_assets(root, str(source), plan["targets"])
|
|
55
|
+
assert result["ok"]
|
|
56
|
+
assert migration_context(root)["status"] == "in_progress"
|
|
57
|
+
bodies = documents(root)
|
|
58
|
+
# Catalog/CLI verification does not masquerade as an MCP retrieval.
|
|
59
|
+
assert migration_context(root)["status"] == "in_progress"
|
|
60
|
+
record_mcp_retrieval(root, bodies[:1])
|
|
61
|
+
remaining = migration_context(root)
|
|
62
|
+
assert remaining["status"] == "in_progress"
|
|
63
|
+
assert sum(len(u["retrievals"]) for u in remaining["remaining"]) < len(bodies)
|
|
64
|
+
record_mcp_retrieval(root, bodies)
|
|
65
|
+
completed = migration_context(root)
|
|
66
|
+
assert completed["status"] == "completed"
|
|
67
|
+
assert completed["client_instructions"] == []
|
|
68
|
+
assert completed["remaining"] == []
|
|
69
|
+
state = (root / STATE).read_bytes()
|
|
70
|
+
import xrefkit.mcp
|
|
71
|
+
monkeypatch.setattr(xrefkit.mcp, "__version__", "999.0.0")
|
|
72
|
+
restarted = XRefCatalog.build(root).get_startup_context({"irrelevant": "cached"})
|
|
73
|
+
assert restarted["legacy_migration"]["status"] == "completed"
|
|
74
|
+
assert (root / STATE).read_bytes() == state
|
|
75
|
+
assert snapshot(source) == original
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_explicit_scope_and_dismissal(tmp_path):
|
|
79
|
+
source, root = legacy(tmp_path)
|
|
80
|
+
assert dismiss_legacy_migration(root)["status"] == "not_required"
|
|
81
|
+
assert XRefCatalog.build(root).get_startup_context()["legacy_migration"]["client_instructions"] == []
|
|
82
|
+
result = import_legacy_assets(root, str(source), ["knowledge/unlinked.txt"])
|
|
83
|
+
assert result["ok"]
|
|
84
|
+
assert not (root / "skills").exists()
|
|
85
|
+
with pytest.raises(ValueError, match="cannot dismiss"):
|
|
86
|
+
dismiss_legacy_migration(root)
|
|
87
|
+
record_mcp_retrieval(root, documents(root))
|
|
88
|
+
assert migration_context(root)["status"] == "completed"
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_conflict_failure_retry_and_existing_assets_protected(tmp_path):
|
|
92
|
+
source, root = legacy(tmp_path)
|
|
93
|
+
protected = root / "skills" / "imported.nested_review" / "SKILL.md"
|
|
94
|
+
protected.parent.mkdir(parents=True)
|
|
95
|
+
protected.write_bytes(b"Existing customized skill\n")
|
|
96
|
+
result = import_legacy_assets(root, str(source), ["skills/nested/review", "knowledge/unlinked.txt"], prefix="imported")
|
|
97
|
+
assert not result["ok"]
|
|
98
|
+
remaining = migration_context(root)["remaining"]
|
|
99
|
+
assert remaining[0]["status"] == "failed"
|
|
100
|
+
assert "refusing to overwrite" in remaining[0]["error"]
|
|
101
|
+
assert protected.read_bytes() == b"Existing customized skill\n"
|
|
102
|
+
record_mcp_retrieval(root, documents(root))
|
|
103
|
+
assert [u["target"] for u in migration_context(root)["remaining"]] == ["skills/nested/review"]
|
|
104
|
+
# Simulate a user moving their customized file aside after reviewing conflict.
|
|
105
|
+
protected.rename(protected.with_suffix(".backup"))
|
|
106
|
+
assert import_legacy_assets(root, str(source), ["skills/nested/review"], prefix="imported")["ok"]
|
|
107
|
+
record_mcp_retrieval(root, documents(root))
|
|
108
|
+
assert migration_context(root)["status"] == "completed"
|
|
109
|
+
assert protected.with_suffix(".backup").read_bytes() == b"Existing customized skill\n"
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def test_partial_publish_retry_is_stable(tmp_path, monkeypatch):
|
|
113
|
+
source, root = legacy(tmp_path)
|
|
114
|
+
real_link = os.link
|
|
115
|
+
failed = False
|
|
116
|
+
def fail_once(source_path, destination, *args, **kwargs):
|
|
117
|
+
nonlocal failed
|
|
118
|
+
if Path(destination).name == "meta.md" and not failed:
|
|
119
|
+
failed = True
|
|
120
|
+
raise OSError("fixture disk failure")
|
|
121
|
+
return real_link(source_path, destination, *args, **kwargs)
|
|
122
|
+
monkeypatch.setattr(os, "link", fail_once)
|
|
123
|
+
assert not import_legacy_assets(root, str(source), ["skills/nested/review"])["ok"]
|
|
124
|
+
published = snapshot(root / "skills")
|
|
125
|
+
assert import_legacy_assets(root, str(source), ["skills/nested/review"])["ok"]
|
|
126
|
+
assert all(snapshot(root / "skills")[p] == b for p, b in published.items())
|
|
127
|
+
record_mcp_retrieval(root, documents(root))
|
|
128
|
+
assert migration_context(root)["status"] == "completed"
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def test_receipts_require_matching_body_identity_and_content(tmp_path):
|
|
132
|
+
source, root = legacy(tmp_path)
|
|
133
|
+
import_legacy_assets(root, str(source), ["knowledge/unlinked.txt"])
|
|
134
|
+
body = documents(root)[0]
|
|
135
|
+
for wrong in ({**body, "content": None}, {**body, "content": "wrong"},
|
|
136
|
+
{**body, "path": "other.md"}, {**body, "xid": "wrong"}):
|
|
137
|
+
record_mcp_retrieval(root, [wrong])
|
|
138
|
+
assert migration_context(root)["status"] == "in_progress"
|
|
139
|
+
record_mcp_retrieval(root, [body])
|
|
140
|
+
assert migration_context(root)["status"] == "completed"
|
|
141
|
+
state = json.loads((root / STATE).read_text(encoding="utf-8"))
|
|
142
|
+
path = root / next(iter(state["units"].values()))["artifacts"][0]["path"]
|
|
143
|
+
path.write_text("Customized after migration", encoding="utf-8")
|
|
144
|
+
assert migration_context(root)["status"] == "in_progress"
|
|
145
|
+
assert not import_legacy_assets(root, str(source), ["knowledge/unlinked.txt"])["ok"]
|
|
146
|
+
assert path.read_text(encoding="utf-8") == "Customized after migration"
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def test_corrupt_state_and_overlap_are_not_reset(tmp_path):
|
|
150
|
+
source, root = legacy(tmp_path)
|
|
151
|
+
for bad in ("{", '{"schema_version": 999, "units": {}}'):
|
|
152
|
+
(root / STATE).parent.mkdir(exist_ok=True)
|
|
153
|
+
(root / STATE).write_text(bad, encoding="utf-8")
|
|
154
|
+
assert migration_context(root)["status"] == "blocked"
|
|
155
|
+
with pytest.raises(ValueError):
|
|
156
|
+
import_legacy_assets(root, str(source), ["knowledge/unlinked.txt"])
|
|
157
|
+
assert (root / STATE).read_text(encoding="utf-8") == bad
|
|
158
|
+
for overlap in (root, root.parent):
|
|
159
|
+
with pytest.raises(ValueError, match="non-overlapping"):
|
|
160
|
+
plan_legacy_migration(root, str(overlap))
|
|
161
|
+
with pytest.raises(ValueError, match="exact targets"):
|
|
162
|
+
import_legacy_assets(root, str(source), ["../escape"])
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def test_existing_xid_conflict_preserves_catalog_and_source(tmp_path):
|
|
166
|
+
source, root = legacy(tmp_path)
|
|
167
|
+
xid = "ABCDEF012345"
|
|
168
|
+
(source / "knowledge" / "rules.md").write_text(f"<!-- xid: {xid} -->\n# Legacy rules\n", encoding="utf-8")
|
|
169
|
+
existing = root / "knowledge" / "existing.md"
|
|
170
|
+
existing.parent.mkdir()
|
|
171
|
+
existing.write_text(f"<!-- xid: {xid} -->\n# Customized rules\n", encoding="utf-8")
|
|
172
|
+
before = snapshot(source)
|
|
173
|
+
result = import_legacy_assets(root, str(source), ["knowledge/rules.md"])
|
|
174
|
+
assert not result["ok"]
|
|
175
|
+
assert "XID conflict" in result["migration"]["remaining"][0]["error"]
|
|
176
|
+
assert XRefCatalog.build(root).get_document_by_xid(xid)["title"] == "Customized rules"
|
|
177
|
+
assert snapshot(source) == before
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def test_unsupported_skill_resources_are_reported_without_false_completion(tmp_path):
|
|
181
|
+
source, root = legacy(tmp_path)
|
|
182
|
+
(source / "skills/nested/review/helper.py").write_text("print('legacy')", encoding="utf-8")
|
|
183
|
+
plan = plan_legacy_migration(root, str(source))
|
|
184
|
+
assert "skills/nested/review/helper.py" in plan["unsupported"]
|
|
185
|
+
assert not import_legacy_assets(root, str(source), ["skills/nested/review"])["ok"]
|
|
186
|
+
assert migration_context(root)["status"] == "in_progress"
|
|
187
|
+
assert not (root / "skills").exists()
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def test_live_stdio_retrieval_and_restart(tmp_path):
|
|
191
|
+
pytest.importorskip("mcp")
|
|
192
|
+
from mcp.client.session import ClientSession
|
|
193
|
+
from mcp.client.stdio import StdioServerParameters, stdio_client
|
|
194
|
+
source, root = legacy(tmp_path)
|
|
195
|
+
original = snapshot(source)
|
|
196
|
+
params = StdioServerParameters(command=sys.executable,
|
|
197
|
+
args=["-m", "xrefkit", "mcp", "serve", "--repo", str(root)])
|
|
198
|
+
async def exercise():
|
|
199
|
+
async def call(session, tool, arguments=None):
|
|
200
|
+
result = await session.call_tool(tool, arguments or {})
|
|
201
|
+
assert not result.isError, result
|
|
202
|
+
return result.structuredContent or json.loads(result.content[0].text)
|
|
203
|
+
async with stdio_client(params) as (read, write):
|
|
204
|
+
async with ClientSession(read, write) as session:
|
|
205
|
+
await session.initialize()
|
|
206
|
+
startup = await call(session, "get_startup_context")
|
|
207
|
+
assert startup["legacy_migration"]["status"] == "not_started"
|
|
208
|
+
plan = await call(session, "plan_legacy_migration", {"source": str(source)})
|
|
209
|
+
argv = [sys.executable, *plan["client_import_command"][1:]]
|
|
210
|
+
for target in plan["targets"]:
|
|
211
|
+
argv.extend(["--target", target])
|
|
212
|
+
proc = await asyncio.to_thread(subprocess.run, argv, capture_output=True, text=True, check=False)
|
|
213
|
+
assert proc.returncode == 0, proc.stdout + proc.stderr
|
|
214
|
+
result = json.loads(proc.stdout)
|
|
215
|
+
assert result["ok"]
|
|
216
|
+
skill_id = result["converted_skills"][0]["skill_id"]
|
|
217
|
+
await call(session, "get_skill", {"skill_id": skill_id})
|
|
218
|
+
context = (await call(session, "get_startup_context"))["legacy_migration"]
|
|
219
|
+
assert context["status"] == "in_progress"
|
|
220
|
+
for unit in context["remaining"]:
|
|
221
|
+
for pending in unit["retrievals"]:
|
|
222
|
+
await call(session, "get_document_by_xid", {"xid": pending["xid"]})
|
|
223
|
+
assert (await call(session, "get_startup_context"))["legacy_migration"]["status"] == "completed"
|
|
224
|
+
async with stdio_client(params) as (read, write):
|
|
225
|
+
async with ClientSession(read, write) as session:
|
|
226
|
+
await session.initialize()
|
|
227
|
+
context = (await call(session, "get_startup_context"))["legacy_migration"]
|
|
228
|
+
assert context["status"] == "completed"
|
|
229
|
+
assert not context["client_instructions"]
|
|
230
|
+
asyncio.run(exercise())
|
|
231
|
+
assert snapshot(source) == original
|
|
@@ -17,6 +17,10 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
17
17
|
from .server import main as server_main
|
|
18
18
|
|
|
19
19
|
args = list(argv or [])
|
|
20
|
+
if args and args[0] == "migrate":
|
|
21
|
+
from .legacy_migration import main as migration_main
|
|
22
|
+
|
|
23
|
+
return migration_main(args[1:])
|
|
20
24
|
if args and args[0] == "setup":
|
|
21
25
|
from .setup import main as setup_main
|
|
22
26
|
|
|
@@ -9,6 +9,7 @@ from dataclasses import dataclass
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
|
|
11
11
|
from .contracts import builtin_tool_contracts
|
|
12
|
+
from .legacy_migration import migration_context
|
|
12
13
|
from ..discovery import discover_skill_packages, DiscoveredSkillPackage
|
|
13
14
|
from ..loaders import load_skill_definition as load_package_skill_definition
|
|
14
15
|
from ..skill_definition import (
|
|
@@ -1213,6 +1214,8 @@ class XRefCatalog:
|
|
|
1213
1214
|
pack_document_text = pack_resolved[1] if pack_resolved else None
|
|
1214
1215
|
startup_contract_pack = _startup_contract_pack(references, pack_document_text)
|
|
1215
1216
|
client_instructions = _client_instructions()
|
|
1217
|
+
legacy_migration = migration_context(self.repo_root)
|
|
1218
|
+
client_instructions.extend(legacy_migration["client_instructions"])
|
|
1216
1219
|
if startup_contract_pack["stale"]:
|
|
1217
1220
|
stale_xids = [
|
|
1218
1221
|
str(item["xid"]) for item in startup_contract_pack["stale_sources"]
|
|
@@ -1268,6 +1271,7 @@ class XRefCatalog:
|
|
|
1268
1271
|
session_context_deduplication=_session_context_deduplication(),
|
|
1269
1272
|
core_runtime_distribution=_xrefkit_runtime_distribution(self.repo_root).to_dict(),
|
|
1270
1273
|
repository_zones=_repository_zones(self.ownership),
|
|
1274
|
+
legacy_migration=legacy_migration,
|
|
1271
1275
|
client_instructions=client_instructions,
|
|
1272
1276
|
client_obligations=_client_obligations(),
|
|
1273
1277
|
link_resolution={
|
|
@@ -27,6 +27,28 @@ def builtin_tool_contracts() -> list[ToolContract]:
|
|
|
27
27
|
requires_workspace=True,
|
|
28
28
|
required_when="Client initialization must show base XRefKit control documents and link-resolution instructions before task routing.",
|
|
29
29
|
),
|
|
30
|
+
ToolContract(
|
|
31
|
+
tool_id="xref.plan_legacy_migration",
|
|
32
|
+
provider="xrefkit-mcp",
|
|
33
|
+
version="1",
|
|
34
|
+
execution_location="server",
|
|
35
|
+
side_effects="none",
|
|
36
|
+
input_schema={"source": "string"},
|
|
37
|
+
output_schema={"plan": "legacy_migration_inventory"},
|
|
38
|
+
requires_workspace=True,
|
|
39
|
+
required_when="The user provided a legacy folder for first-use migration; return inventory and a client-side Python import command without writing assets.",
|
|
40
|
+
),
|
|
41
|
+
ToolContract(
|
|
42
|
+
tool_id="xref.dismiss_legacy_migration",
|
|
43
|
+
provider="xrefkit-mcp",
|
|
44
|
+
version="1",
|
|
45
|
+
execution_location="server",
|
|
46
|
+
side_effects="audit_write",
|
|
47
|
+
input_schema={},
|
|
48
|
+
output_schema={"migration": "legacy_migration_state"},
|
|
49
|
+
requires_workspace=True,
|
|
50
|
+
required_when="The user explicitly confirmed that no legacy assets need migration.",
|
|
51
|
+
),
|
|
30
52
|
ToolContract(
|
|
31
53
|
tool_id="xref.bind_skill_run",
|
|
32
54
|
provider="xrefkit-mcp",
|