capability-compiler 0.1.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.
- capability_compiler-0.1.0/.gitignore +36 -0
- capability_compiler-0.1.0/LICENSE +21 -0
- capability_compiler-0.1.0/PKG-INFO +261 -0
- capability_compiler-0.1.0/README.md +212 -0
- capability_compiler-0.1.0/docs/adapters/browser.md +88 -0
- capability_compiler-0.1.0/docs/architecture/README.md +17 -0
- capability_compiler-0.1.0/docs/architecture/mcp.md +236 -0
- capability_compiler-0.1.0/docs/architecture/registry.md +259 -0
- capability_compiler-0.1.0/docs/architecture.md +111 -0
- capability_compiler-0.1.0/docs/benchmarks.md +143 -0
- capability_compiler-0.1.0/docs/ci.md +170 -0
- capability_compiler-0.1.0/docs/cli/commands.md +337 -0
- capability_compiler-0.1.0/docs/concepts/exploration.md +66 -0
- capability_compiler-0.1.0/docs/concepts/local-first.md +225 -0
- capability_compiler-0.1.0/docs/master-plan.md +43 -0
- capability_compiler-0.1.0/docs/models.md +65 -0
- capability_compiler-0.1.0/docs/research/differentiation.md +96 -0
- capability_compiler-0.1.0/docs/research/landscape.md +64 -0
- capability_compiler-0.1.0/docs/research/sources/benchmarks-skill-learning.md +592 -0
- capability_compiler-0.1.0/docs/research/sources/desktop-automation.md +613 -0
- capability_compiler-0.1.0/docs/research/sources/gui-agents-vision.md +157 -0
- capability_compiler-0.1.0/docs/research/sources/mcp-ecosystem.md +527 -0
- capability_compiler-0.1.0/docs/research/sources/packaging-security.md +767 -0
- capability_compiler-0.1.0/pyproject.toml +153 -0
- capability_compiler-0.1.0/src/capability_compiler/__init__.py +76 -0
- capability_compiler-0.1.0/src/capability_compiler/_version.py +8 -0
- capability_compiler-0.1.0/src/capability_compiler/adapters/__init__.py +70 -0
- capability_compiler-0.1.0/src/capability_compiler/adapters/base.py +166 -0
- capability_compiler-0.1.0/src/capability_compiler/adapters/browser/__init__.py +7 -0
- capability_compiler-0.1.0/src/capability_compiler/adapters/browser/adapter.py +474 -0
- capability_compiler-0.1.0/src/capability_compiler/adapters/browser/aria.py +147 -0
- capability_compiler-0.1.0/src/capability_compiler/adapters/browser/elements.py +185 -0
- capability_compiler-0.1.0/src/capability_compiler/adapters/desktop/__init__.py +9 -0
- capability_compiler-0.1.0/src/capability_compiler/adapters/desktop/base.py +90 -0
- capability_compiler-0.1.0/src/capability_compiler/adapters/fake_adapter.py +242 -0
- capability_compiler-0.1.0/src/capability_compiler/benchmark/__init__.py +42 -0
- capability_compiler-0.1.0/src/capability_compiler/benchmark/data/capability_bench.json +81 -0
- capability_compiler-0.1.0/src/capability_compiler/benchmark/data/seed.json +148 -0
- capability_compiler-0.1.0/src/capability_compiler/benchmark/report.py +164 -0
- capability_compiler-0.1.0/src/capability_compiler/benchmark/spec.py +249 -0
- capability_compiler-0.1.0/src/capability_compiler/benchmark/suite.py +396 -0
- capability_compiler-0.1.0/src/capability_compiler/cli/__init__.py +5 -0
- capability_compiler-0.1.0/src/capability_compiler/cli/_common.py +135 -0
- capability_compiler-0.1.0/src/capability_compiler/cli/_register.py +35 -0
- capability_compiler-0.1.0/src/capability_compiler/cli/benchmark_cmd.py +284 -0
- capability_compiler-0.1.0/src/capability_compiler/cli/config_cmds.py +230 -0
- capability_compiler-0.1.0/src/capability_compiler/cli/execute_cmd.py +196 -0
- capability_compiler-0.1.0/src/capability_compiler/cli/learn_cmd.py +134 -0
- capability_compiler-0.1.0/src/capability_compiler/cli/main.py +184 -0
- capability_compiler-0.1.0/src/capability_compiler/cli/registry_cmds.py +127 -0
- capability_compiler-0.1.0/src/capability_compiler/cli/serve_cmd.py +124 -0
- capability_compiler-0.1.0/src/capability_compiler/compiler.py +203 -0
- capability_compiler-0.1.0/src/capability_compiler/config.py +282 -0
- capability_compiler-0.1.0/src/capability_compiler/errors.py +348 -0
- capability_compiler-0.1.0/src/capability_compiler/exploration/__init__.py +33 -0
- capability_compiler-0.1.0/src/capability_compiler/exploration/effects.py +227 -0
- capability_compiler-0.1.0/src/capability_compiler/exploration/engine.py +347 -0
- capability_compiler-0.1.0/src/capability_compiler/exploration/semantics.py +257 -0
- capability_compiler-0.1.0/src/capability_compiler/logging.py +228 -0
- capability_compiler-0.1.0/src/capability_compiler/models/__init__.py +127 -0
- capability_compiler-0.1.0/src/capability_compiler/models/action.py +216 -0
- capability_compiler-0.1.0/src/capability_compiler/models/capability.py +389 -0
- capability_compiler-0.1.0/src/capability_compiler/models/observation.py +281 -0
- capability_compiler-0.1.0/src/capability_compiler/models/state.py +49 -0
- capability_compiler-0.1.0/src/capability_compiler/models/transition.py +124 -0
- capability_compiler-0.1.0/src/capability_compiler/models/verification.py +85 -0
- capability_compiler-0.1.0/src/capability_compiler/models/versioning.py +77 -0
- capability_compiler-0.1.0/src/capability_compiler/perception/__init__.py +22 -0
- capability_compiler-0.1.0/src/capability_compiler/perception/pipeline.py +70 -0
- capability_compiler-0.1.0/src/capability_compiler/perception/semantic.py +245 -0
- capability_compiler-0.1.0/src/capability_compiler/providers/__init__.py +60 -0
- capability_compiler-0.1.0/src/capability_compiler/providers/anthropic.py +132 -0
- capability_compiler-0.1.0/src/capability_compiler/providers/base.py +185 -0
- capability_compiler-0.1.0/src/capability_compiler/providers/http.py +216 -0
- capability_compiler-0.1.0/src/capability_compiler/providers/mock.py +158 -0
- capability_compiler-0.1.0/src/capability_compiler/providers/ollama.py +124 -0
- capability_compiler-0.1.0/src/capability_compiler/providers/openai_compat.py +153 -0
- capability_compiler-0.1.0/src/capability_compiler/recording/__init__.py +6 -0
- capability_compiler-0.1.0/src/capability_compiler/recording/recorder.py +255 -0
- capability_compiler-0.1.0/src/capability_compiler/recording/replay.py +174 -0
- capability_compiler-0.1.0/src/capability_compiler/refinement/__init__.py +11 -0
- capability_compiler-0.1.0/src/capability_compiler/refinement/engine.py +188 -0
- capability_compiler-0.1.0/src/capability_compiler/refinement/repair.py +254 -0
- capability_compiler-0.1.0/src/capability_compiler/registry/__init__.py +24 -0
- capability_compiler-0.1.0/src/capability_compiler/registry/permissions.py +191 -0
- capability_compiler-0.1.0/src/capability_compiler/registry/registry.py +251 -0
- capability_compiler-0.1.0/src/capability_compiler/runtime/__init__.py +17 -0
- capability_compiler-0.1.0/src/capability_compiler/runtime/assertions.py +114 -0
- capability_compiler-0.1.0/src/capability_compiler/runtime/executor.py +422 -0
- capability_compiler-0.1.0/src/capability_compiler/server/__init__.py +114 -0
- capability_compiler-0.1.0/src/capability_compiler/server/auth.py +141 -0
- capability_compiler-0.1.0/src/capability_compiler/server/executor_factory.py +75 -0
- capability_compiler-0.1.0/src/capability_compiler/server/server.py +555 -0
- capability_compiler-0.1.0/src/capability_compiler/server/tool_defs.py +98 -0
- capability_compiler-0.1.0/src/capability_compiler/storage/__init__.py +7 -0
- capability_compiler-0.1.0/src/capability_compiler/storage/base.py +62 -0
- capability_compiler-0.1.0/src/capability_compiler/storage/filesystem.py +236 -0
- capability_compiler-0.1.0/src/capability_compiler/storage/sqlite.py +284 -0
- capability_compiler-0.1.0/src/capability_compiler/synthesis/__init__.py +20 -0
- capability_compiler-0.1.0/src/capability_compiler/synthesis/engine.py +549 -0
- capability_compiler-0.1.0/src/capability_compiler/synthesis/templating.py +84 -0
- capability_compiler-0.1.0/src/capability_compiler/types.py +97 -0
- capability_compiler-0.1.0/src/capability_compiler/verification/__init__.py +42 -0
- capability_compiler-0.1.0/src/capability_compiler/verification/base.py +97 -0
- capability_compiler-0.1.0/src/capability_compiler/verification/file_visual.py +224 -0
- capability_compiler-0.1.0/src/capability_compiler/verification/runner.py +79 -0
- capability_compiler-0.1.0/src/capability_compiler/verification/verifiers.py +292 -0
- capability_compiler-0.1.0/tests/conftest.py +60 -0
- capability_compiler-0.1.0/tests/fixtures/site/index.html +88 -0
- capability_compiler-0.1.0/tests/test_action_semantics.py +199 -0
- capability_compiler-0.1.0/tests/test_aria_parser.py +90 -0
- capability_compiler-0.1.0/tests/test_benchmark.py +438 -0
- capability_compiler-0.1.0/tests/test_browser_adapter.py +185 -0
- capability_compiler-0.1.0/tests/test_browser_unit.py +93 -0
- capability_compiler-0.1.0/tests/test_cli.py +539 -0
- capability_compiler-0.1.0/tests/test_compile_e2e.py +181 -0
- capability_compiler-0.1.0/tests/test_compiler.py +119 -0
- capability_compiler-0.1.0/tests/test_config.py +133 -0
- capability_compiler-0.1.0/tests/test_e2e_record_replay.py +109 -0
- capability_compiler-0.1.0/tests/test_errors.py +69 -0
- capability_compiler-0.1.0/tests/test_executor.py +220 -0
- capability_compiler-0.1.0/tests/test_exploration.py +288 -0
- capability_compiler-0.1.0/tests/test_exploration_e2e.py +103 -0
- capability_compiler-0.1.0/tests/test_logging.py +96 -0
- capability_compiler-0.1.0/tests/test_mcp_server.py +460 -0
- capability_compiler-0.1.0/tests/test_models.py +253 -0
- capability_compiler-0.1.0/tests/test_perception.py +227 -0
- capability_compiler-0.1.0/tests/test_providers_http.py +214 -0
- capability_compiler-0.1.0/tests/test_recording.py +194 -0
- capability_compiler-0.1.0/tests/test_refinement.py +197 -0
- capability_compiler-0.1.0/tests/test_refinement_e2e.py +90 -0
- capability_compiler-0.1.0/tests/test_registry.py +294 -0
- capability_compiler-0.1.0/tests/test_state_consistency_eval.py +88 -0
- capability_compiler-0.1.0/tests/test_storage.py +162 -0
- capability_compiler-0.1.0/tests/test_synthesis.py +242 -0
- capability_compiler-0.1.0/tests/test_types.py +77 -0
- capability_compiler-0.1.0/tests/test_verifiers.py +255 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
.claude/
|
|
2
|
+
implementation_plan.md
|
|
3
|
+
|
|
4
|
+
# Python
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
*.egg-info/
|
|
8
|
+
.eggs/
|
|
9
|
+
dist/
|
|
10
|
+
build/
|
|
11
|
+
.venv/
|
|
12
|
+
venv/
|
|
13
|
+
|
|
14
|
+
# Tooling caches
|
|
15
|
+
.pytest_cache/
|
|
16
|
+
.mypy_cache/
|
|
17
|
+
.ruff_cache/
|
|
18
|
+
.coverage
|
|
19
|
+
coverage.xml
|
|
20
|
+
htmlcov/
|
|
21
|
+
|
|
22
|
+
# Local state
|
|
23
|
+
*.sqlite3
|
|
24
|
+
*.db
|
|
25
|
+
capability-compiler.toml
|
|
26
|
+
|
|
27
|
+
# OS/editor
|
|
28
|
+
.DS_Store
|
|
29
|
+
Thumbs.db
|
|
30
|
+
.idea/
|
|
31
|
+
.vscode/
|
|
32
|
+
|
|
33
|
+
# Secrets — never commit
|
|
34
|
+
.env
|
|
35
|
+
.env.*
|
|
36
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Capability Compiler Contributors
|
|
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.
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: capability-compiler
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Turn any software into an API for AI: compile interaction trajectories into verified, reusable capabilities exposed via Python, CLI, and MCP.
|
|
5
|
+
Project-URL: Homepage, https://github.com/capability-compiler/capability-compiler
|
|
6
|
+
Project-URL: Documentation, https://github.com/capability-compiler/capability-compiler/tree/main/docs
|
|
7
|
+
Project-URL: Issues, https://github.com/capability-compiler/capability-compiler/issues
|
|
8
|
+
Author: Capability Compiler Contributors
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agents,automation,browser-automation,capability-learning,gui-agents,llm,mcp,model-context-protocol
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: mcp<3,>=2.0
|
|
23
|
+
Requires-Dist: platformdirs<5,>=4.2
|
|
24
|
+
Requires-Dist: pydantic-settings<3,>=2.3
|
|
25
|
+
Requires-Dist: pydantic<3,>=2.7
|
|
26
|
+
Requires-Dist: pyyaml<7,>=6.0
|
|
27
|
+
Requires-Dist: typer<1,>=0.12
|
|
28
|
+
Provides-Extra: anthropic
|
|
29
|
+
Requires-Dist: httpx>=0.27; extra == 'anthropic'
|
|
30
|
+
Provides-Extra: browser
|
|
31
|
+
Requires-Dist: playwright>=1.45; extra == 'browser'
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: bandit>=1.7; extra == 'dev'
|
|
34
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
35
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest>=8.2; extra == 'dev'
|
|
39
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
40
|
+
Requires-Dist: types-pyyaml; extra == 'dev'
|
|
41
|
+
Provides-Extra: models
|
|
42
|
+
Requires-Dist: httpx>=0.27; extra == 'models'
|
|
43
|
+
Provides-Extra: ollama
|
|
44
|
+
Requires-Dist: httpx>=0.27; extra == 'ollama'
|
|
45
|
+
Provides-Extra: openai
|
|
46
|
+
Requires-Dist: httpx>=0.27; extra == 'openai'
|
|
47
|
+
Provides-Extra: sqlite
|
|
48
|
+
Description-Content-Type: text/markdown
|
|
49
|
+
|
|
50
|
+
# Capability Compiler
|
|
51
|
+
|
|
52
|
+
> **Turn any software into an API for AI.**
|
|
53
|
+
|
|
54
|
+
Capability Compiler observes black-box software, explores it safely, and
|
|
55
|
+
compiles interaction trajectories into **verified, reusable capabilities** —
|
|
56
|
+
exposed to any LLM through Python APIs, the `cc` CLI, and the Model Context
|
|
57
|
+
Protocol (MCP). Fully local-first: the default configuration runs offline
|
|
58
|
+
with no account and no telemetry.
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
UNKNOWN SOFTWARE ─▶ OBSERVE ─▶ EXPLORE ─▶ COMPILE ─▶ VERIFY ─▶ REUSE
|
|
62
|
+
│
|
|
63
|
+
┌───────────────────────┼───────────────────────┐
|
|
64
|
+
▼ ▼ ▼
|
|
65
|
+
`cc execute` `cc serve` (MCP) Python API
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## What does this do?
|
|
69
|
+
|
|
70
|
+
Capability Compiler records how an application responds to actions, classifies
|
|
71
|
+
those responses with deterministic semantic-state diffs, and turns the result
|
|
72
|
+
into a typed, versioned, permission-scoped **Capability** artifact — a unit
|
|
73
|
+
of reusable software control that any LLM can call via MCP. The output is
|
|
74
|
+
*executable without an LLM in the loop*: it carries inputs, preconditions,
|
|
75
|
+
postconditions, verifiers, and confidence derived from execution evidence.
|
|
76
|
+
|
|
77
|
+
## Why does it exist?
|
|
78
|
+
|
|
79
|
+
Every adjacent project — record/replay tools, GUI-agent libraries, skill
|
|
80
|
+
distributors — stops one or two steps short of the full pipeline. Capability
|
|
81
|
+
Compiler ships the whole pipeline as a **compiler**, with the properties
|
|
82
|
+
compilers have: determinism where possible, typed artifacts, reproducible
|
|
83
|
+
outputs, and versioned inputs/outputs. See
|
|
84
|
+
[`docs/research/differentiation.md`](docs/research/differentiation.md) for
|
|
85
|
+
the detailed thesis, and [`docs/research/landscape.md`](docs/research/landscape.md)
|
|
86
|
+
for the ecosystem map that motivated it.
|
|
87
|
+
|
|
88
|
+
Five differentiators in one line each:
|
|
89
|
+
|
|
90
|
+
1. **Trajectories → parameterized capabilities** (not replays, not prompts).
|
|
91
|
+
2. **Verification manufactured, not hand-written** (synthesized from the
|
|
92
|
+
observed state diffs).
|
|
93
|
+
3. **Cross-run element re-anchoring** (semantic refs survive DOM drift).
|
|
94
|
+
4. **Trust data attached to executable artifacts** (fingerprint,
|
|
95
|
+
provenance, evidence-based score, deny-by-default permissions).
|
|
96
|
+
5. **Local-first, offline-complete** (mock provider runs the whole pipeline
|
|
97
|
+
with zero network).
|
|
98
|
+
|
|
99
|
+
## Quick start
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# 1. Install (Python 3.11+; MCP transport included by default)
|
|
103
|
+
pip install capability-compiler # everything except adapters/providers below
|
|
104
|
+
pip install capability-compiler[browser] # add the Playwright adapter
|
|
105
|
+
pip install capability-compiler[models] # add Anthropic / OpenAI / Ollama providers
|
|
106
|
+
|
|
107
|
+
# 2. Verify the install
|
|
108
|
+
cc doctor
|
|
109
|
+
|
|
110
|
+
# 3. Inspect effective configuration
|
|
111
|
+
cc config show
|
|
112
|
+
|
|
113
|
+
# 4. Learn a capability from a local app (fake adapter, no browser needed)
|
|
114
|
+
cc learn "export a pdf" --adapter fake --name export_pdf
|
|
115
|
+
|
|
116
|
+
# 5. Run it through the gate-ordered executor
|
|
117
|
+
cc execute export_pdf --key format=pdf --key file_name=report.pdf
|
|
118
|
+
|
|
119
|
+
# 6. Browse what you have
|
|
120
|
+
cc capabilities
|
|
121
|
+
cc inspect export_pdf
|
|
122
|
+
|
|
123
|
+
# 7. Serve every capability as MCP tools (stdio for editor clients)
|
|
124
|
+
cc serve --transport stdio
|
|
125
|
+
cc serve --transport http --host 127.0.0.1 --port 8765 --token "$CC_MCP_TOKEN"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Every command supports `--json` for machine-readable output. Pass `--verbose`
|
|
129
|
+
(`-v`) at the top level to bump logging to DEBUG; set `CC_DEBUG=1` to print
|
|
130
|
+
full tracebacks instead of structured error messages.
|
|
131
|
+
|
|
132
|
+
### Python quick start
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
import asyncio
|
|
136
|
+
from capability_compiler import Compiler, CompilerSettings, CapabilityRegistry
|
|
137
|
+
|
|
138
|
+
async def main() -> None:
|
|
139
|
+
compiler = Compiler() # offline-safe defaults (mock provider)
|
|
140
|
+
async with compiler: # connect/disconnect bracket
|
|
141
|
+
observation = await compiler.observe()
|
|
142
|
+
report = await compiler.explore(max_steps=20)
|
|
143
|
+
if compiler.exploration and compiler.exploration.trajectories:
|
|
144
|
+
capability = await compiler.synthesize(
|
|
145
|
+
compiler.exploration.trajectories[-1],
|
|
146
|
+
goal_hint="export a pdf",
|
|
147
|
+
)
|
|
148
|
+
registry = CapabilityRegistry.from_settings(CompilerSettings())
|
|
149
|
+
await registry.save(capability)
|
|
150
|
+
result = await compiler.execute(capability, {"format": "pdf"})
|
|
151
|
+
print(result.status.value, result.duration_ms)
|
|
152
|
+
|
|
153
|
+
asyncio.run(main())
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Architecture summary
|
|
157
|
+
|
|
158
|
+
The framework is layered so each phase delivers a coherent unit and each
|
|
159
|
+
later phase builds on a stable contract from the previous one.
|
|
160
|
+
|
|
161
|
+
| Layer | Module | Contract | Notes |
|
|
162
|
+
|---|---|---|---|
|
|
163
|
+
| Domain models | `capability_compiler.models` | Pydantic v2 data contracts | Single source of truth for capabilities, trajectories, actions, observations |
|
|
164
|
+
| Errors | `capability_compiler.errors` | `CapabilityCompilerError` + 9-way `FailureCategory` taxonomy | Every failure classifies exactly once |
|
|
165
|
+
| Logging | `capability_compiler.logging` | Structured JSON or human formatter; secret redaction filter | Never logs API keys, even under odd key names |
|
|
166
|
+
| Config | `capability_compiler.config` | Layered settings (defaults → TOML → `CC_*__*` env) | API keys only ever resolved from env vars |
|
|
167
|
+
| Adapters | `capability_compiler.adapters` | `EnvironmentAdapter` protocol | `fake` (offline), `browser` (Playwright), `desktop` (skeleton) |
|
|
168
|
+
| Providers | `capability_compiler.providers` | `ModelProvider` protocol | `mock`, `ollama`, `anthropic`, `openai`, `openai_compatible` |
|
|
169
|
+
| Recording | `capability_compiler.recording` | `TrajectoryRecorder` + `Replayer` | Every action carries before/after state ids |
|
|
170
|
+
| Perception | `capability_compiler.perception` | `SemanticState` + `StateDiff` (deterministic, no model) | `semantic-v1` fingerprint algorithm |
|
|
171
|
+
| Exploration | `capability_compiler.exploration` | `ExplorationEngine` + `ActionSemanticsEngine` | Effect-first naming; UNKNOWN beats hallucination |
|
|
172
|
+
| Synthesis | `capability_compiler.synthesis` | `CapabilitySynthesizer` | Trajectory → typed, templatized capability |
|
|
173
|
+
| Runtime | `capability_compiler.runtime` | `CapabilityExecutor` (8-gate ordered) | Validate → permissions → confirm → preconditions → procedure → postconditions → record |
|
|
174
|
+
| Verification | `capability_compiler.verification` | 8 verifier kinds (`state`, `dom`, `accessibility`, `file`, `visual`, `schema`, `custom`, `composite`) | Never accepts "exit code 0" as success |
|
|
175
|
+
| Refinement | `capability_compiler.refinement` | `SelfImprovementEngine` + `CapabilityRepairer` | Deterministic repairs promoted only on test-pass |
|
|
176
|
+
| Storage | `capability_compiler.storage` | `CapabilityStore` protocol | `FileCapabilityStore` (atomic writes + integrity check) and `SqliteCapabilityStore` |
|
|
177
|
+
| Registry | `capability_compiler.registry` | `CapabilityRegistry` + `Permission` bitfield | Search, summaries, risk tagging, version-aware rollback |
|
|
178
|
+
| Compiler | `capability_compiler.compiler` | The `Compiler` facade | Wires + supervises — algorithms live in engines |
|
|
179
|
+
| CLI | `capability_compiler.cli` | The `cc` command | `version`, `doctor`, `config`, `capabilities`, `inspect`, `learn`, `execute`, `serve`, `benchmark` |
|
|
180
|
+
| Server | `capability_compiler.server` | MCP transports (`stdio` and streamable `http`) | Bearer-token auth on the HTTP transport |
|
|
181
|
+
|
|
182
|
+
The full overview lives at [`docs/architecture.md`](docs/architecture.md).
|
|
183
|
+
Subsystem deep-dives live in [`docs/architecture/`](docs/architecture/).
|
|
184
|
+
|
|
185
|
+
## Security posture
|
|
186
|
+
|
|
187
|
+
Capability Compiler is **deny-by-default** at every layer:
|
|
188
|
+
|
|
189
|
+
- `security.allow_network` and `security.allow_shell` both default to `false`.
|
|
190
|
+
- `allowed_read_roots` and `allowed_write_roots` default to empty lists
|
|
191
|
+
(filesystem scope is opt-in per capability).
|
|
192
|
+
- The browser adapter blocks navigation to non-loopback URLs unless
|
|
193
|
+
`security.allow_network=true`; failed navigation becomes a structured
|
|
194
|
+
`PERMISSION_DENIED`, never a crash.
|
|
195
|
+
- API keys are referenced by env-var *name* in config; values are resolved at
|
|
196
|
+
call time and never persisted. The logging layer redacts by key name
|
|
197
|
+
(`api_key`, `token`, `secret`, `password`, `authorization`, `cookie`,
|
|
198
|
+
`credential`, `session_id`) and by value pattern (`Bearer …`, `sk-…`,
|
|
199
|
+
`gh[pousr]_…`) as a second line of defense.
|
|
200
|
+
- Destructive capabilities (`permissions.destructive=true` or
|
|
201
|
+
`risk ≥ HIGH`) require explicit user confirmation by default; the CLI
|
|
202
|
+
prompts on a TTY and the executor accepts `confirmed=True` to skip.
|
|
203
|
+
- Capabilities are **pure data** (JSON-serializable Pydantic models).
|
|
204
|
+
Nothing in a stored capability is ever evaluated as code.
|
|
205
|
+
|
|
206
|
+
The complete threat model, scope of promises, and explicit non-goals are in
|
|
207
|
+
[`SECURITY.md`](SECURITY.md). Local-first design choices are explained in
|
|
208
|
+
[`docs/concepts/local-first.md`](docs/concepts/local-first.md).
|
|
209
|
+
|
|
210
|
+
## How to contribute / how to extend
|
|
211
|
+
|
|
212
|
+
Capability Compiler ships pluggable protocols at every cross-cutting
|
|
213
|
+
boundary; subclasses are not required (Protocols are structural).
|
|
214
|
+
|
|
215
|
+
| To add … | Use … |
|
|
216
|
+
|---|---|
|
|
217
|
+
| A new environment (browser, desktop, mobile, CLI) | `register_adapter(kind, factory)` in `capability_compiler.adapters.base` |
|
|
218
|
+
| A new model backend (new vendor, new on-prem) | `register_provider(name, factory)` in `capability_compiler.providers.base` |
|
|
219
|
+
| A new persistence backend (Redis, Postgres, S3) | Implement the `CapabilityStore` protocol in `capability_compiler.storage.base` |
|
|
220
|
+
| A new check on capability outcomes | `register_verifier(kind, factory)` in `capability_compiler.verification.base` |
|
|
221
|
+
| A new CLI command | Append a Typer command module under `src/capability_compiler/cli/` and register it in `main.py` |
|
|
222
|
+
|
|
223
|
+
The differentiation thesis ([`docs/research/differentiation.md`](docs/research/differentiation.md))
|
|
224
|
+
is the source of intent — please read it before opening a feature PR.
|
|
225
|
+
The master plan ([`docs/master-plan.md`](docs/master-plan.md)) defines
|
|
226
|
+
what is in scope and what is not. Development setup, test layout, and CI
|
|
227
|
+
gates are in [`docs/ci.md`](docs/ci.md).
|
|
228
|
+
|
|
229
|
+
## Benchmarks
|
|
230
|
+
|
|
231
|
+
Capability Compiler ships an internal **CapabilityBench** suite used for
|
|
232
|
+
sanity checks and gate reporting. It runs against the in-memory `fake`
|
|
233
|
+
adapter so it never touches the network, a real OS, or a browser. See
|
|
234
|
+
[`docs/benchmarks.md`](docs/benchmarks.md) for what is and isn't measured.
|
|
235
|
+
|
|
236
|
+
## Documentation index
|
|
237
|
+
|
|
238
|
+
- Concepts — [`docs/concepts/exploration.md`](docs/concepts/exploration.md),
|
|
239
|
+
[`docs/concepts/local-first.md`](docs/concepts/local-first.md)
|
|
240
|
+
- Architecture — [`docs/architecture.md`](docs/architecture.md),
|
|
241
|
+
[`docs/architecture/registry.md`](docs/architecture/registry.md),
|
|
242
|
+
[`docs/architecture/mcp.md`](docs/architecture/mcp.md)
|
|
243
|
+
- Adapters — [`docs/adapters/browser.md`](docs/adapters/browser.md)
|
|
244
|
+
- Model providers — [`docs/models.md`](docs/models.md)
|
|
245
|
+
- CLI reference — [`docs/cli/commands.md`](docs/cli/commands.md)
|
|
246
|
+
- Benchmarks — [`docs/benchmarks.md`](docs/benchmarks.md)
|
|
247
|
+
- CI / `cc doctor` — [`docs/ci.md`](docs/ci.md)
|
|
248
|
+
- Research — [`docs/research/landscape.md`](docs/research/landscape.md),
|
|
249
|
+
[`docs/research/differentiation.md`](docs/research/differentiation.md)
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
MIT — see [`LICENSE`](LICENSE).
|
|
254
|
+
|
|
255
|
+
## Acknowledgments
|
|
256
|
+
|
|
257
|
+
Capability Compiler stands on the shoulders of projects whose work the
|
|
258
|
+
[`docs/research/landscape.md`](docs/research/landscape.md) map credits in
|
|
259
|
+
detail. The full production-readiness release was authored by the
|
|
260
|
+
Capability Compiler contributors; see
|
|
261
|
+
[`CHANGELOG.md`](CHANGELOG.md) for what shipped in each phase.
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Capability Compiler
|
|
2
|
+
|
|
3
|
+
> **Turn any software into an API for AI.**
|
|
4
|
+
|
|
5
|
+
Capability Compiler observes black-box software, explores it safely, and
|
|
6
|
+
compiles interaction trajectories into **verified, reusable capabilities** —
|
|
7
|
+
exposed to any LLM through Python APIs, the `cc` CLI, and the Model Context
|
|
8
|
+
Protocol (MCP). Fully local-first: the default configuration runs offline
|
|
9
|
+
with no account and no telemetry.
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
UNKNOWN SOFTWARE ─▶ OBSERVE ─▶ EXPLORE ─▶ COMPILE ─▶ VERIFY ─▶ REUSE
|
|
13
|
+
│
|
|
14
|
+
┌───────────────────────┼───────────────────────┐
|
|
15
|
+
▼ ▼ ▼
|
|
16
|
+
`cc execute` `cc serve` (MCP) Python API
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## What does this do?
|
|
20
|
+
|
|
21
|
+
Capability Compiler records how an application responds to actions, classifies
|
|
22
|
+
those responses with deterministic semantic-state diffs, and turns the result
|
|
23
|
+
into a typed, versioned, permission-scoped **Capability** artifact — a unit
|
|
24
|
+
of reusable software control that any LLM can call via MCP. The output is
|
|
25
|
+
*executable without an LLM in the loop*: it carries inputs, preconditions,
|
|
26
|
+
postconditions, verifiers, and confidence derived from execution evidence.
|
|
27
|
+
|
|
28
|
+
## Why does it exist?
|
|
29
|
+
|
|
30
|
+
Every adjacent project — record/replay tools, GUI-agent libraries, skill
|
|
31
|
+
distributors — stops one or two steps short of the full pipeline. Capability
|
|
32
|
+
Compiler ships the whole pipeline as a **compiler**, with the properties
|
|
33
|
+
compilers have: determinism where possible, typed artifacts, reproducible
|
|
34
|
+
outputs, and versioned inputs/outputs. See
|
|
35
|
+
[`docs/research/differentiation.md`](docs/research/differentiation.md) for
|
|
36
|
+
the detailed thesis, and [`docs/research/landscape.md`](docs/research/landscape.md)
|
|
37
|
+
for the ecosystem map that motivated it.
|
|
38
|
+
|
|
39
|
+
Five differentiators in one line each:
|
|
40
|
+
|
|
41
|
+
1. **Trajectories → parameterized capabilities** (not replays, not prompts).
|
|
42
|
+
2. **Verification manufactured, not hand-written** (synthesized from the
|
|
43
|
+
observed state diffs).
|
|
44
|
+
3. **Cross-run element re-anchoring** (semantic refs survive DOM drift).
|
|
45
|
+
4. **Trust data attached to executable artifacts** (fingerprint,
|
|
46
|
+
provenance, evidence-based score, deny-by-default permissions).
|
|
47
|
+
5. **Local-first, offline-complete** (mock provider runs the whole pipeline
|
|
48
|
+
with zero network).
|
|
49
|
+
|
|
50
|
+
## Quick start
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# 1. Install (Python 3.11+; MCP transport included by default)
|
|
54
|
+
pip install capability-compiler # everything except adapters/providers below
|
|
55
|
+
pip install capability-compiler[browser] # add the Playwright adapter
|
|
56
|
+
pip install capability-compiler[models] # add Anthropic / OpenAI / Ollama providers
|
|
57
|
+
|
|
58
|
+
# 2. Verify the install
|
|
59
|
+
cc doctor
|
|
60
|
+
|
|
61
|
+
# 3. Inspect effective configuration
|
|
62
|
+
cc config show
|
|
63
|
+
|
|
64
|
+
# 4. Learn a capability from a local app (fake adapter, no browser needed)
|
|
65
|
+
cc learn "export a pdf" --adapter fake --name export_pdf
|
|
66
|
+
|
|
67
|
+
# 5. Run it through the gate-ordered executor
|
|
68
|
+
cc execute export_pdf --key format=pdf --key file_name=report.pdf
|
|
69
|
+
|
|
70
|
+
# 6. Browse what you have
|
|
71
|
+
cc capabilities
|
|
72
|
+
cc inspect export_pdf
|
|
73
|
+
|
|
74
|
+
# 7. Serve every capability as MCP tools (stdio for editor clients)
|
|
75
|
+
cc serve --transport stdio
|
|
76
|
+
cc serve --transport http --host 127.0.0.1 --port 8765 --token "$CC_MCP_TOKEN"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Every command supports `--json` for machine-readable output. Pass `--verbose`
|
|
80
|
+
(`-v`) at the top level to bump logging to DEBUG; set `CC_DEBUG=1` to print
|
|
81
|
+
full tracebacks instead of structured error messages.
|
|
82
|
+
|
|
83
|
+
### Python quick start
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
import asyncio
|
|
87
|
+
from capability_compiler import Compiler, CompilerSettings, CapabilityRegistry
|
|
88
|
+
|
|
89
|
+
async def main() -> None:
|
|
90
|
+
compiler = Compiler() # offline-safe defaults (mock provider)
|
|
91
|
+
async with compiler: # connect/disconnect bracket
|
|
92
|
+
observation = await compiler.observe()
|
|
93
|
+
report = await compiler.explore(max_steps=20)
|
|
94
|
+
if compiler.exploration and compiler.exploration.trajectories:
|
|
95
|
+
capability = await compiler.synthesize(
|
|
96
|
+
compiler.exploration.trajectories[-1],
|
|
97
|
+
goal_hint="export a pdf",
|
|
98
|
+
)
|
|
99
|
+
registry = CapabilityRegistry.from_settings(CompilerSettings())
|
|
100
|
+
await registry.save(capability)
|
|
101
|
+
result = await compiler.execute(capability, {"format": "pdf"})
|
|
102
|
+
print(result.status.value, result.duration_ms)
|
|
103
|
+
|
|
104
|
+
asyncio.run(main())
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Architecture summary
|
|
108
|
+
|
|
109
|
+
The framework is layered so each phase delivers a coherent unit and each
|
|
110
|
+
later phase builds on a stable contract from the previous one.
|
|
111
|
+
|
|
112
|
+
| Layer | Module | Contract | Notes |
|
|
113
|
+
|---|---|---|---|
|
|
114
|
+
| Domain models | `capability_compiler.models` | Pydantic v2 data contracts | Single source of truth for capabilities, trajectories, actions, observations |
|
|
115
|
+
| Errors | `capability_compiler.errors` | `CapabilityCompilerError` + 9-way `FailureCategory` taxonomy | Every failure classifies exactly once |
|
|
116
|
+
| Logging | `capability_compiler.logging` | Structured JSON or human formatter; secret redaction filter | Never logs API keys, even under odd key names |
|
|
117
|
+
| Config | `capability_compiler.config` | Layered settings (defaults → TOML → `CC_*__*` env) | API keys only ever resolved from env vars |
|
|
118
|
+
| Adapters | `capability_compiler.adapters` | `EnvironmentAdapter` protocol | `fake` (offline), `browser` (Playwright), `desktop` (skeleton) |
|
|
119
|
+
| Providers | `capability_compiler.providers` | `ModelProvider` protocol | `mock`, `ollama`, `anthropic`, `openai`, `openai_compatible` |
|
|
120
|
+
| Recording | `capability_compiler.recording` | `TrajectoryRecorder` + `Replayer` | Every action carries before/after state ids |
|
|
121
|
+
| Perception | `capability_compiler.perception` | `SemanticState` + `StateDiff` (deterministic, no model) | `semantic-v1` fingerprint algorithm |
|
|
122
|
+
| Exploration | `capability_compiler.exploration` | `ExplorationEngine` + `ActionSemanticsEngine` | Effect-first naming; UNKNOWN beats hallucination |
|
|
123
|
+
| Synthesis | `capability_compiler.synthesis` | `CapabilitySynthesizer` | Trajectory → typed, templatized capability |
|
|
124
|
+
| Runtime | `capability_compiler.runtime` | `CapabilityExecutor` (8-gate ordered) | Validate → permissions → confirm → preconditions → procedure → postconditions → record |
|
|
125
|
+
| Verification | `capability_compiler.verification` | 8 verifier kinds (`state`, `dom`, `accessibility`, `file`, `visual`, `schema`, `custom`, `composite`) | Never accepts "exit code 0" as success |
|
|
126
|
+
| Refinement | `capability_compiler.refinement` | `SelfImprovementEngine` + `CapabilityRepairer` | Deterministic repairs promoted only on test-pass |
|
|
127
|
+
| Storage | `capability_compiler.storage` | `CapabilityStore` protocol | `FileCapabilityStore` (atomic writes + integrity check) and `SqliteCapabilityStore` |
|
|
128
|
+
| Registry | `capability_compiler.registry` | `CapabilityRegistry` + `Permission` bitfield | Search, summaries, risk tagging, version-aware rollback |
|
|
129
|
+
| Compiler | `capability_compiler.compiler` | The `Compiler` facade | Wires + supervises — algorithms live in engines |
|
|
130
|
+
| CLI | `capability_compiler.cli` | The `cc` command | `version`, `doctor`, `config`, `capabilities`, `inspect`, `learn`, `execute`, `serve`, `benchmark` |
|
|
131
|
+
| Server | `capability_compiler.server` | MCP transports (`stdio` and streamable `http`) | Bearer-token auth on the HTTP transport |
|
|
132
|
+
|
|
133
|
+
The full overview lives at [`docs/architecture.md`](docs/architecture.md).
|
|
134
|
+
Subsystem deep-dives live in [`docs/architecture/`](docs/architecture/).
|
|
135
|
+
|
|
136
|
+
## Security posture
|
|
137
|
+
|
|
138
|
+
Capability Compiler is **deny-by-default** at every layer:
|
|
139
|
+
|
|
140
|
+
- `security.allow_network` and `security.allow_shell` both default to `false`.
|
|
141
|
+
- `allowed_read_roots` and `allowed_write_roots` default to empty lists
|
|
142
|
+
(filesystem scope is opt-in per capability).
|
|
143
|
+
- The browser adapter blocks navigation to non-loopback URLs unless
|
|
144
|
+
`security.allow_network=true`; failed navigation becomes a structured
|
|
145
|
+
`PERMISSION_DENIED`, never a crash.
|
|
146
|
+
- API keys are referenced by env-var *name* in config; values are resolved at
|
|
147
|
+
call time and never persisted. The logging layer redacts by key name
|
|
148
|
+
(`api_key`, `token`, `secret`, `password`, `authorization`, `cookie`,
|
|
149
|
+
`credential`, `session_id`) and by value pattern (`Bearer …`, `sk-…`,
|
|
150
|
+
`gh[pousr]_…`) as a second line of defense.
|
|
151
|
+
- Destructive capabilities (`permissions.destructive=true` or
|
|
152
|
+
`risk ≥ HIGH`) require explicit user confirmation by default; the CLI
|
|
153
|
+
prompts on a TTY and the executor accepts `confirmed=True` to skip.
|
|
154
|
+
- Capabilities are **pure data** (JSON-serializable Pydantic models).
|
|
155
|
+
Nothing in a stored capability is ever evaluated as code.
|
|
156
|
+
|
|
157
|
+
The complete threat model, scope of promises, and explicit non-goals are in
|
|
158
|
+
[`SECURITY.md`](SECURITY.md). Local-first design choices are explained in
|
|
159
|
+
[`docs/concepts/local-first.md`](docs/concepts/local-first.md).
|
|
160
|
+
|
|
161
|
+
## How to contribute / how to extend
|
|
162
|
+
|
|
163
|
+
Capability Compiler ships pluggable protocols at every cross-cutting
|
|
164
|
+
boundary; subclasses are not required (Protocols are structural).
|
|
165
|
+
|
|
166
|
+
| To add … | Use … |
|
|
167
|
+
|---|---|
|
|
168
|
+
| A new environment (browser, desktop, mobile, CLI) | `register_adapter(kind, factory)` in `capability_compiler.adapters.base` |
|
|
169
|
+
| A new model backend (new vendor, new on-prem) | `register_provider(name, factory)` in `capability_compiler.providers.base` |
|
|
170
|
+
| A new persistence backend (Redis, Postgres, S3) | Implement the `CapabilityStore` protocol in `capability_compiler.storage.base` |
|
|
171
|
+
| A new check on capability outcomes | `register_verifier(kind, factory)` in `capability_compiler.verification.base` |
|
|
172
|
+
| A new CLI command | Append a Typer command module under `src/capability_compiler/cli/` and register it in `main.py` |
|
|
173
|
+
|
|
174
|
+
The differentiation thesis ([`docs/research/differentiation.md`](docs/research/differentiation.md))
|
|
175
|
+
is the source of intent — please read it before opening a feature PR.
|
|
176
|
+
The master plan ([`docs/master-plan.md`](docs/master-plan.md)) defines
|
|
177
|
+
what is in scope and what is not. Development setup, test layout, and CI
|
|
178
|
+
gates are in [`docs/ci.md`](docs/ci.md).
|
|
179
|
+
|
|
180
|
+
## Benchmarks
|
|
181
|
+
|
|
182
|
+
Capability Compiler ships an internal **CapabilityBench** suite used for
|
|
183
|
+
sanity checks and gate reporting. It runs against the in-memory `fake`
|
|
184
|
+
adapter so it never touches the network, a real OS, or a browser. See
|
|
185
|
+
[`docs/benchmarks.md`](docs/benchmarks.md) for what is and isn't measured.
|
|
186
|
+
|
|
187
|
+
## Documentation index
|
|
188
|
+
|
|
189
|
+
- Concepts — [`docs/concepts/exploration.md`](docs/concepts/exploration.md),
|
|
190
|
+
[`docs/concepts/local-first.md`](docs/concepts/local-first.md)
|
|
191
|
+
- Architecture — [`docs/architecture.md`](docs/architecture.md),
|
|
192
|
+
[`docs/architecture/registry.md`](docs/architecture/registry.md),
|
|
193
|
+
[`docs/architecture/mcp.md`](docs/architecture/mcp.md)
|
|
194
|
+
- Adapters — [`docs/adapters/browser.md`](docs/adapters/browser.md)
|
|
195
|
+
- Model providers — [`docs/models.md`](docs/models.md)
|
|
196
|
+
- CLI reference — [`docs/cli/commands.md`](docs/cli/commands.md)
|
|
197
|
+
- Benchmarks — [`docs/benchmarks.md`](docs/benchmarks.md)
|
|
198
|
+
- CI / `cc doctor` — [`docs/ci.md`](docs/ci.md)
|
|
199
|
+
- Research — [`docs/research/landscape.md`](docs/research/landscape.md),
|
|
200
|
+
[`docs/research/differentiation.md`](docs/research/differentiation.md)
|
|
201
|
+
|
|
202
|
+
## License
|
|
203
|
+
|
|
204
|
+
MIT — see [`LICENSE`](LICENSE).
|
|
205
|
+
|
|
206
|
+
## Acknowledgments
|
|
207
|
+
|
|
208
|
+
Capability Compiler stands on the shoulders of projects whose work the
|
|
209
|
+
[`docs/research/landscape.md`](docs/research/landscape.md) map credits in
|
|
210
|
+
detail. The full production-readiness release was authored by the
|
|
211
|
+
Capability Compiler contributors; see
|
|
212
|
+
[`CHANGELOG.md`](CHANGELOG.md) for what shipped in each phase.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Browser Adapter
|
|
2
|
+
|
|
3
|
+
> Status: **Phase 2 — production-ready for local/loopback targets.**
|
|
4
|
+
> Playwright-based; requires the `browser` extra: `pip install capability-compiler[browser]`
|
|
5
|
+
> then `python -m playwright install chromium`.
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
Wraps Playwright's async API behind the
|
|
10
|
+
[`EnvironmentAdapter`](../architecture.md#extension-points-phase-1-contracts-filled-later)
|
|
11
|
+
protocol:
|
|
12
|
+
|
|
13
|
+
| Verb | Implementation |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `connect(url?)` | launch browser + context + page, navigate, remember start URL |
|
|
16
|
+
| `observe(screenshot=True)` | one normalized `Observation` (see below) |
|
|
17
|
+
| `execute(action)` | map domain action → Playwright call via semantic target resolution |
|
|
18
|
+
| `reset()` | best-effort return to the start URL |
|
|
19
|
+
| `resolve_target(target)` | `ActionTarget` → Playwright `Locator` |
|
|
20
|
+
|
|
21
|
+
## Observation composition
|
|
22
|
+
|
|
23
|
+
- **Accessibility tree** — `page.aria_snapshot()` YAML parsed into
|
|
24
|
+
`AccessibilityNode` (parser validated byte-exact against Playwright 1.62
|
|
25
|
+
output; the legacy `page.accessibility` API is gone in current Playwright).
|
|
26
|
+
Used for state identity *inspection*, exploration, and repair — **not**
|
|
27
|
+
fingerprinted (Chromium updates its a11y tree asynchronously; that race
|
|
28
|
+
made fingerprints nondeterministic — pinned by tests).
|
|
29
|
+
- **Interactive elements** — an in-page read-only scan (roles, best-effort
|
|
30
|
+
accessible names, values, visibility, enabledness, bounding boxes) with
|
|
31
|
+
stable positional ids `e1..eN` in document order.
|
|
32
|
+
- **Structure** — URL, title, DOM hash (diagnostics only), and a
|
|
33
|
+
whitespace-normalized **visible-text digest** (the deterministic content
|
|
34
|
+
identity that catches non-interactive changes the element scan cannot
|
|
35
|
+
see).
|
|
36
|
+
- **Screenshot** — content-hashed artifact written under the storage
|
|
37
|
+
artifacts dir; large images stay on disk, small ones inline base64.
|
|
38
|
+
|
|
39
|
+
## Target resolution order (drift-resilient by construction)
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
ref (element id from an observation)
|
|
43
|
+
→ role + name + ordinal among identical role+name matches
|
|
44
|
+
→ explicit target.role / target.name
|
|
45
|
+
→ CSS/XPath selector
|
|
46
|
+
→ coordinates (last resort, recorded for debugging)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
When a `ref` misses the cached observation (first action after navigation,
|
|
50
|
+
stale page), the adapter re-observes once and retries — the seed of the
|
|
51
|
+
Phase-6 re-anchoring mechanism. Strict-mode ambiguity is preserved:
|
|
52
|
+
duplicate `role+name` elements are disambiguated by recorded ordinal, not by
|
|
53
|
+
guessing.
|
|
54
|
+
|
|
55
|
+
## Security
|
|
56
|
+
|
|
57
|
+
- **Navigation policy** (`url_allowed`): `file:`/`data:`/`about:`/`blob:` and
|
|
58
|
+
loopback hosts are always allowed; **any other host requires
|
|
59
|
+
`security.allow_network = true`** (default false). Failed navigation is a
|
|
60
|
+
`PERMISSION_DENIED` action result, never a crash.
|
|
61
|
+
- Page content is untrusted data. The scan is read-only; nothing from the
|
|
62
|
+
page is ever evaluated as code.
|
|
63
|
+
- Screenshots may contain injected-instruction text; downstream model
|
|
64
|
+
consumers must treat them as data (enforced by provider prompt design).
|
|
65
|
+
|
|
66
|
+
## Determinism notes (hard-won)
|
|
67
|
+
|
|
68
|
+
| Source of instability | Resolution |
|
|
69
|
+
|---|---|
|
|
70
|
+
| a11y tree async updates | excluded from fingerprint |
|
|
71
|
+
| `page.content()` attribute placement | DOM hash diagnostics-only; visible-text digest instead |
|
|
72
|
+
| duplicate-named elements | ordinal disambiguation from scan order |
|
|
73
|
+
| replay after navigation | ref-miss → re-observe → retry once |
|
|
74
|
+
|
|
75
|
+
All four are pinned by tests (`test_e2e_record_replay.py`,
|
|
76
|
+
`test_browser_adapter.py`).
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from capability_compiler import CompilerSettings
|
|
82
|
+
from capability_compiler.adapters import create_adapter
|
|
83
|
+
|
|
84
|
+
settings = CompilerSettings()
|
|
85
|
+
adapter = create_adapter("browser", settings)
|
|
86
|
+
await adapter.connect("file:///path/to/app.html")
|
|
87
|
+
observation = await adapter.observe()
|
|
88
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Architecture — subsystem index
|
|
2
|
+
|
|
3
|
+
> Detailed design notes for the cross-cutting subsystems of Capability Compiler.
|
|
4
|
+
> The top-level architecture overview is in [`../architecture.md`](../architecture.md);
|
|
5
|
+
> these files go deeper on registry, MCP, and the rationale behind them.
|
|
6
|
+
|
|
7
|
+
| Subsystem | Document |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Capability registry | [`registry.md`](registry.md) — backends, search, summaries, permissions, authorization |
|
|
10
|
+
| MCP integration | [`mcp.md`](mcp.md) — transports, tool + result schema, authentication |
|
|
11
|
+
| Local-first design | [`../concepts/local-first.md`](../concepts/local-first.md) |
|
|
12
|
+
| Exploration pipeline | [`../concepts/exploration.md`](../concepts/exploration.md) |
|
|
13
|
+
|
|
14
|
+
The implementation follows the eight-phase plan in
|
|
15
|
+
[`../master-plan.md`](../master-plan.md). Every subsystem module ships with
|
|
16
|
+
its own docstring describing the contract; the docs here narrate *why* and
|
|
17
|
+
*how* the contracts compose into the framework.
|