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.
Files changed (209) hide show
  1. {xrefkit-0.6.0 → xrefkit-0.6.1}/PKG-INFO +15 -1
  2. {xrefkit-0.6.0 → xrefkit-0.6.1}/README.md +14 -0
  3. {xrefkit-0.6.0 → xrefkit-0.6.1}/pyproject.toml +1 -1
  4. xrefkit-0.6.1/tests/test_legacy_migration.py +231 -0
  5. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/__init__.py +1 -1
  6. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/__init__.py +4 -0
  7. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/catalog.py +4 -0
  8. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/contracts.py +22 -0
  9. xrefkit-0.6.1/xrefkit/mcp/legacy_migration.py +383 -0
  10. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/schemas.py +2 -0
  11. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/server.py +28 -0
  12. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/setup.py +27 -34
  13. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit.egg-info/PKG-INFO +15 -1
  14. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit.egg-info/SOURCES.txt +2 -0
  15. {xrefkit-0.6.0 → xrefkit-0.6.1}/LICENSE +0 -0
  16. {xrefkit-0.6.0 → xrefkit-0.6.1}/setup.cfg +0 -0
  17. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_artifact_selected_family.py +0 -0
  18. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_attention_pet.py +0 -0
  19. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_attention_pet_client_protocol.py +0 -0
  20. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_attention_pet_codex_session.py +0 -0
  21. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_attention_pet_fit.py +0 -0
  22. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_boundary_analysis.py +0 -0
  23. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_brownfield_csharp_structure_definitions.py +0 -0
  24. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_brownfield_file_editing_protocol.py +0 -0
  25. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_business_intake_conversation_definitions.py +0 -0
  26. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_business_intake_definition.py +0 -0
  27. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_calibration_lint.py +0 -0
  28. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_catalog_preparation_definition.py +0 -0
  29. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_check_skill_knowledge_xids.py +0 -0
  30. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_cli.py +0 -0
  31. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_code_constraint_definition.py +0 -0
  32. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_collect_analyzer_sarif.py +0 -0
  33. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_constraint_derivation_family_definition.py +0 -0
  34. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_constraint_derivation_selected_family.py +0 -0
  35. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_contribution_returns.py +0 -0
  36. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_convert_to_xrefkit_skill.py +0 -0
  37. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_cs_scope_probe.py +0 -0
  38. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_csharp_commonality.py +0 -0
  39. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_csharp_naming_profile.py +0 -0
  40. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_ctx.py +0 -0
  41. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_cutover_readiness.py +0 -0
  42. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_dashboard.py +0 -0
  43. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_database_batch_definition_migration.py +0 -0
  44. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_decision_trace.py +0 -0
  45. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_design_business_intake_selected_family.py +0 -0
  46. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_design_planning_definition_migration.py +0 -0
  47. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_dotnet_definition_candidate.py +0 -0
  48. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_editorial_family_definition.py +0 -0
  49. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_editorial_intake_definition.py +0 -0
  50. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_editorial_selected_family.py +0 -0
  51. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_embedded_startup_pack.py +0 -0
  52. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_error_policy_audit.py +0 -0
  53. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_error_policy_locator.py +0 -0
  54. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_execution_binding.py +0 -0
  55. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_existing_skill_definition_batch.py +0 -0
  56. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_final_skilldefinition_batch.py +0 -0
  57. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_flow_selected_family.py +0 -0
  58. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_fm_multiroot.py +0 -0
  59. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_gate.py +0 -0
  60. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_gateway.py +0 -0
  61. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_gateway_mcp.py +0 -0
  62. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_gateway_skill_adapter.py +0 -0
  63. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_gateway_work_items.py +0 -0
  64. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_goal_desired_state.py +0 -0
  65. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_host_precheck.py +0 -0
  66. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_human_evaluation.py +0 -0
  67. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_implementation_flow_definition.py +0 -0
  68. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_implementation_review_selected_family.py +0 -0
  69. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_inbound_uploads.py +0 -0
  70. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_instruction_workflow.py +0 -0
  71. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_knowledge_relations_validator.py +0 -0
  72. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_language_review_definition.py +0 -0
  73. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_mcp_package_routing.py +0 -0
  74. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_mcp_setup.py +0 -0
  75. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_mcp_subagent_startup.py +0 -0
  76. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_mcp_subagent_startup_integration.py +0 -0
  77. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_os_family_definition.py +0 -0
  78. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_os_knowledge_family_definition.py +0 -0
  79. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_os_selected_family.py +0 -0
  80. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_ownership.py +0 -0
  81. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_packmeta.py +0 -0
  82. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_project_quality_baseline.py +0 -0
  83. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_qa_report_definition.py +0 -0
  84. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_resource_provider.py +0 -0
  85. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_runtime_contracts.py +0 -0
  86. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_sarif_to_locator.py +0 -0
  87. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_security_definition_migration.py +0 -0
  88. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_definition.py +0 -0
  89. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_definition_governance.py +0 -0
  90. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_definition_mcp.py +0 -0
  91. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_definition_runtime.py +0 -0
  92. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_edits.py +0 -0
  93. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_maturity_return.py +0 -0
  94. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skill_runtime_audit.py +0 -0
  95. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skillmeta.py +0 -0
  96. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_skills_sync.py +0 -0
  97. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_structure_catalog.py +0 -0
  98. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_subagent_startup.py +0 -0
  99. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_subagent_startup_boundaries.py +0 -0
  100. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_wbs.py +0 -0
  101. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_workflow_family_definition.py +0 -0
  102. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_xref.py +0 -0
  103. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_xrefkit_instance.py +0 -0
  104. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_xrefkit_tools.py +0 -0
  105. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_xrefkit_v2_discovery.py +0 -0
  106. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_xrefkit_v2_models.py +0 -0
  107. {xrefkit-0.6.0 → xrefkit-0.6.1}/tests/test_xrefkit_v2_pipeline.py +0 -0
  108. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/__main__.py +0 -0
  109. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/__init__.py +0 -0
  110. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/__main__.py +0 -0
  111. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/client.py +0 -0
  112. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/client_protocol.py +0 -0
  113. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/codex_session.py +0 -0
  114. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/evaluator.py +0 -0
  115. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/model.py +0 -0
  116. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/presentation.py +0 -0
  117. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/profiles.py +0 -0
  118. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/scenarios.py +0 -0
  119. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/server.py +0 -0
  120. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/attention_pet/store.py +0 -0
  121. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/boundary_analysis.py +0 -0
  122. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/catalog_cli.py +0 -0
  123. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/cli.py +0 -0
  124. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/contracts.py +0 -0
  125. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/ctx.py +0 -0
  126. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/dashboard.py +0 -0
  127. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/decision_trace.py +0 -0
  128. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/discovery.py +0 -0
  129. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/execution_binding.py +0 -0
  130. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/execution_binding_cli.py +0 -0
  131. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/gate.py +0 -0
  132. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/gateway.py +0 -0
  133. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/goalstate.py +0 -0
  134. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/hashing.py +0 -0
  135. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/host_precheck.py +0 -0
  136. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/import_skill.py +0 -0
  137. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/instance.py +0 -0
  138. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/loaders.py +0 -0
  139. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/audit.py +0 -0
  140. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/bootstrap.py +0 -0
  141. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/cli.py +0 -0
  142. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/client_cache.py +0 -0
  143. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/client_flow.py +0 -0
  144. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/context_registry.py +0 -0
  145. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/context_token.py +0 -0
  146. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/contribution_adoption.py +0 -0
  147. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/contribution_returns.py +0 -0
  148. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/dist.py +0 -0
  149. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/gateway.py +0 -0
  150. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/inbound_uploads.py +0 -0
  151. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/knowledge_edits.py +0 -0
  152. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/ownership.py +0 -0
  153. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/repository.py +0 -0
  154. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/skill_edits.py +0 -0
  155. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/skill_maturity.py +0 -0
  156. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/startup_contract_pack.py +0 -0
  157. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp/subagent_startup.py +0 -0
  158. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/mcp_tools.py +0 -0
  159. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/__init__.py +0 -0
  160. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/common.py +0 -0
  161. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/effective_bundle.py +0 -0
  162. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/human_evaluation.py +0 -0
  163. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/local_manifest.py +0 -0
  164. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/package_manifest.py +0 -0
  165. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/run_log.py +0 -0
  166. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/server_config.py +0 -0
  167. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/models/skill_definition.py +0 -0
  168. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/operations_cli.py +0 -0
  169. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/ownership.py +0 -0
  170. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/packmeta.py +0 -0
  171. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/registry.py +0 -0
  172. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resolver.py +0 -0
  173. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resource_provider.py +0 -0
  174. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/attention_pet/client-state.schema.json +0 -0
  175. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/attention_pet/pet.css +0 -0
  176. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/attention_pet/pet.html +0 -0
  177. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/attention_pet/pet.js +0 -0
  178. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/contracts.json +0 -0
  179. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/current.json +0 -0
  180. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/generations/7a682a5272907354/contracts.json +0 -0
  181. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/generations/7a682a5272907354/model_body.md +0 -0
  182. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/generations/9929294385ccb7b0/contracts.json +0 -0
  183. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/generations/9929294385ccb7b0/model_body.md +0 -0
  184. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/model_body.md +0 -0
  185. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/startup_sources/000_agent_entry.md +0 -0
  186. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/startup_sources/011_startup_xref_routing.md +0 -0
  187. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/startup_sources/015_shared_memory_operations.md +0 -0
  188. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/startup_sources/016_uncertainty_protocol.md +0 -0
  189. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/startup_sources/017_base_and_xref_layering.md +0 -0
  190. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/resources/base/startup_sources/053_context_direction_security_guard.md +0 -0
  191. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/runlog.py +0 -0
  192. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/skill_definition.py +0 -0
  193. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/skill_definition_catalog.py +0 -0
  194. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/skill_definition_governance.py +0 -0
  195. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/skillmeta.py +0 -0
  196. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/skillrun.py +0 -0
  197. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/skills_sync.py +0 -0
  198. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/structure_catalog.py +0 -0
  199. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/subagent_startup.py +0 -0
  200. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/tools/__init__.py +0 -0
  201. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/tools/__main__.py +0 -0
  202. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/v2_cli.py +0 -0
  203. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/wbs.py +0 -0
  204. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/workspace.py +0 -0
  205. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit/xref.py +0 -0
  206. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit.egg-info/dependency_links.txt +0 -0
  207. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit.egg-info/entry_points.txt +0 -0
  208. {xrefkit-0.6.0 → xrefkit-0.6.1}/xrefkit.egg-info/requires.txt +0 -0
  209. {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.0
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)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "xrefkit"
7
- version = "0.6.0"
7
+ version = "0.6.1"
8
8
  description = "Portable XID, Skill, Knowledge, workflow, and MCP runtime for XRefKit"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -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
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.6.0"
5
+ __version__ = "0.6.1"
@@ -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",