xrefkit 0.3.0__py3-none-any.whl

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 (65) hide show
  1. xrefkit/__init__.py +5 -0
  2. xrefkit/__main__.py +5 -0
  3. xrefkit/catalog_cli.py +57 -0
  4. xrefkit/cli.py +71 -0
  5. xrefkit/contracts.py +297 -0
  6. xrefkit/ctx.py +160 -0
  7. xrefkit/dashboard.py +1220 -0
  8. xrefkit/discovery.py +85 -0
  9. xrefkit/gate.py +428 -0
  10. xrefkit/goalstate.py +555 -0
  11. xrefkit/hashing.py +18 -0
  12. xrefkit/import_skill.py +469 -0
  13. xrefkit/instance.py +133 -0
  14. xrefkit/loaders.py +77 -0
  15. xrefkit/mcp/__init__.py +26 -0
  16. xrefkit/mcp/audit.py +168 -0
  17. xrefkit/mcp/bootstrap.py +337 -0
  18. xrefkit/mcp/catalog.py +2638 -0
  19. xrefkit/mcp/cli.py +173 -0
  20. xrefkit/mcp/client_cache.py +356 -0
  21. xrefkit/mcp/context_registry.py +277 -0
  22. xrefkit/mcp/contracts.py +243 -0
  23. xrefkit/mcp/dist.py +234 -0
  24. xrefkit/mcp/ownership.py +246 -0
  25. xrefkit/mcp/repository.py +217 -0
  26. xrefkit/mcp/schemas.py +349 -0
  27. xrefkit/mcp/server.py +773 -0
  28. xrefkit/mcp/startup_contract_pack.py +154 -0
  29. xrefkit/mcp_tools.py +47 -0
  30. xrefkit/models/__init__.py +41 -0
  31. xrefkit/models/common.py +185 -0
  32. xrefkit/models/effective_bundle.py +131 -0
  33. xrefkit/models/local_manifest.py +217 -0
  34. xrefkit/models/package_manifest.py +126 -0
  35. xrefkit/models/run_log.py +276 -0
  36. xrefkit/models/server_config.py +160 -0
  37. xrefkit/models/skill_definition.py +131 -0
  38. xrefkit/operations_cli.py +670 -0
  39. xrefkit/ownership.py +276 -0
  40. xrefkit/packmeta.py +289 -0
  41. xrefkit/registry.py +334 -0
  42. xrefkit/resolver.py +252 -0
  43. xrefkit/resource_provider.py +187 -0
  44. xrefkit/resources/base/contracts.json +178 -0
  45. xrefkit/resources/base/current.json +6 -0
  46. xrefkit/resources/base/generations/7a682a5272907354/contracts.json +178 -0
  47. xrefkit/resources/base/generations/7a682a5272907354/model_body.md +22 -0
  48. xrefkit/resources/base/generations/9929294385ccb7b0/contracts.json +178 -0
  49. xrefkit/resources/base/generations/9929294385ccb7b0/model_body.md +22 -0
  50. xrefkit/resources/base/model_body.md +22 -0
  51. xrefkit/runlog.py +45 -0
  52. xrefkit/skillmeta.py +1034 -0
  53. xrefkit/skillrun.py +2381 -0
  54. xrefkit/structure_catalog.py +199 -0
  55. xrefkit/tools/__init__.py +119 -0
  56. xrefkit/tools/__main__.py +4 -0
  57. xrefkit/v2_cli.py +130 -0
  58. xrefkit/workspace.py +117 -0
  59. xrefkit/xref.py +1048 -0
  60. xrefkit-0.3.0.dist-info/METADATA +203 -0
  61. xrefkit-0.3.0.dist-info/RECORD +65 -0
  62. xrefkit-0.3.0.dist-info/WHEEL +5 -0
  63. xrefkit-0.3.0.dist-info/entry_points.txt +2 -0
  64. xrefkit-0.3.0.dist-info/licenses/LICENSE +21 -0
  65. xrefkit-0.3.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,160 @@
1
+ """Pydantic model for xrefkit.server.toml."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pydantic import Field, field_validator, model_validator
6
+
7
+ from .common import CoreProtocol, StrictModel, validate_non_empty, validate_package_id
8
+
9
+
10
+ class CoreConfig(StrictModel):
11
+ package: str
12
+ version_constraint: str
13
+ startup_contract: str
14
+ protocols: list[CoreProtocol]
15
+
16
+ @field_validator("package", "version_constraint", "startup_contract")
17
+ @classmethod
18
+ def _validate_non_empty(cls, value: str) -> str:
19
+ return validate_non_empty(value, "value")
20
+
21
+ @field_validator("protocols")
22
+ @classmethod
23
+ def _validate_protocols(cls, values: list[CoreProtocol]) -> list[CoreProtocol]:
24
+ if not values:
25
+ raise ValueError("core.protocols must not be empty")
26
+ if len(set(values)) != len(values):
27
+ raise ValueError("core.protocols must not contain duplicates")
28
+ return values
29
+
30
+
31
+ class DiscoveryConfig(StrictModel):
32
+ python_entry_points: bool = True
33
+ filesystem_mounts: bool = True
34
+
35
+
36
+ class EnabledPackagesConfig(StrictModel):
37
+ enabled: list[str] = Field(default_factory=list)
38
+
39
+ @field_validator("enabled")
40
+ @classmethod
41
+ def _validate_enabled(cls, values: list[str]) -> list[str]:
42
+ if len(set(values)) != len(values):
43
+ raise ValueError("packages.enabled must not contain duplicates")
44
+ return [validate_package_id(value) for value in values]
45
+
46
+
47
+ class LocalMountConfig(StrictModel):
48
+ path: str | None = None
49
+ required: bool = False
50
+
51
+ @model_validator(mode="after")
52
+ def _require_path_when_required(self) -> "LocalMountConfig":
53
+ if self.required and not self.path:
54
+ raise ValueError("local.path is required when local.required is true")
55
+ return self
56
+
57
+
58
+ class MergePolicyConfig(StrictModel):
59
+ local_can_weaken_core: bool = False
60
+ local_can_weaken_pack_contract: bool = False
61
+ conflict_as_error: bool = True
62
+ require_source_trace: bool = True
63
+
64
+ @model_validator(mode="after")
65
+ def _enforce_mvp_policy(self) -> "MergePolicyConfig":
66
+ if self.local_can_weaken_core:
67
+ raise ValueError("MVP does not allow Project Local to weaken Core")
68
+ if self.local_can_weaken_pack_contract:
69
+ raise ValueError("MVP does not allow Project Local to weaken Pack contracts")
70
+ return self
71
+
72
+
73
+ class ServerLoadPolicyConfig(StrictModel):
74
+ default_knowledge: str = "reference_then_inline"
75
+ default_branch: str = "on_demand"
76
+ human_full_materialize: bool = True
77
+
78
+ @field_validator("default_knowledge")
79
+ @classmethod
80
+ def _validate_default_knowledge(cls, value: str) -> str:
81
+ allowed = {"reference_then_inline", "startup_reference", "on_demand", "required_inline"}
82
+ if value not in allowed:
83
+ raise ValueError(f"default_knowledge must be one of {sorted(allowed)}")
84
+ return value
85
+
86
+ @field_validator("default_branch")
87
+ @classmethod
88
+ def _validate_default_branch(cls, value: str) -> str:
89
+ if value != "on_demand":
90
+ raise ValueError("MVP only supports default_branch='on_demand'")
91
+ return value
92
+
93
+
94
+ class LoggingConfig(StrictModel):
95
+ run_log_enabled: bool = True
96
+ include_loaded_xids: bool = True
97
+ include_used_xids: bool = True
98
+ include_source_trace: bool = True
99
+ include_text_body: bool = False
100
+
101
+
102
+ class McpServerConfig(StrictModel):
103
+ host: str = "127.0.0.1"
104
+ port: int = 7331
105
+
106
+ @field_validator("host")
107
+ @classmethod
108
+ def _validate_host(cls, value: str) -> str:
109
+ return validate_non_empty(value, "host")
110
+
111
+ @field_validator("port")
112
+ @classmethod
113
+ def _validate_port(cls, value: int) -> int:
114
+ if value < 1 or value > 65535:
115
+ raise ValueError("mcp.port must be between 1 and 65535")
116
+ return value
117
+
118
+
119
+ class IdentityConfig(StrictModel):
120
+ mode: str = "client_ip"
121
+
122
+ @field_validator("mode")
123
+ @classmethod
124
+ def _validate_mode(cls, value: str) -> str:
125
+ if value not in {"client_ip", "user_id"}:
126
+ raise ValueError("identity.mode must be 'client_ip' or 'user_id'")
127
+ return value
128
+
129
+
130
+ class RuntimeConfig(StrictModel):
131
+ mode: str = "client_context"
132
+ require_used_xids: bool = True
133
+ require_unknowns: bool = True
134
+ require_applied_skills: bool = True
135
+ validate_output_contract: bool = True
136
+
137
+
138
+ class ExecutionConfig(StrictModel):
139
+ allow_package_code: bool = False
140
+ allowed_tools: dict[str, bool] = Field(default_factory=dict)
141
+
142
+ @model_validator(mode="after")
143
+ def _enforce_mvp_execution(self) -> "ExecutionConfig":
144
+ if self.allow_package_code:
145
+ raise ValueError("MVP does not allow package code execution")
146
+ return self
147
+
148
+
149
+ class XRefKitServerConfig(StrictModel):
150
+ core: CoreConfig
151
+ discovery: DiscoveryConfig = Field(default_factory=DiscoveryConfig)
152
+ packages: EnabledPackagesConfig = Field(default_factory=EnabledPackagesConfig)
153
+ local: LocalMountConfig = Field(default_factory=LocalMountConfig)
154
+ merge: MergePolicyConfig = Field(default_factory=MergePolicyConfig)
155
+ load_policy: ServerLoadPolicyConfig = Field(default_factory=ServerLoadPolicyConfig)
156
+ logging: LoggingConfig = Field(default_factory=LoggingConfig)
157
+ mcp: McpServerConfig = Field(default_factory=McpServerConfig)
158
+ identity: IdentityConfig | None = None
159
+ runtime: RuntimeConfig | None = None
160
+ execution: ExecutionConfig = Field(default_factory=ExecutionConfig)
@@ -0,0 +1,131 @@
1
+ """Pydantic model for reusable *.skill.yaml files."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Literal
6
+
7
+ from pydantic import Field, field_validator, model_validator
8
+
9
+ from .common import StrictModel, validate_non_empty, validate_xid
10
+
11
+
12
+ class SkillEntry(StrictModel):
13
+ xid: str
14
+ path: str
15
+ load_policy: Literal["required_inline"]
16
+
17
+ @field_validator("xid")
18
+ @classmethod
19
+ def _validate_xid(cls, value: str) -> str:
20
+ return validate_xid(value)
21
+
22
+ @field_validator("path")
23
+ @classmethod
24
+ def _validate_path(cls, value: str) -> str:
25
+ return validate_non_empty(value, "path")
26
+
27
+
28
+ class SkillFragment(StrictModel):
29
+ id: str
30
+ xid: str
31
+ path: str
32
+ load_policy: Literal["required_inline"]
33
+
34
+ @field_validator("id", "path")
35
+ @classmethod
36
+ def _validate_non_empty(cls, value: str) -> str:
37
+ return validate_non_empty(value, "value")
38
+
39
+ @field_validator("xid")
40
+ @classmethod
41
+ def _validate_xid(cls, value: str) -> str:
42
+ return validate_xid(value)
43
+
44
+
45
+ class BranchCondition(StrictModel):
46
+ any_intent: list[str]
47
+
48
+ @field_validator("any_intent")
49
+ @classmethod
50
+ def _validate_any_intent(cls, values: list[str]) -> list[str]:
51
+ if not values:
52
+ raise ValueError("branch condition any_intent must not be empty")
53
+ return [validate_non_empty(value, "intent") for value in values]
54
+
55
+
56
+ class SkillBranch(StrictModel):
57
+ id: str
58
+ xid: str
59
+ path: str
60
+ condition: BranchCondition
61
+ load_policy: Literal["on_demand"]
62
+
63
+ @field_validator("id", "path")
64
+ @classmethod
65
+ def _validate_non_empty(cls, value: str) -> str:
66
+ return validate_non_empty(value, "value")
67
+
68
+ @field_validator("xid")
69
+ @classmethod
70
+ def _validate_xid(cls, value: str) -> str:
71
+ return validate_xid(value)
72
+
73
+
74
+ class SkillExtensionPolicy(StrictModel):
75
+ can_be_extended_by_local_skill: bool = True
76
+ local_can_weaken_required_outputs: bool = False
77
+ local_can_override_must_not: bool = False
78
+
79
+ @model_validator(mode="after")
80
+ def _enforce_mvp_policy(self) -> "SkillExtensionPolicy":
81
+ if self.local_can_weaken_required_outputs:
82
+ raise ValueError("MVP does not allow local skills to weaken required outputs")
83
+ if self.local_can_override_must_not:
84
+ raise ValueError("MVP does not allow local skills to override must_not")
85
+ return self
86
+
87
+
88
+ class SkillDefinition(StrictModel):
89
+ skill_id: str
90
+ xid: str
91
+ role: str | None = None
92
+ entry: SkillEntry
93
+ required_fragments: list[SkillFragment] = Field(default_factory=list)
94
+ branches: list[SkillBranch] = Field(default_factory=list)
95
+ required_outputs: list[str]
96
+ required_knowledge: list[str] = Field(default_factory=list)
97
+ review_axes: list[str] = Field(default_factory=list)
98
+ schemas: list[str] = Field(default_factory=list)
99
+ must_not: list[str] = Field(default_factory=list)
100
+ extension_policy: SkillExtensionPolicy
101
+
102
+ @field_validator("skill_id")
103
+ @classmethod
104
+ def _validate_skill_id(cls, value: str) -> str:
105
+ return validate_non_empty(value, "skill_id")
106
+
107
+ @field_validator("xid")
108
+ @classmethod
109
+ def _validate_xid(cls, value: str) -> str:
110
+ return validate_xid(value)
111
+
112
+ @field_validator("required_outputs")
113
+ @classmethod
114
+ def _validate_required_outputs(cls, values: list[str]) -> list[str]:
115
+ if not values:
116
+ raise ValueError("required_outputs must not be empty")
117
+ return [validate_non_empty(value, "required_output") for value in values]
118
+
119
+ @field_validator("required_knowledge", "review_axes", "schemas", "must_not")
120
+ @classmethod
121
+ def _validate_string_list(cls, values: list[str]) -> list[str]:
122
+ return [validate_non_empty(value, "list item") for value in values]
123
+
124
+ @model_validator(mode="after")
125
+ def _validate_unique_xids(self) -> "SkillDefinition":
126
+ xids = [self.xid, self.entry.xid]
127
+ xids.extend(fragment.xid for fragment in self.required_fragments)
128
+ xids.extend(branch.xid for branch in self.branches)
129
+ if len(xids) != len(set(xids)):
130
+ raise ValueError("SkillDefinition contains duplicate XIDs")
131
+ return self