envknit 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.
Files changed (127) hide show
  1. envknit-0.1.0/.github/workflows/build-cli.yml +158 -0
  2. envknit-0.1.0/.github/workflows/publish-python.yml +34 -0
  3. envknit-0.1.0/.github/workflows/test.yml +36 -0
  4. envknit-0.1.0/.gitignore +86 -0
  5. envknit-0.1.0/CHANGELOG.md +74 -0
  6. envknit-0.1.0/Cargo.toml +3 -0
  7. envknit-0.1.0/DESIGN_NOTES.md +579 -0
  8. envknit-0.1.0/PKG-INFO +119 -0
  9. envknit-0.1.0/README.md +80 -0
  10. envknit-0.1.0/crates/envknit-cli/.gitignore +1 -0
  11. envknit-0.1.0/crates/envknit-cli/Cargo.toml +38 -0
  12. envknit-0.1.0/crates/envknit-cli/src/backends/conda.rs +33 -0
  13. envknit-0.1.0/crates/envknit-cli/src/backends/mod.rs +37 -0
  14. envknit-0.1.0/crates/envknit-cli/src/backends/pip.rs +36 -0
  15. envknit-0.1.0/crates/envknit-cli/src/backends/poetry.rs +33 -0
  16. envknit-0.1.0/crates/envknit-cli/src/cli.rs +215 -0
  17. envknit-0.1.0/crates/envknit-cli/src/commands/add.rs +106 -0
  18. envknit-0.1.0/crates/envknit-cli/src/commands/check.rs +196 -0
  19. envknit-0.1.0/crates/envknit-cli/src/commands/completions.rs +11 -0
  20. envknit-0.1.0/crates/envknit-cli/src/commands/diff.rs +193 -0
  21. envknit-0.1.0/crates/envknit-cli/src/commands/doctor.rs +279 -0
  22. envknit-0.1.0/crates/envknit-cli/src/commands/env_create.rs +97 -0
  23. envknit-0.1.0/crates/envknit-cli/src/commands/env_list.rs +34 -0
  24. envknit-0.1.0/crates/envknit-cli/src/commands/env_remove.rs +78 -0
  25. envknit-0.1.0/crates/envknit-cli/src/commands/export.rs +139 -0
  26. envknit-0.1.0/crates/envknit-cli/src/commands/graph.rs +168 -0
  27. envknit-0.1.0/crates/envknit-cli/src/commands/init.rs +82 -0
  28. envknit-0.1.0/crates/envknit-cli/src/commands/init_shell.rs +107 -0
  29. envknit-0.1.0/crates/envknit-cli/src/commands/install.rs +247 -0
  30. envknit-0.1.0/crates/envknit-cli/src/commands/lock.rs +136 -0
  31. envknit-0.1.0/crates/envknit-cli/src/commands/mod.rs +63 -0
  32. envknit-0.1.0/crates/envknit-cli/src/commands/pin.rs +164 -0
  33. envknit-0.1.0/crates/envknit-cli/src/commands/publish.rs +137 -0
  34. envknit-0.1.0/crates/envknit-cli/src/commands/remove.rs +100 -0
  35. envknit-0.1.0/crates/envknit-cli/src/commands/run.rs +115 -0
  36. envknit-0.1.0/crates/envknit-cli/src/commands/status.rs +68 -0
  37. envknit-0.1.0/crates/envknit-cli/src/commands/store.rs +293 -0
  38. envknit-0.1.0/crates/envknit-cli/src/commands/tree.rs +47 -0
  39. envknit-0.1.0/crates/envknit-cli/src/commands/upgrade.rs +218 -0
  40. envknit-0.1.0/crates/envknit-cli/src/commands/verify.rs +90 -0
  41. envknit-0.1.0/crates/envknit-cli/src/commands/why.rs +64 -0
  42. envknit-0.1.0/crates/envknit-cli/src/config.rs +259 -0
  43. envknit-0.1.0/crates/envknit-cli/src/error.rs +15 -0
  44. envknit-0.1.0/crates/envknit-cli/src/global_config.rs +176 -0
  45. envknit-0.1.0/crates/envknit-cli/src/lib.rs +15 -0
  46. envknit-0.1.0/crates/envknit-cli/src/lockfile.rs +173 -0
  47. envknit-0.1.0/crates/envknit-cli/src/main.rs +9 -0
  48. envknit-0.1.0/crates/envknit-cli/src/node_resolver.rs +273 -0
  49. envknit-0.1.0/crates/envknit-cli/src/python_resolver.rs +252 -0
  50. envknit-0.1.0/crates/envknit-cli/src/resolver.rs +611 -0
  51. envknit-0.1.0/crates/envknit-cli/tests/integration.rs +364 -0
  52. envknit-0.1.0/docs/INSTALLATION-CONSIDERATIONS.md +218 -0
  53. envknit-0.1.0/docs/guide/ci.md +189 -0
  54. envknit-0.1.0/docs/guide/cli-scripts.md +240 -0
  55. envknit-0.1.0/docs/guide/concepts.md +225 -0
  56. envknit-0.1.0/docs/guide/environments.md +302 -0
  57. envknit-0.1.0/docs/guide/getting-started.md +284 -0
  58. envknit-0.1.0/docs/guide/node-version.md +275 -0
  59. envknit-0.1.0/docs/guide/python-api.md +348 -0
  60. envknit-0.1.0/docs/guide/python-version.md +220 -0
  61. envknit-0.1.0/docs/plans/2026-03-03-nodejs-v3-design.md +137 -0
  62. envknit-0.1.0/docs/plans/2026-03-03-nodejs-v3.md +895 -0
  63. envknit-0.1.0/docs/reference/cli.md +580 -0
  64. envknit-0.1.0/docs/reference/config-schema.md +151 -0
  65. envknit-0.1.0/docs/reference/lock-schema.md +228 -0
  66. envknit-0.1.0/envknit-cli.spec +171 -0
  67. envknit-0.1.0/poc/demo.py +156 -0
  68. envknit-0.1.0/poc/fake_packages/mylib_v1/mylib/__init__.py +13 -0
  69. envknit-0.1.0/poc/fake_packages/mylib_v2/mylib/__init__.py +13 -0
  70. envknit-0.1.0/poc/versioned_import.py +253 -0
  71. envknit-0.1.0/pyproject.toml +122 -0
  72. envknit-0.1.0/schemas/envknit-config.schema.json +56 -0
  73. envknit-0.1.0/schemas/envknit-lock.schema.json +62 -0
  74. envknit-0.1.0/scripts/build-cli.sh +116 -0
  75. envknit-0.1.0/src/envknit/__init__.py +77 -0
  76. envknit-0.1.0/src/envknit/__main__.py +22 -0
  77. envknit-0.1.0/src/envknit/ai/__init__.py +26 -0
  78. envknit-0.1.0/src/envknit/ai/context.py +792 -0
  79. envknit-0.1.0/src/envknit/backends/__init__.py +52 -0
  80. envknit-0.1.0/src/envknit/backends/base.py +168 -0
  81. envknit-0.1.0/src/envknit/backends/conda.py +796 -0
  82. envknit-0.1.0/src/envknit/backends/pip.py +586 -0
  83. envknit-0.1.0/src/envknit/backends/poetry.py +797 -0
  84. envknit-0.1.0/src/envknit/cli/__init__.py +13 -0
  85. envknit-0.1.0/src/envknit/cli/main.py +98 -0
  86. envknit-0.1.0/src/envknit/config/__init__.py +13 -0
  87. envknit-0.1.0/src/envknit/config/schema.py +212 -0
  88. envknit-0.1.0/src/envknit/core/__init__.py +58 -0
  89. envknit-0.1.0/src/envknit/core/graph.py +264 -0
  90. envknit-0.1.0/src/envknit/core/lock.py +1173 -0
  91. envknit-0.1.0/src/envknit/core/resolver.py +810 -0
  92. envknit-0.1.0/src/envknit/isolation/__init__.py +75 -0
  93. envknit-0.1.0/src/envknit/isolation/import_hook.py +1321 -0
  94. envknit-0.1.0/src/envknit/isolation/shim.py +874 -0
  95. envknit-0.1.0/src/envknit/isolation/worker.py +499 -0
  96. envknit-0.1.0/src/envknit/security/__init__.py +22 -0
  97. envknit-0.1.0/src/envknit/security/models.py +308 -0
  98. envknit-0.1.0/src/envknit/security/scanner.py +648 -0
  99. envknit-0.1.0/src/envknit/storage/__init__.py +28 -0
  100. envknit-0.1.0/src/envknit/storage/cache.py +457 -0
  101. envknit-0.1.0/src/envknit/storage/store.py +721 -0
  102. envknit-0.1.0/src/envknit/utils/__init__.py +13 -0
  103. envknit-0.1.0/src/envknit/utils/version.py +80 -0
  104. envknit-0.1.0/test_ai_context.py +933 -0
  105. envknit-0.1.0/tests/__init__.py +5 -0
  106. envknit-0.1.0/tests/conftest.py +77 -0
  107. envknit-0.1.0/tests/test_ai_context.py +933 -0
  108. envknit-0.1.0/tests/test_backends.py +1876 -0
  109. envknit-0.1.0/tests/test_cli.py +1673 -0
  110. envknit-0.1.0/tests/test_config_schema.py +277 -0
  111. envknit-0.1.0/tests/test_configure_from_lock.py +457 -0
  112. envknit-0.1.0/tests/test_graph.py +327 -0
  113. envknit-0.1.0/tests/test_import_hook.py +1599 -0
  114. envknit-0.1.0/tests/test_lock.py +709 -0
  115. envknit-0.1.0/tests/test_resolver.py +594 -0
  116. envknit-0.1.0/tests/test_security.py +702 -0
  117. envknit-0.1.0/tests/test_shim.py +505 -0
  118. envknit-0.1.0/tests/test_storage.py +1093 -0
  119. envknit-0.1.0/tests/test_version.py +143 -0
  120. envknit-0.1.0/tests/test_worker.py +595 -0
  121. envknit-0.1.0/tests/test_worker_integration.py +359 -0
  122. envknit-0.1.0/vscode-extension/README.md +30 -0
  123. envknit-0.1.0/vscode-extension/package.json +57 -0
  124. envknit-0.1.0/vscode-extension/schemas/envknit-config.schema.json +56 -0
  125. envknit-0.1.0/vscode-extension/schemas/envknit-lock.schema.json +62 -0
  126. envknit-0.1.0/vscode-extension/src/extension.ts +109 -0
  127. envknit-0.1.0/vscode-extension/tsconfig.json +14 -0
@@ -0,0 +1,158 @@
1
+ name: Build CLI Binary
2
+
3
+ # Triggers:
4
+ # push/PR to main — build for smoke testing
5
+ # tag push vX.Y.Z — build and upload to GitHub Release
6
+ on:
7
+ push:
8
+ branches: [main]
9
+ tags: ["v*.*.*"]
10
+ pull_request:
11
+ branches: [main]
12
+
13
+ jobs:
14
+ test-rust:
15
+ name: Test Rust CLI
16
+ runs-on: ubuntu-latest
17
+
18
+ steps:
19
+ - name: Checkout
20
+ uses: actions/checkout@v6
21
+
22
+ - name: Install Rust toolchain
23
+ uses: dtolnay/rust-toolchain@stable
24
+
25
+ - name: Cache Cargo registry and build
26
+ uses: actions/cache@v5
27
+ with:
28
+ path: |
29
+ ~/.cargo/registry
30
+ ~/.cargo/git
31
+ target/
32
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
33
+ restore-keys: ${{ runner.os }}-cargo-
34
+
35
+ - name: Run tests
36
+ run: cargo test --manifest-path crates/envknit-cli/Cargo.toml
37
+
38
+ build-rust:
39
+ name: Build Rust CLI (${{ matrix.os }})
40
+ needs: test-rust
41
+ runs-on: ${{ matrix.os }}
42
+ strategy:
43
+ fail-fast: false
44
+ matrix:
45
+ include:
46
+ # Linux amd64 (glibc)
47
+ - os: ubuntu-latest
48
+ target: x86_64-unknown-linux-gnu
49
+ artifact_name: envknit-linux-amd64
50
+ binary_path: target/x86_64-unknown-linux-gnu/release/envknit
51
+ # Linux amd64 (musl — portable, no glibc dep)
52
+ - os: ubuntu-latest
53
+ target: x86_64-unknown-linux-musl
54
+ artifact_name: envknit-linux-amd64-musl
55
+ binary_path: target/x86_64-unknown-linux-musl/release/envknit
56
+ # macOS amd64
57
+ - os: macos-latest
58
+ target: x86_64-apple-darwin
59
+ artifact_name: envknit-macos-amd64
60
+ binary_path: target/x86_64-apple-darwin/release/envknit
61
+ # macOS arm64 (Apple Silicon)
62
+ - os: macos-latest
63
+ target: aarch64-apple-darwin
64
+ artifact_name: envknit-macos-arm64
65
+ binary_path: target/aarch64-apple-darwin/release/envknit
66
+ # Windows amd64
67
+ - os: windows-latest
68
+ target: x86_64-pc-windows-msvc
69
+ artifact_name: envknit-windows-amd64.exe
70
+ binary_path: target/x86_64-pc-windows-msvc/release/envknit.exe
71
+
72
+ steps:
73
+ - name: Checkout
74
+ uses: actions/checkout@v6
75
+
76
+ - name: Install Rust toolchain
77
+ uses: dtolnay/rust-toolchain@stable
78
+
79
+ - name: Cache Cargo registry and build
80
+ uses: actions/cache@v5
81
+ with:
82
+ path: |
83
+ ~/.cargo/registry
84
+ ~/.cargo/git
85
+ target/
86
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
87
+ restore-keys: ${{ runner.os }}-cargo-
88
+
89
+ - name: Install musl tools (Ubuntu / musl target)
90
+ if: matrix.target == 'x86_64-unknown-linux-musl'
91
+ run: |
92
+ sudo apt-get install -y musl-tools
93
+ rustup target add x86_64-unknown-linux-musl
94
+
95
+ - name: Add macOS cross-compile targets
96
+ if: runner.os == 'macOS'
97
+ run: |
98
+ rustup target add aarch64-apple-darwin
99
+ rustup target add x86_64-apple-darwin
100
+
101
+ - name: Build release binary
102
+ run: >
103
+ cargo build --release
104
+ --manifest-path crates/envknit-cli/Cargo.toml
105
+ --target ${{ matrix.target }}
106
+
107
+ - name: Smoke test (native Linux/macOS)
108
+ if: runner.os != 'Windows' && matrix.target != 'aarch64-apple-darwin' && matrix.target != 'x86_64-apple-darwin'
109
+ run: |
110
+ "${{ matrix.binary_path }}" --version
111
+ "${{ matrix.binary_path }}" --help
112
+
113
+ - name: Smoke test (Windows)
114
+ if: runner.os == 'Windows'
115
+ shell: pwsh
116
+ run: |
117
+ & "${{ matrix.binary_path }}" --version
118
+ & "${{ matrix.binary_path }}" --help
119
+
120
+ - name: Rename artifact
121
+ shell: bash
122
+ run: cp "${{ matrix.binary_path }}" "${{ matrix.artifact_name }}"
123
+
124
+ - name: Upload artifact
125
+ uses: actions/upload-artifact@v7
126
+ with:
127
+ name: ${{ matrix.artifact_name }}
128
+ path: ${{ matrix.artifact_name }}
129
+ retention-days: 7
130
+
131
+ # ── Release upload ──────────────────────────────────────────────────────────
132
+ # Only runs on version tag pushes (e.g., v1.0.0)
133
+ release:
134
+ name: Upload to GitHub Release
135
+ needs: [build-rust]
136
+ runs-on: ubuntu-latest
137
+ if: startsWith(github.ref, 'refs/tags/v')
138
+
139
+ permissions:
140
+ contents: write
141
+
142
+ steps:
143
+ - name: Download all artifacts
144
+ uses: actions/download-artifact@v8
145
+ with:
146
+ path: artifacts/
147
+
148
+ - name: Upload binaries to release
149
+ uses: softprops/action-gh-release@v2
150
+ with:
151
+ files: |
152
+ artifacts/envknit-linux-amd64/envknit-linux-amd64
153
+ artifacts/envknit-linux-amd64-musl/envknit-linux-amd64-musl
154
+ artifacts/envknit-macos-amd64/envknit-macos-amd64
155
+ artifacts/envknit-macos-arm64/envknit-macos-arm64
156
+ artifacts/envknit-windows-amd64.exe/envknit-windows-amd64.exe
157
+ draft: false
158
+ generate_release_notes: true
@@ -0,0 +1,34 @@
1
+ name: Publish Python Library
2
+
3
+ # Publishes the `envknit` Python package to PyPI on version tag pushes.
4
+ # Requires PYPI_TOKEN secret to be set in repository settings.
5
+ on:
6
+ push:
7
+ tags: ["v*.*.*"]
8
+
9
+ jobs:
10
+ publish:
11
+ name: Build and publish to PyPI
12
+ runs-on: ubuntu-latest
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ steps:
18
+ - uses: actions/checkout@v6
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.11"
24
+
25
+ - name: Install build tools
26
+ run: pip install build
27
+
28
+ - name: Build distribution
29
+ run: python -m build
30
+
31
+ - name: Publish to PyPI
32
+ uses: pypa/gh-action-pypi-publish@release/v1
33
+ with:
34
+ password: ${{ secrets.PYPI_TOKEN }}
@@ -0,0 +1,36 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v6
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Install dependencies
25
+ run: pip install -e ".[dev,cli]"
26
+
27
+ - name: Run tests
28
+ run: pytest --tb=short -q
29
+
30
+ - name: Upload coverage report
31
+ if: matrix.python-version == '3.11'
32
+ uses: actions/upload-artifact@v7
33
+ with:
34
+ name: coverage-report
35
+ path: htmlcov/
36
+ if-no-files-found: ignore
@@ -0,0 +1,86 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # PyInstaller — ignore generated artifacts but keep the committed spec file
28
+ *.manifest
29
+ # *.spec intentionally NOT ignored — envknit-cli.spec is committed source
30
+
31
+ # Installer logs
32
+ pip-log.txt
33
+ pip-delete-this-directory.txt
34
+
35
+ # Unit test / coverage reports
36
+ htmlcov/
37
+ .tox/
38
+ .nox/
39
+ .coverage
40
+ .coverage.*
41
+ .cache
42
+ nosetests.xml
43
+ coverage.xml
44
+ *.cover
45
+ *.py,cover
46
+ .hypothesis/
47
+ .pytest_cache/
48
+
49
+ # Translations
50
+ *.mo
51
+ *.pot
52
+
53
+ # Environments
54
+ .env
55
+ .venv
56
+ env/
57
+ venv/
58
+ ENV/
59
+ env.bak/
60
+ venv.bak/
61
+
62
+ # IDE
63
+ .idea/
64
+ .vscode/
65
+ *.swp
66
+ *.swo
67
+ *~
68
+
69
+ # OS
70
+ .DS_Store
71
+ Thumbs.db
72
+
73
+ # Project specific
74
+ .envknit/
75
+ envknit-lock.yaml
76
+ *.lock
77
+
78
+ # mypy
79
+ .mypy_cache/
80
+ .dmypy.json
81
+ dmypy.json
82
+
83
+ # ruff
84
+ .ruff_cache/
85
+ .claude/
86
+ /target/
@@ -0,0 +1,74 @@
1
+ # Changelog
2
+
3
+ All notable changes to EnvKnit are documented here.
4
+
5
+ ---
6
+
7
+ ## [0.1.0] — 2026-02-27
8
+
9
+ ### Added
10
+
11
+ #### Core architecture
12
+ - **Split CLI/library architecture**: `envknit-cli` (standalone binary) and `envknit` (pip library) communicate only through `envknit.lock.yaml` — no shared Python environment
13
+ - **PubGrub dependency resolver** with transitive dependency resolution enabled by default, semantic conflict detection (not just syntactic), and cache invalidation on backtrack
14
+ - **Lock file contract** (`envknit.lock.yaml`): `schema_version` gate, `install_path` field per package, schema forward-compatibility check (`SchemaVersionError` for future major versions)
15
+
16
+ #### Runtime import isolation
17
+ - **`VersionedFinder`** — `sys.meta_path` hook that routes `import` to versioned install paths
18
+ - **`VersionContext`** — context manager implementing per-context module isolation via `ContextVar` (`_active_versions`, `_ctx_modules`); async-safe and thread-safe
19
+ - **`_CachedModuleLoader` + `_CtxCachingLoader`** — fast-path cache for repeated imports within the same context; modules are cached on first load
20
+ - **`configure_from_lock()`** — loads `envknit.lock.yaml`, registers all versioned install paths, auto-installs import hook; supports `env` filter and deduplication
21
+
22
+ #### Hybrid C extension detection
23
+ - **`_has_c_extensions(path)`** — scans install path for `.so`/`.pyd` files; process-global cache (`_c_ext_detection_cache`)
24
+ - **`CExtensionError(ImportError)`** — raised by `use()` when C extensions detected; message includes ready-to-use `worker()` snippet
25
+ - Pure-Python packages use `use()` transparently; C extension packages require `worker()`
26
+
27
+ #### Subprocess worker pool
28
+ - **`worker()`** context manager — routes C extension packages through isolated subprocesses
29
+ - **`ProcessPool`** — lazy spawn, health checks, graceful SIGTERM → SIGKILL shutdown, `atexit` handler for zombie/SharedMemory cleanup
30
+ - **`WorkerContext`** — IPC over `multiprocessing.Pipe`; large arrays via `multiprocessing.shared_memory`
31
+
32
+ #### CLI (`envknit-cli`)
33
+ - Commands: `init`, `add`, `resolve`, `lock`, `install`, `status`, `tree`, `graph`, `why`, `remove`, `run`, `env`, `store`, `shim`, `init-shell`, `auto`, `export`, `security`, `activate`, `deactivate`
34
+ - Backends: **conda** (conda/mamba search), **pip** (`pip index versions` + PyPI JSON API fallback), **poetry** (PyPI JSON API)
35
+ - `--dry-run` for `resolve`; `--update <pkg>` for `lock`
36
+
37
+ #### Standalone binary distribution
38
+ - **PyInstaller spec** (`envknit-cli.spec`) — single-file binary bundling click, rich, pyyaml, and all EnvKnit internals
39
+ - **Build script** (`scripts/build-cli.sh`) — `--clean`, `--strip`, `--upx` flags; ~29 MB output
40
+ - **CI workflow** (`.github/workflows/build-cli.yml`) — builds linux/macos/windows artifacts on `v*.*.*` tag push; uploads to GitHub Release
41
+
42
+ #### Security scanning
43
+ - **`VulnerabilityScanner`** — `scan_package()`, `scan_all()`, `check_updates()`
44
+ - **`PipAuditBackend`** (preferred) — wraps `pip-audit` CLI, batch scan via stdin
45
+ - **`PyPIAPIBackend`** (fallback) — OSV API + PyPI JSON API; CVSS → LOW/MEDIUM/HIGH/CRITICAL mapping
46
+ - Result cache: SHA-256 key, 1-hour TTL, disk + memory layers
47
+
48
+ #### AI context export
49
+ - **`AIContextGenerator`** — analyzes `Config` + `LockFile` to produce `AIContext` with dependency summaries, issue detection, and recommendations
50
+ - Export formats: Markdown (LLM-ready), `requirements.txt`, conda `environment.yml`, JSON
51
+
52
+ #### Shim system
53
+ - **`ShimGenerator`** — generates Python `__init__.py` shims that redirect imports to versioned install paths
54
+ - **`CLIShimGenerator`** — generates executable shim scripts for CLI tools (conda, pip, python, etc.)
55
+ - **`ShellIntegration`** — installs `eval "$(envknit init-shell)"` blocks into `.bashrc`/`.zshrc`/`config.fish`; idempotent install/uninstall
56
+ - **`ToolDispatcher`** — resolves correct tool path from lock file at runtime, dispatches subprocess
57
+
58
+ ### Infrastructure
59
+ - **CI test workflow** (`.github/workflows/test.yml`) — runs `pytest` on Python 3.10–3.13 matrix on push/PR to `main`
60
+ - `.gitignore` updated to exclude `.claude/` worktree and session cache
61
+
62
+ ### Tests
63
+ - **474 tests** across 17 test files
64
+ - Coverage: `ai/context.py` 100%, `config/schema.py` 100%, `security/models.py` 97%, `security/scanner.py` 84%, `storage/cache.py` 90%, `storage/store.py` 66%, `resolver.py` 87%, `lock.py` 82%, `worker.py` 75%, `shim.py` ~55%, overall **51%**
65
+
66
+ ---
67
+
68
+ ## [Unreleased]
69
+
70
+ ### Known limitations
71
+ - `isolation/shim.py` 19% → 55% (partial; env management methods require real backend)
72
+ - `cli/main.py` 20% → 30% (partial; install/lock commands require real backend)
73
+ - C extension in-process multi-version loading permanently impossible; subprocess worker is the only viable path (see `DESIGN_NOTES.md` #5)
74
+ - `VersionContext` Category B limitations (global registries, retained references) are fundamental to the Python process model; subprocess isolation required for affected packages (see `DESIGN_NOTES.md` #6)
@@ -0,0 +1,3 @@
1
+ [workspace]
2
+ members = ["crates/envknit-cli"]
3
+ resolver = "2"