aictx 0.3.0__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 (39) hide show
  1. aictx-0.3.0/LICENSE +21 -0
  2. aictx-0.3.0/PKG-INFO +170 -0
  3. aictx-0.3.0/README.md +152 -0
  4. aictx-0.3.0/pyproject.toml +41 -0
  5. aictx-0.3.0/setup.cfg +4 -0
  6. aictx-0.3.0/src/aictx/__init__.py +4 -0
  7. aictx-0.3.0/src/aictx/__main__.py +3 -0
  8. aictx-0.3.0/src/aictx/_version.py +1 -0
  9. aictx-0.3.0/src/aictx/adapters.py +200 -0
  10. aictx-0.3.0/src/aictx/agent_runtime.py +201 -0
  11. aictx-0.3.0/src/aictx/cli.py +585 -0
  12. aictx-0.3.0/src/aictx/core_runtime.py +1877 -0
  13. aictx-0.3.0/src/aictx/global_metrics.py +759 -0
  14. aictx-0.3.0/src/aictx/middleware.py +401 -0
  15. aictx-0.3.0/src/aictx/runner_integrations.py +372 -0
  16. aictx-0.3.0/src/aictx/runtime_compat.py +130 -0
  17. aictx-0.3.0/src/aictx/runtime_contract.py +229 -0
  18. aictx-0.3.0/src/aictx/runtime_cost.py +445 -0
  19. aictx-0.3.0/src/aictx/runtime_failure.py +244 -0
  20. aictx-0.3.0/src/aictx/runtime_graph.py +339 -0
  21. aictx-0.3.0/src/aictx/runtime_io.py +101 -0
  22. aictx-0.3.0/src/aictx/runtime_knowledge.py +1098 -0
  23. aictx-0.3.0/src/aictx/runtime_launcher.py +108 -0
  24. aictx-0.3.0/src/aictx/runtime_memory.py +280 -0
  25. aictx-0.3.0/src/aictx/runtime_metrics.py +125 -0
  26. aictx-0.3.0/src/aictx/runtime_task_memory.py +167 -0
  27. aictx-0.3.0/src/aictx/runtime_tasks.py +302 -0
  28. aictx-0.3.0/src/aictx/runtime_versioning.py +92 -0
  29. aictx-0.3.0/src/aictx/scaffold.py +224 -0
  30. aictx-0.3.0/src/aictx/state.py +129 -0
  31. aictx-0.3.0/src/aictx/templates/context_packet_schema.json +34 -0
  32. aictx-0.3.0/src/aictx/templates/model_routing.json +47 -0
  33. aictx-0.3.0/src/aictx/templates/user_preferences.json +74 -0
  34. aictx-0.3.0/src/aictx.egg-info/PKG-INFO +170 -0
  35. aictx-0.3.0/src/aictx.egg-info/SOURCES.txt +37 -0
  36. aictx-0.3.0/src/aictx.egg-info/dependency_links.txt +1 -0
  37. aictx-0.3.0/src/aictx.egg-info/entry_points.txt +2 -0
  38. aictx-0.3.0/src/aictx.egg-info/top_level.txt +1 -0
  39. aictx-0.3.0/tests/test_smoke.py +1012 -0
aictx-0.3.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Santi Santamaria
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
aictx-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,170 @@
1
+ Metadata-Version: 2.4
2
+ Name: aictx
3
+ Version: 0.3.0
4
+ Summary: Repo-native runtime contract and context bootstrapper for coding agents
5
+ Author: Santi Santamaria
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/oldskultxo/aictx
8
+ Project-URL: Repository, https://github.com/oldskultxo/aictx
9
+ Project-URL: Issues, https://github.com/oldskultxo/aictx/issues
10
+ Keywords: ai,llm,coding-agents,developer-tools,context-engine,codex,claude
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Development Status :: 4 - Beta
14
+ Requires-Python: >=3.11
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Dynamic: license-file
18
+
19
+ # aictx
20
+
21
+ **Install once. Initialize a repo. Give coding agents a real runtime contract.**
22
+
23
+ `aictx` turns a normal repository into a repository that is prepared for coding agents.
24
+
25
+ ## Product surface
26
+
27
+ The sellable user flow stays intentionally small:
28
+
29
+ 1. `aictx install`
30
+ 2. `aictx init`
31
+ 3. use Codex, Claude Code, or your normal automation
32
+
33
+ Everything else exists to support that runtime, not to expand the primary UX.
34
+
35
+ ## What it really does today
36
+
37
+ After `install + init`, `aictx` can provide:
38
+
39
+ - repo-local bootstrap memory under `.ai_context_engine/`
40
+ - packet-oriented context for non-trivial work
41
+ - task memory, failure memory, and memory graph scaffolds
42
+ - repo-native instruction integration for Codex and Claude Code
43
+ - wrapped middleware for generic automation via `aictx internal run-execution`
44
+ - local/global telemetry and health artifacts
45
+
46
+ ## Honest limits
47
+
48
+ This is still a **0.x beta** product.
49
+
50
+ - final behavior depends on each runner honoring its instruction and hook system
51
+ - telemetry quality is best-effort unless confidence is explicitly high
52
+ - advanced/internal commands are supported, but not the main thing being sold
53
+ - some deeper capabilities are still being extracted from the canonical engine
54
+
55
+ See [docs/LIMITATIONS.md](docs/LIMITATIONS.md).
56
+
57
+ ## Install from PyPI
58
+
59
+ ```bash
60
+ pip install aictx
61
+ ```
62
+
63
+ Then:
64
+
65
+ ```bash
66
+ aictx install
67
+ aictx init --repo .
68
+ ```
69
+
70
+ ## Install once
71
+
72
+ ```bash
73
+ aictx install
74
+ ```
75
+
76
+ Non-interactive:
77
+
78
+ ```bash
79
+ aictx install --yes --workspace-root ~/projects
80
+ ```
81
+
82
+ This creates the global runtime under `~/.ai_context_engine/` and provisions:
83
+
84
+ - global configuration
85
+ - workspace registry
86
+ - adapters and wrappers
87
+ - global telemetry storage
88
+ - global Codex instructions
89
+
90
+ ## Initialize a repo
91
+
92
+ ```bash
93
+ aictx init
94
+ ```
95
+
96
+ Non-interactive:
97
+
98
+ ```bash
99
+ aictx init --repo . --yes
100
+ ```
101
+
102
+ `init` creates:
103
+
104
+ - `.ai_context_engine/memory/`
105
+ - `.ai_context_engine/cost/`
106
+ - `.ai_context_engine/task_memory/`
107
+ - `.ai_context_engine/failure_memory/`
108
+ - `.ai_context_engine/memory_graph/`
109
+ - `.ai_context_engine/library/`
110
+ - `.ai_context_engine/metrics/`
111
+ - `.ai_context_engine/adapters/`
112
+ - `.ai_context_engine/state.json`
113
+ - `.ai_context_engine/agent_runtime.md`
114
+
115
+ And native repo integration files:
116
+
117
+ - `AGENTS.md`
118
+ - `AGENTS.override.md`
119
+ - `CLAUDE.md`
120
+ - `.claude/settings.json`
121
+ - `.claude/hooks/...`
122
+ - `.gitignore`
123
+
124
+ ## Runtime consistency
125
+
126
+ `aictx boot --repo <path>` and `aictx execution prepare ...` now expose:
127
+
128
+ - effective communication policy
129
+ - communication source precedence
130
+ - runtime consistency checks between repo preferences and repo state
131
+
132
+ Precedence is:
133
+
134
+ `explicit user instruction > repo prefs > global defaults > hardcoded fallback`
135
+
136
+ ## Public beta posture
137
+
138
+ `aictx` is now distributed publicly as a **beta 0.x** package.
139
+
140
+ - installation is supported through PyPI and GitHub releases
141
+ - the core user flow is `pip install aictx` -> `aictx install` -> `aictx init`
142
+ - compatibility is still best-effort, not a long-term 1.0 stability promise
143
+
144
+ ## Development quickstart
145
+
146
+ ```bash
147
+ python3 -m venv .venv
148
+ .venv/bin/pip install --upgrade pip
149
+ .venv/bin/pip install -e . pytest build
150
+ make test
151
+ make smoke
152
+ make package-check
153
+ ```
154
+
155
+ You can also call the installed script directly:
156
+
157
+ ```bash
158
+ .venv/bin/aictx --help
159
+ ```
160
+
161
+ Public release validation also checks clean wheel installation, not just editable installs.
162
+
163
+ ## Read next
164
+
165
+ - [Usage guide](docs/USAGE.md)
166
+ - [Technical overview](docs/TECHNICAL_OVERVIEW.md)
167
+ - [5-minute demo](docs/DEMO.md)
168
+ - [Current limitations](docs/LIMITATIONS.md)
169
+ - [Phase 2 notes](docs/PHASE2_NOTES.md)
170
+ - [Release checklist](docs/RELEASE_CHECKLIST.md)
aictx-0.3.0/README.md ADDED
@@ -0,0 +1,152 @@
1
+ # aictx
2
+
3
+ **Install once. Initialize a repo. Give coding agents a real runtime contract.**
4
+
5
+ `aictx` turns a normal repository into a repository that is prepared for coding agents.
6
+
7
+ ## Product surface
8
+
9
+ The sellable user flow stays intentionally small:
10
+
11
+ 1. `aictx install`
12
+ 2. `aictx init`
13
+ 3. use Codex, Claude Code, or your normal automation
14
+
15
+ Everything else exists to support that runtime, not to expand the primary UX.
16
+
17
+ ## What it really does today
18
+
19
+ After `install + init`, `aictx` can provide:
20
+
21
+ - repo-local bootstrap memory under `.ai_context_engine/`
22
+ - packet-oriented context for non-trivial work
23
+ - task memory, failure memory, and memory graph scaffolds
24
+ - repo-native instruction integration for Codex and Claude Code
25
+ - wrapped middleware for generic automation via `aictx internal run-execution`
26
+ - local/global telemetry and health artifacts
27
+
28
+ ## Honest limits
29
+
30
+ This is still a **0.x beta** product.
31
+
32
+ - final behavior depends on each runner honoring its instruction and hook system
33
+ - telemetry quality is best-effort unless confidence is explicitly high
34
+ - advanced/internal commands are supported, but not the main thing being sold
35
+ - some deeper capabilities are still being extracted from the canonical engine
36
+
37
+ See [docs/LIMITATIONS.md](docs/LIMITATIONS.md).
38
+
39
+ ## Install from PyPI
40
+
41
+ ```bash
42
+ pip install aictx
43
+ ```
44
+
45
+ Then:
46
+
47
+ ```bash
48
+ aictx install
49
+ aictx init --repo .
50
+ ```
51
+
52
+ ## Install once
53
+
54
+ ```bash
55
+ aictx install
56
+ ```
57
+
58
+ Non-interactive:
59
+
60
+ ```bash
61
+ aictx install --yes --workspace-root ~/projects
62
+ ```
63
+
64
+ This creates the global runtime under `~/.ai_context_engine/` and provisions:
65
+
66
+ - global configuration
67
+ - workspace registry
68
+ - adapters and wrappers
69
+ - global telemetry storage
70
+ - global Codex instructions
71
+
72
+ ## Initialize a repo
73
+
74
+ ```bash
75
+ aictx init
76
+ ```
77
+
78
+ Non-interactive:
79
+
80
+ ```bash
81
+ aictx init --repo . --yes
82
+ ```
83
+
84
+ `init` creates:
85
+
86
+ - `.ai_context_engine/memory/`
87
+ - `.ai_context_engine/cost/`
88
+ - `.ai_context_engine/task_memory/`
89
+ - `.ai_context_engine/failure_memory/`
90
+ - `.ai_context_engine/memory_graph/`
91
+ - `.ai_context_engine/library/`
92
+ - `.ai_context_engine/metrics/`
93
+ - `.ai_context_engine/adapters/`
94
+ - `.ai_context_engine/state.json`
95
+ - `.ai_context_engine/agent_runtime.md`
96
+
97
+ And native repo integration files:
98
+
99
+ - `AGENTS.md`
100
+ - `AGENTS.override.md`
101
+ - `CLAUDE.md`
102
+ - `.claude/settings.json`
103
+ - `.claude/hooks/...`
104
+ - `.gitignore`
105
+
106
+ ## Runtime consistency
107
+
108
+ `aictx boot --repo <path>` and `aictx execution prepare ...` now expose:
109
+
110
+ - effective communication policy
111
+ - communication source precedence
112
+ - runtime consistency checks between repo preferences and repo state
113
+
114
+ Precedence is:
115
+
116
+ `explicit user instruction > repo prefs > global defaults > hardcoded fallback`
117
+
118
+ ## Public beta posture
119
+
120
+ `aictx` is now distributed publicly as a **beta 0.x** package.
121
+
122
+ - installation is supported through PyPI and GitHub releases
123
+ - the core user flow is `pip install aictx` -> `aictx install` -> `aictx init`
124
+ - compatibility is still best-effort, not a long-term 1.0 stability promise
125
+
126
+ ## Development quickstart
127
+
128
+ ```bash
129
+ python3 -m venv .venv
130
+ .venv/bin/pip install --upgrade pip
131
+ .venv/bin/pip install -e . pytest build
132
+ make test
133
+ make smoke
134
+ make package-check
135
+ ```
136
+
137
+ You can also call the installed script directly:
138
+
139
+ ```bash
140
+ .venv/bin/aictx --help
141
+ ```
142
+
143
+ Public release validation also checks clean wheel installation, not just editable installs.
144
+
145
+ ## Read next
146
+
147
+ - [Usage guide](docs/USAGE.md)
148
+ - [Technical overview](docs/TECHNICAL_OVERVIEW.md)
149
+ - [5-minute demo](docs/DEMO.md)
150
+ - [Current limitations](docs/LIMITATIONS.md)
151
+ - [Phase 2 notes](docs/PHASE2_NOTES.md)
152
+ - [Release checklist](docs/RELEASE_CHECKLIST.md)
@@ -0,0 +1,41 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "aictx"
7
+ version = "0.3.0"
8
+ description = "Repo-native runtime contract and context bootstrapper for coding agents"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ authors = [
12
+ { name = "Santi Santamaria" }
13
+ ]
14
+ license = "MIT"
15
+ keywords = ["ai", "llm", "coding-agents", "developer-tools", "context-engine", "codex", "claude"]
16
+ classifiers = [
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3 :: Only",
19
+ "Development Status :: 4 - Beta"
20
+ ]
21
+ dependencies = []
22
+
23
+ [project.urls]
24
+ Homepage = "https://github.com/oldskultxo/aictx"
25
+ Repository = "https://github.com/oldskultxo/aictx"
26
+ Issues = "https://github.com/oldskultxo/aictx/issues"
27
+
28
+ [project.scripts]
29
+ aictx = "aictx.cli:main"
30
+
31
+ [tool.setuptools]
32
+ package-dir = {"" = "src"}
33
+
34
+ [tool.setuptools.packages.find]
35
+ where = ["src"]
36
+
37
+ [tool.setuptools.package-data]
38
+ "aictx" = ["templates/*.json"]
39
+
40
+ [tool.pytest.ini_options]
41
+ testpaths = ["tests"]
aictx-0.3.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,4 @@
1
+ from ._version import __version__
2
+ from .middleware import finalize_execution, prepare_execution
3
+
4
+ __all__ = ["__version__", "prepare_execution", "finalize_execution"]
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ raise SystemExit(main())
@@ -0,0 +1 @@
1
+ __version__ = "0.3.0"
@@ -0,0 +1,200 @@
1
+ from __future__ import annotations
2
+
3
+ import stat
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+ from .state import ENGINE_HOME, REPO_ADAPTERS_DIR, write_json, read_json
8
+
9
+ GLOBAL_ADAPTERS_DIR = ENGINE_HOME / "adapters"
10
+ GLOBAL_ADAPTERS_REGISTRY_PATH = GLOBAL_ADAPTERS_DIR / "registry.json"
11
+ GLOBAL_ADAPTERS_BIN_DIR = GLOBAL_ADAPTERS_DIR / "bin"
12
+ GLOBAL_ADAPTERS_INSTALL_STATUS_PATH = GLOBAL_ADAPTERS_DIR / "install_status.json"
13
+
14
+
15
+ def adapter_runtime_contract(adapter_id: str) -> dict[str, Any]:
16
+ return {
17
+ "runtime_entrypoint": "aictx internal run-execution",
18
+ "integration_mode": "wrapper",
19
+ "auto_prepare_finalize": True,
20
+ "requires_request_context": True,
21
+ "wrapper_env": [
22
+ "AICTX_REQUEST",
23
+ "AICTX_REPO",
24
+ "AICTX_EXECUTION_ID",
25
+ "AICTX_AGENT_ID",
26
+ "AICTX_TASK_TYPE",
27
+ "AICTX_EXECUTION_MODE",
28
+ "AICTX_VALIDATED_LEARNING",
29
+ ],
30
+ "wrapper_script_name": f"aictx-{adapter_id}-auto",
31
+ }
32
+
33
+
34
+ def adapter_profiles() -> dict[str, dict[str, Any]]:
35
+ return {
36
+ "generic": {
37
+ "adapter_id": "generic",
38
+ "display_name": "Generic multi-LLM runner",
39
+ "family": "multi_llm",
40
+ "middleware_always_on": True,
41
+ "explicit_skill_metadata": False,
42
+ "structured_skill_metadata": True,
43
+ "heuristic_skill_fallback": True,
44
+ "auto_installed": True,
45
+ "runtime_contract": adapter_runtime_contract("generic"),
46
+ },
47
+ "codex": {
48
+ "adapter_id": "codex",
49
+ "display_name": "OpenAI Codex",
50
+ "family": "openai_codex",
51
+ "middleware_always_on": True,
52
+ "explicit_skill_metadata": True,
53
+ "structured_skill_metadata": True,
54
+ "heuristic_skill_fallback": True,
55
+ "expected_skill_metadata_fields": ["skill_id", "skill_name", "skill_path", "source"],
56
+ "auto_installed": True,
57
+ "runtime_contract": adapter_runtime_contract("codex"),
58
+ },
59
+ "claude": {
60
+ "adapter_id": "claude",
61
+ "display_name": "Anthropic Claude",
62
+ "family": "anthropic_claude",
63
+ "middleware_always_on": True,
64
+ "explicit_skill_metadata": True,
65
+ "structured_skill_metadata": True,
66
+ "heuristic_skill_fallback": True,
67
+ "expected_skill_metadata_fields": ["skill_id", "skill_name", "skill_path", "source"],
68
+ "auto_installed": True,
69
+ "runtime_contract": adapter_runtime_contract("claude"),
70
+ },
71
+ }
72
+
73
+
74
+ def adapter_registry_payload(scope: str) -> dict[str, Any]:
75
+ profiles = adapter_profiles()
76
+ return {
77
+ "version": 1,
78
+ "scope": scope,
79
+ "default_adapter_id": "generic",
80
+ "supported_adapters": sorted(profiles.keys()),
81
+ "middleware_mode": "always_on",
82
+ "skill_detection_contract": {
83
+ "authoritative_signal": "explicit_runner_metadata",
84
+ "structured_fallback": True,
85
+ "heuristic_fallback": True,
86
+ },
87
+ "runtime_contract": {
88
+ "entrypoint": "aictx internal run-execution",
89
+ "integration_mode": "wrapper",
90
+ "supported_runners": sorted(profiles.keys()),
91
+ },
92
+ }
93
+
94
+
95
+ def write_executable(path: Path, content: str) -> None:
96
+ path.parent.mkdir(parents=True, exist_ok=True)
97
+ path.write_text(content, encoding="utf-8")
98
+ path.chmod(path.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
99
+
100
+
101
+ def render_wrapper_script(adapter_id: str) -> str:
102
+ return f"""#!/bin/sh
103
+ set -eu
104
+ REQUEST="${{AICTX_REQUEST:-}}"
105
+ if [ -z "$REQUEST" ]; then
106
+ echo "AICTX_REQUEST must be set for {adapter_id} auto wrapper." >&2
107
+ exit 64
108
+ fi
109
+ REPO="${{AICTX_REPO:-.}}"
110
+ EXEC_ID="${{AICTX_EXECUTION_ID:-auto}}"
111
+ AGENT_ID="${{AICTX_AGENT_ID:-{adapter_id}}}"
112
+ TASK_TYPE="${{AICTX_TASK_TYPE:-}}"
113
+ EXEC_MODE="${{AICTX_EXECUTION_MODE:-plain}}"
114
+ VALIDATED="${{AICTX_VALIDATED_LEARNING:-0}}"
115
+ if [ "$VALIDATED" = "1" ] || [ "$VALIDATED" = "true" ]; then
116
+ VALIDATED_FLAG="--validated-learning"
117
+ else
118
+ VALIDATED_FLAG=""
119
+ fi
120
+ if [ -n "$TASK_TYPE" ]; then
121
+ exec aictx internal run-execution --repo "$REPO" --request "$REQUEST" --agent-id "$AGENT_ID" --adapter-id "{adapter_id}" --execution-id "$EXEC_ID" --execution-mode "$EXEC_MODE" $VALIDATED_FLAG --task-type "$TASK_TYPE" -- "$@"
122
+ fi
123
+ exec aictx internal run-execution --repo "$REPO" --request "$REQUEST" --agent-id "$AGENT_ID" --adapter-id "{adapter_id}" --execution-id "$EXEC_ID" --execution-mode "$EXEC_MODE" $VALIDATED_FLAG -- "$@"
124
+ """
125
+
126
+
127
+ def install_adapter_wrappers() -> list[Path]:
128
+ created: list[Path] = []
129
+ GLOBAL_ADAPTERS_BIN_DIR.mkdir(parents=True, exist_ok=True)
130
+ for adapter_id in sorted(adapter_profiles().keys()):
131
+ wrapper_name = adapter_runtime_contract(adapter_id)["wrapper_script_name"]
132
+ path = GLOBAL_ADAPTERS_BIN_DIR / wrapper_name
133
+ write_executable(path, render_wrapper_script(adapter_id))
134
+ created.append(path)
135
+ return created
136
+
137
+
138
+ def adapter_install_status_payload(wrapper_paths: list[Path]) -> dict[str, Any]:
139
+ profiles = adapter_profiles()
140
+ wrappers = {
141
+ adapter_id: str(GLOBAL_ADAPTERS_BIN_DIR / profiles[adapter_id]["runtime_contract"]["wrapper_script_name"])
142
+ for adapter_id in sorted(profiles.keys())
143
+ }
144
+ return {
145
+ "version": 1,
146
+ "engine_home": str(ENGINE_HOME),
147
+ "integration_mode": "wrapper",
148
+ "runtime_entrypoint": "aictx internal run-execution",
149
+ "supported_runners": sorted(profiles.keys()),
150
+ "wrappers": wrappers,
151
+ "artifacts": [str(path) for path in wrapper_paths],
152
+ "status": "wrapper_ready",
153
+ }
154
+
155
+
156
+ def install_global_adapters() -> list[Path]:
157
+ GLOBAL_ADAPTERS_DIR.mkdir(parents=True, exist_ok=True)
158
+ write_json(GLOBAL_ADAPTERS_REGISTRY_PATH, adapter_registry_payload("global"))
159
+ created = [GLOBAL_ADAPTERS_REGISTRY_PATH]
160
+ for adapter_id, payload in adapter_profiles().items():
161
+ path = GLOBAL_ADAPTERS_DIR / f"{adapter_id}.json"
162
+ write_json(path, payload)
163
+ created.append(path)
164
+ wrapper_paths = install_adapter_wrappers()
165
+ created.extend(wrapper_paths)
166
+ write_json(GLOBAL_ADAPTERS_INSTALL_STATUS_PATH, adapter_install_status_payload(wrapper_paths))
167
+ created.append(GLOBAL_ADAPTERS_INSTALL_STATUS_PATH)
168
+ return created
169
+
170
+
171
+ def install_repo_adapters(repo: Path) -> list[Path]:
172
+ adapters_dir = repo / REPO_ADAPTERS_DIR
173
+ adapters_dir.mkdir(parents=True, exist_ok=True)
174
+ registry_path = adapters_dir / "registry.json"
175
+ write_json(registry_path, adapter_registry_payload("repo"))
176
+ created = [registry_path]
177
+ for adapter_id, payload in adapter_profiles().items():
178
+ path = adapters_dir / f"{adapter_id}.json"
179
+ write_json(path, payload)
180
+ created.append(path)
181
+ return created
182
+
183
+
184
+ def resolve_adapter_profile(adapter_id: str | None, agent_id: str | None = None, repo_root: Path | None = None) -> dict[str, Any]:
185
+ requested = str(adapter_id or "").strip().lower()
186
+ agent = str(agent_id or "").strip().lower()
187
+ profiles = adapter_profiles()
188
+ resolved_id = requested if requested in profiles else "generic"
189
+ if resolved_id == "generic":
190
+ if "codex" in requested or "codex" in agent:
191
+ resolved_id = "codex"
192
+ elif "claude" in requested or "claude" in agent:
193
+ resolved_id = "claude"
194
+ if repo_root:
195
+ repo_path = repo_root / REPO_ADAPTERS_DIR / f"{resolved_id}.json"
196
+ if repo_path.exists():
197
+ payload = read_json(repo_path, {})
198
+ if payload:
199
+ return payload
200
+ return dict(profiles[resolved_id])