dekk 1.0.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 (109) hide show
  1. dekk-1.0.0/.gitignore +65 -0
  2. dekk-1.0.0/CHANGELOG.md +14 -0
  3. dekk-1.0.0/CONTRIBUTING.md +3 -0
  4. dekk-1.0.0/LICENSE +21 -0
  5. dekk-1.0.0/PKG-INFO +531 -0
  6. dekk-1.0.0/README.md +480 -0
  7. dekk-1.0.0/docs/architecture.md +209 -0
  8. dekk-1.0.0/docs/cheatsheet.md +234 -0
  9. dekk-1.0.0/docs/contributing.md +88 -0
  10. dekk-1.0.0/docs/examples-by-language.md +303 -0
  11. dekk-1.0.0/docs/getting-started.md +324 -0
  12. dekk-1.0.0/docs/index.md +39 -0
  13. dekk-1.0.0/docs/spec.md +311 -0
  14. dekk-1.0.0/docs/wrapper.md +195 -0
  15. dekk-1.0.0/examples/.dekk.toml.conda +18 -0
  16. dekk-1.0.0/examples/.dekk.toml.minimal +7 -0
  17. dekk-1.0.0/examples/.dekk.toml.quickstart +15 -0
  18. dekk-1.0.0/examples/README.md +62 -0
  19. dekk-1.0.0/pyproject.toml +129 -0
  20. dekk-1.0.0/src/dekk/__init__.py +174 -0
  21. dekk-1.0.0/src/dekk/__main__.py +7 -0
  22. dekk-1.0.0/src/dekk/_compat.py +57 -0
  23. dekk-1.0.0/src/dekk/activation.py +126 -0
  24. dekk-1.0.0/src/dekk/build.py +888 -0
  25. dekk-1.0.0/src/dekk/cache.py +267 -0
  26. dekk-1.0.0/src/dekk/ci.py +719 -0
  27. dekk-1.0.0/src/dekk/cli/__init__.py +39 -0
  28. dekk-1.0.0/src/dekk/cli/commands.py +362 -0
  29. dekk-1.0.0/src/dekk/cli/config.py +244 -0
  30. dekk-1.0.0/src/dekk/cli/errors.py +178 -0
  31. dekk-1.0.0/src/dekk/cli/main.py +208 -0
  32. dekk-1.0.0/src/dekk/cli/output.py +232 -0
  33. dekk-1.0.0/src/dekk/cli/progress.py +53 -0
  34. dekk-1.0.0/src/dekk/cli/runner.py +96 -0
  35. dekk-1.0.0/src/dekk/cli/styles.py +205 -0
  36. dekk-1.0.0/src/dekk/cli_commands.py +117 -0
  37. dekk-1.0.0/src/dekk/commands.py +336 -0
  38. dekk-1.0.0/src/dekk/compiler.py +291 -0
  39. dekk-1.0.0/src/dekk/conda.py +292 -0
  40. dekk-1.0.0/src/dekk/config.py +205 -0
  41. dekk-1.0.0/src/dekk/context.py +928 -0
  42. dekk-1.0.0/src/dekk/dekk_os.py +257 -0
  43. dekk-1.0.0/src/dekk/deps.py +200 -0
  44. dekk-1.0.0/src/dekk/detect.py +201 -0
  45. dekk-1.0.0/src/dekk/diagnostic.py +285 -0
  46. dekk-1.0.0/src/dekk/diagnostic_checks.py +219 -0
  47. dekk-1.0.0/src/dekk/env.py +157 -0
  48. dekk-1.0.0/src/dekk/envspec.py +163 -0
  49. dekk-1.0.0/src/dekk/install.py +348 -0
  50. dekk-1.0.0/src/dekk/libpath.py +221 -0
  51. dekk-1.0.0/src/dekk/lockfile.py +632 -0
  52. dekk-1.0.0/src/dekk/py.typed +1 -0
  53. dekk-1.0.0/src/dekk/remediate.py +165 -0
  54. dekk-1.0.0/src/dekk/runner.py +226 -0
  55. dekk-1.0.0/src/dekk/scaffold.py +947 -0
  56. dekk-1.0.0/src/dekk/shell.py +1028 -0
  57. dekk-1.0.0/src/dekk/templates/conda.toml +18 -0
  58. dekk-1.0.0/src/dekk/templates/minimal.toml +7 -0
  59. dekk-1.0.0/src/dekk/templates/quickstart.toml +15 -0
  60. dekk-1.0.0/src/dekk/test_runner.py +179 -0
  61. dekk-1.0.0/src/dekk/toolchain.py +216 -0
  62. dekk-1.0.0/src/dekk/typer_app.py +367 -0
  63. dekk-1.0.0/src/dekk/validate.py +302 -0
  64. dekk-1.0.0/src/dekk/validation_cache.py +87 -0
  65. dekk-1.0.0/src/dekk/version.py +424 -0
  66. dekk-1.0.0/src/dekk/version_managers.py +432 -0
  67. dekk-1.0.0/src/dekk/workspace.py +934 -0
  68. dekk-1.0.0/src/dekk/wrapper.py +550 -0
  69. dekk-1.0.0/tests/__init__.py +1 -0
  70. dekk-1.0.0/tests/cli/__init__.py +0 -0
  71. dekk-1.0.0/tests/cli/conftest.py +118 -0
  72. dekk-1.0.0/tests/cli/test_config.py +169 -0
  73. dekk-1.0.0/tests/cli/test_errors.py +306 -0
  74. dekk-1.0.0/tests/cli/test_output.py +394 -0
  75. dekk-1.0.0/tests/cli/test_progress.py +76 -0
  76. dekk-1.0.0/tests/cli/test_runner.py +309 -0
  77. dekk-1.0.0/tests/cli/test_styles.py +365 -0
  78. dekk-1.0.0/tests/test_build.py +568 -0
  79. dekk-1.0.0/tests/test_cache.py +357 -0
  80. dekk-1.0.0/tests/test_ci.py +466 -0
  81. dekk-1.0.0/tests/test_ci_build.py +176 -0
  82. dekk-1.0.0/tests/test_cli_commands.py +486 -0
  83. dekk-1.0.0/tests/test_cli_main.py +174 -0
  84. dekk-1.0.0/tests/test_cli_templates.py +24 -0
  85. dekk-1.0.0/tests/test_commands.py +446 -0
  86. dekk-1.0.0/tests/test_compiler.py +178 -0
  87. dekk-1.0.0/tests/test_conda.py +377 -0
  88. dekk-1.0.0/tests/test_config.py +507 -0
  89. dekk-1.0.0/tests/test_context.py +435 -0
  90. dekk-1.0.0/tests/test_dekk_os.py +13 -0
  91. dekk-1.0.0/tests/test_deps.py +57 -0
  92. dekk-1.0.0/tests/test_detect.py +38 -0
  93. dekk-1.0.0/tests/test_diagnostic.py +447 -0
  94. dekk-1.0.0/tests/test_env.py +350 -0
  95. dekk-1.0.0/tests/test_install.py +38 -0
  96. dekk-1.0.0/tests/test_libpath.py +470 -0
  97. dekk-1.0.0/tests/test_lockfile.py +435 -0
  98. dekk-1.0.0/tests/test_main_module.py +34 -0
  99. dekk-1.0.0/tests/test_runner.py +38 -0
  100. dekk-1.0.0/tests/test_scaffold.py +258 -0
  101. dekk-1.0.0/tests/test_shell.py +497 -0
  102. dekk-1.0.0/tests/test_test_runner.py +50 -0
  103. dekk-1.0.0/tests/test_toolchain.py +474 -0
  104. dekk-1.0.0/tests/test_typer_app.py +394 -0
  105. dekk-1.0.0/tests/test_validate.py +646 -0
  106. dekk-1.0.0/tests/test_version.py +404 -0
  107. dekk-1.0.0/tests/test_version_managers.py +210 -0
  108. dekk-1.0.0/tests/test_workspace.py +608 -0
  109. dekk-1.0.0/tests/test_wrapper.py +719 -0
dekk-1.0.0/.gitignore ADDED
@@ -0,0 +1,65 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ venv/
25
+ env/
26
+ ENV/
27
+ .venv
28
+
29
+ # Testing
30
+ .pytest_cache/
31
+ .coverage
32
+ .coverage.*
33
+ htmlcov/
34
+ .tox/
35
+ .nox/
36
+
37
+ # IDEs
38
+ .vscode/
39
+ .idea/
40
+ *.swp
41
+ *.swo
42
+ *~
43
+
44
+ # OS
45
+ .DS_Store
46
+ Thumbs.db
47
+
48
+ # Environment / local config
49
+ .env
50
+ .env.*
51
+ .env.local
52
+
53
+ # Documentation
54
+ docs/_build/
55
+
56
+ # mypy
57
+ .mypy_cache/
58
+ .dmypy.json
59
+ dmypy.json
60
+
61
+ # Ruff
62
+ .ruff_cache/
63
+
64
+ # Agent / IDE worktrees
65
+ .claude/
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ All notable changes to `dekk` will be documented in this file.
4
+
5
+ ## 1.0.0 - 2026-03-19
6
+
7
+ First public `dekk` release.
8
+
9
+ - Renamed the published distribution to `dekk`.
10
+ - Renamed the Python import package to `dekk`.
11
+ - Renamed the default config file to `.dekk.toml`.
12
+ - Standardized the console entrypoint as `dekk`.
13
+ - Cleaned up repository metadata, developer docs, and packaging surfaces for reuse.
14
+ - Added CI coverage for linting, typing, tests, and package builds.
@@ -0,0 +1,3 @@
1
+ # Contributing
2
+
3
+ Development and release instructions live in [docs/contributing.md](docs/contributing.md).
dekk-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Randres Herrera
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.
dekk-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,531 @@
1
+ Metadata-Version: 2.4
2
+ Name: dekk
3
+ Version: 1.0.0
4
+ Summary: Reusable environment detection, activation, and wrapper tooling for developer CLIs.
5
+ Project-URL: Homepage, https://github.com/randreshg/dekk
6
+ Project-URL: Documentation, https://github.com/randreshg/dekk/tree/main/docs
7
+ Project-URL: Repository, https://github.com/randreshg/dekk
8
+ Project-URL: Issues, https://github.com/randreshg/dekk/issues
9
+ Project-URL: Changelog, https://github.com/randreshg/dekk/blob/main/CHANGELOG.md
10
+ Author-email: Randres Herrera <randres2011@gmail.com>
11
+ Maintainer-email: Randres Herrera <randres2011@gmail.com>
12
+ License: MIT
13
+ License-File: LICENSE
14
+ Keywords: cli,conda,detection,developer-tools,environment,toolchain,workspace
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Environment :: Console
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: MacOS
20
+ Classifier: Operating System :: Microsoft :: Windows
21
+ Classifier: Operating System :: POSIX :: Linux
22
+ Classifier: Programming Language :: Python :: 3
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.12
26
+ Classifier: Programming Language :: Python :: 3.13
27
+ Classifier: Topic :: Software Development :: Build Tools
28
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
29
+ Classifier: Topic :: System :: Systems Administration
30
+ Classifier: Topic :: Utilities
31
+ Classifier: Typing :: Typed
32
+ Requires-Python: >=3.10
33
+ Requires-Dist: pyyaml>=6.0
34
+ Requires-Dist: rich>=13.0.0
35
+ Requires-Dist: tomli-w>=1.0.0
36
+ Requires-Dist: tomli>=2.0.0; python_version < '3.11'
37
+ Requires-Dist: typer>=0.9.0
38
+ Provides-Extra: all
39
+ Requires-Dist: tully>=0.1.0; extra == 'all'
40
+ Provides-Extra: dev
41
+ Requires-Dist: build>=1.2.1; extra == 'dev'
42
+ Requires-Dist: mypy>=1.8; extra == 'dev'
43
+ Requires-Dist: pytest-cov>=4.1; extra == 'dev'
44
+ Requires-Dist: pytest-mock>=3.12; extra == 'dev'
45
+ Requires-Dist: pytest>=8.0; extra == 'dev'
46
+ Requires-Dist: ruff>=0.2; extra == 'dev'
47
+ Requires-Dist: twine>=5.0.0; extra == 'dev'
48
+ Provides-Extra: tracking
49
+ Requires-Dist: tully>=0.1.0; extra == 'tracking'
50
+ Description-Content-Type: text/markdown
51
+
52
+ # dekk
53
+
54
+ **Make project CLIs runnable with one config and zero manual activation.**
55
+
56
+ dekk turns project setup into a reusable runtime layer. Declare the
57
+ environment once in `.dekk.toml`, then use `dekk` to detect tools,
58
+ activate the environment, install wrappers, and make project commands
59
+ work on fresh machines without hand-written setup steps.
60
+
61
+ ## Install And Start
62
+
63
+ Recommended for end users:
64
+
65
+ ```bash
66
+ pipx install dekk
67
+ ```
68
+
69
+ Fallback if you already manage Python packages directly:
70
+
71
+ ```bash
72
+ python -m pip install --upgrade dekk
73
+ ```
74
+
75
+ After installation:
76
+
77
+ - Use `dekk` for the CLI.
78
+ - Use `python -m dekk` as a fallback if your scripts directory is not on `PATH` yet.
79
+
80
+ ## The Problem
81
+
82
+ Every project needs environment setup: conda environments, PATH entries,
83
+ environment variables, tool versions. Developers manually activate things.
84
+ AI agents waste thousands of tokens describing setup steps. CI pipelines
85
+ duplicate configuration.
86
+
87
+ ## The Solution
88
+
89
+ Declare your environment once in `.dekk.toml`. dekk handles detection,
90
+ activation, wrapper generation, and installed command setup from that
91
+ single source of truth.
92
+
93
+ ```toml
94
+ [project]
95
+ name = "myapp"
96
+
97
+ [conda]
98
+ name = "myapp"
99
+ file = "environment.yaml"
100
+
101
+ [tools]
102
+ python = { command = "python", version = ">=3.10" }
103
+ cmake = { command = "cmake", version = ">=3.20" }
104
+ cargo = { command = "cargo" }
105
+
106
+ [env]
107
+ MLIR_DIR = "{conda}/lib/cmake/mlir"
108
+
109
+ [paths]
110
+ bin = ["{project}/bin"]
111
+ ```
112
+
113
+ ## Three Pillars
114
+
115
+ ### 1. Detect
116
+
117
+ Zero-dependency detection of your entire development environment:
118
+
119
+ - **Platform**: OS, architecture, Linux distro, WSL, containers
120
+ - **Package managers**: conda/mamba, with environment validation
121
+ - **Build systems**: 25+ (Cargo, CMake, npm, Poetry, Maven, Gradle, ...)
122
+ - **Compilers**: GCC, Clang, Rust, Go with versions and targets
123
+ - **CI providers**: 14 (GitHub Actions, GitLab CI, Jenkins, ...)
124
+ - **Shells**: 9 types (bash, zsh, fish, tcsh, PowerShell, ...)
125
+ - **Workspaces**: Monorepo detection with dependency graphs
126
+
127
+ ```python
128
+ from dekk import PlatformDetector, CondaDetector, BuildSystemDetector
129
+
130
+ platform = PlatformDetector().detect()
131
+ # PlatformInfo(os='Linux', arch='x86_64', distro='ubuntu', ...)
132
+
133
+ conda = CondaDetector().find_environment("myenv")
134
+ # CondaEnvironment(name='myenv', prefix=Path('/opt/conda/envs/myenv'))
135
+
136
+ builds = BuildSystemDetector().detect(Path("."))
137
+ # [BuildSystemInfo(system=BuildSystem.CARGO, root=Path("."), ...)]
138
+ ```
139
+
140
+ ### 2. Activate
141
+
142
+ Read `.dekk.toml`, resolve conda paths, set environment variables, validate tools:
143
+
144
+ ```python
145
+ from dekk import EnvironmentActivator
146
+
147
+ activator = EnvironmentActivator.from_cwd()
148
+ result = activator.activate()
149
+ # ActivationResult(env_vars={'CONDA_PREFIX': '...', 'MLIR_DIR': '...'}, ...)
150
+ ```
151
+
152
+ Or from the CLI:
153
+ ```
154
+ $ eval "$(dekk activate --shell bash)"
155
+ ```
156
+
157
+ On Windows PowerShell:
158
+ ```powershell
159
+ PS> Invoke-Expression (& dekk activate --shell powershell | Out-String)
160
+ ```
161
+
162
+ ### 3. Wrap
163
+
164
+ Generate a self-contained launcher that bakes in the full environment.
165
+ **This is what makes dekk zero-friction.**
166
+
167
+ ```
168
+ $ dekk wrap myapp ./bin/myapp
169
+ Generated myapp -> ~/.local/bin/myapp
170
+
171
+ $ myapp doctor # just works -- no activation needed
172
+ ```
173
+
174
+ On POSIX, the wrapper is a simple shell script with hardcoded paths:
175
+ ```sh
176
+ #!/bin/sh
177
+ export CONDA_PREFIX="/home/user/miniforge3/envs/myapp"
178
+ export PATH="/home/user/miniforge3/envs/myapp/bin:$PATH"
179
+ export MLIR_DIR="/home/user/miniforge3/envs/myapp/lib/cmake/mlir"
180
+ exec "/home/user/miniforge3/envs/myapp/bin/python3" \
181
+ "/home/user/projects/myapp/tools/cli.py" "$@"
182
+ ```
183
+
184
+ On Windows, dekk installs a `.cmd` launcher in Python's user scripts
185
+ directory (the `Scripts` directory under `python -m site --user-base`) so the
186
+ command works from both Command Prompt and PowerShell without requiring
187
+ `Activate.ps1`.
188
+
189
+ From Python:
190
+ ```python
191
+ from dekk import WrapperGenerator
192
+
193
+ result = WrapperGenerator.install_from_spec(
194
+ spec_file=Path(".dekk.toml"),
195
+ target=Path("tools/cli.py"),
196
+ python=Path("/opt/conda/envs/myapp/bin/python3"),
197
+ name="myapp",
198
+ )
199
+ ```
200
+
201
+ ## Installation
202
+
203
+ ```bash
204
+ pipx install dekk
205
+ python -m pip install --upgrade dekk
206
+ python -m pip install --upgrade "dekk[tracking]"
207
+ python -m pip install --upgrade "dekk[all]"
208
+ ```
209
+
210
+ ## First Run
211
+
212
+ The default path should be simple:
213
+
214
+ ```bash
215
+ dekk --help
216
+ dekk doctor
217
+ dekk init --example quickstart
218
+ ```
219
+
220
+ That gives you a working CLI immediately, a system check, and a starter
221
+ `.dekk.toml` in the current directory.
222
+
223
+ If `dekk` is not found yet, your scripts directory is probably not on `PATH`.
224
+ Use `python -m dekk --help` immediately, then add the user scripts
225
+ directory reported by `python -m site --user-base` to `PATH`.
226
+
227
+ If you want a built-in starter without writing files yet:
228
+
229
+ ```bash
230
+ dekk example quickstart
231
+ dekk example conda --output .dekk.toml
232
+ ```
233
+
234
+ Built-in templates live in
235
+ [examples/.dekk.toml.quickstart](examples/.dekk.toml.quickstart),
236
+ [examples/.dekk.toml.minimal](examples/.dekk.toml.minimal),
237
+ and [examples/.dekk.toml.conda](examples/.dekk.toml.conda).
238
+
239
+ Typical next steps:
240
+
241
+ ```bash
242
+ # Python CLI from a repo with pyproject.toml
243
+ dekk install ./tools/cli.py
244
+
245
+ # POSIX shells
246
+ eval "$(dekk activate --shell bash)"
247
+
248
+ # Install a launcher after your project builds a target
249
+ dekk install ./bin/myapp --name myapp
250
+ ```
251
+
252
+ For Python scripts, `dekk install ./tools/cli.py` uses `pyproject.toml` to
253
+ create or refresh `.venv` automatically on first run. For binaries and
254
+ conda-backed projects, `dekk install` uses `.dekk.toml` to bake the
255
+ required environment into the installed command.
256
+
257
+ ```powershell
258
+ # PowerShell
259
+ Invoke-Expression (& dekk activate --shell powershell | Out-String)
260
+ dekk install .\dist\myapp.exe --name myapp
261
+ ```
262
+
263
+ ## Naming Conventions
264
+
265
+ dekk uses one name per surface area:
266
+
267
+ - **PyPI package**: `dekk`
268
+ - **Python import**: `dekk`
269
+ - **CLI command**: `dekk`
270
+ - **Project config file**: `.dekk.toml`
271
+ - **Default wrapper location**: the Python user scripts directory on the current platform
272
+
273
+ That keeps installation, imports, command usage, and project setup distinct and predictable.
274
+
275
+ ## CLI Framework
276
+
277
+ dekk includes a production-quality CLI framework built on Rich and Typer.
278
+ Use it as the foundation for your own CLI tools:
279
+
280
+ ```python
281
+ from dekk import Typer, Option
282
+
283
+ app = Typer(
284
+ name="myapp",
285
+ auto_activate=True, # auto-setup from .dekk.toml
286
+ add_doctor_command=True, # built-in health check
287
+ add_version_command=True, # built-in version info
288
+ )
289
+
290
+ @app.command()
291
+ def build(release: bool = Option(True, "--release/--debug")):
292
+ """Build the project."""
293
+ ...
294
+
295
+ if __name__ == "__main__":
296
+ app()
297
+ ```
298
+
299
+ ### Styled output
300
+
301
+ ```python
302
+ from dekk import print_success, print_error, print_warning, print_info
303
+ from dekk import print_header, print_step, print_table
304
+
305
+ print_header("Building MyApp")
306
+ print_step("Compiling...")
307
+ print_success("Build complete!")
308
+ print_warning("Debug symbols not stripped")
309
+ ```
310
+
311
+ ### Progress indicators
312
+
313
+ ```python
314
+ from dekk import spinner, progress_bar
315
+
316
+ with spinner("Installing dependencies..."):
317
+ install_deps()
318
+
319
+ with progress_bar("Processing", total=100) as bar:
320
+ for item in items:
321
+ process(item)
322
+ bar.advance()
323
+ ```
324
+
325
+ ### Structured errors
326
+
327
+ ```python
328
+ from dekk import NotFoundError, DependencyError
329
+
330
+ raise NotFoundError(
331
+ "Compiler not found",
332
+ hint="Install the required toolchain for this project",
333
+ )
334
+ # Displays styled error with hint, exits with code 3
335
+ ```
336
+
337
+ ### Multi-format output
338
+
339
+ ```python
340
+ from dekk import OutputFormatter, OutputFormat
341
+
342
+ fmt = OutputFormatter(format=OutputFormat.JSON)
343
+ fmt.print_result({"status": "ok", "version": "1.0"})
344
+ ```
345
+
346
+ ### LLM-friendly subprocess runner
347
+
348
+ ```python
349
+ from dekk import run_logged
350
+
351
+ result = run_logged(
352
+ ["cargo", "build", "--release"],
353
+ log_path=Path(".logs/build.log"),
354
+ spinner_text="Building...",
355
+ )
356
+ # Shows spinner, captures output to log, prints path for agents to read
357
+ ```
358
+
359
+ ## .dekk.toml Reference
360
+
361
+ ### [project] -- required
362
+
363
+ ```toml
364
+ [project]
365
+ name = "myapp"
366
+ description = "Optional description"
367
+ ```
368
+
369
+ ### [conda] -- conda/mamba environment
370
+
371
+ ```toml
372
+ [conda]
373
+ name = "myapp"
374
+ file = "environment.yaml"
375
+ ```
376
+
377
+ ### [tools] -- required CLI tools
378
+
379
+ ```toml
380
+ [tools]
381
+ python = { command = "python", version = ">=3.10" }
382
+ cmake = { command = "cmake", version = ">=3.20" }
383
+ ninja = { command = "ninja" }
384
+ cargo = { command = "cargo", optional = true }
385
+ ```
386
+
387
+ ### [env] -- environment variables
388
+
389
+ ```toml
390
+ [env]
391
+ MLIR_DIR = "{conda}/lib/cmake/mlir"
392
+ LLVM_DIR = "{conda}/lib/cmake/llvm"
393
+ MY_HOME = "{project}"
394
+ ```
395
+
396
+ Placeholders: `{project}` (project root), `{conda}` (conda prefix), `{home}` (user home)
397
+
398
+ ### [paths] -- PATH prepends
399
+
400
+ ```toml
401
+ [paths]
402
+ bin = ["{project}/bin", "{project}/target/release"]
403
+ ```
404
+
405
+ ## Examples by Language
406
+
407
+ ### Python + Conda
408
+ ```toml
409
+ [project]
410
+ name = "ml-pipeline"
411
+
412
+ [conda]
413
+ name = "ml-pipeline"
414
+ file = "environment.yaml"
415
+
416
+ [tools]
417
+ python = { command = "python", version = ">=3.10" }
418
+ jupyter = { command = "jupyter" }
419
+
420
+ [env]
421
+ PYTHONPATH = "{project}/src"
422
+ ```
423
+
424
+ ### Rust
425
+ ```toml
426
+ [project]
427
+ name = "my-rust-app"
428
+
429
+ [tools]
430
+ cargo = { command = "cargo", version = ">=1.70" }
431
+ rustc = { command = "rustc" }
432
+
433
+ [paths]
434
+ bin = ["{project}/target/release"]
435
+ ```
436
+
437
+ ### C++ with CMake
438
+ ```toml
439
+ [project]
440
+ name = "physics-sim"
441
+
442
+ [conda]
443
+ name = "physics-sim"
444
+ file = "environment.yaml"
445
+
446
+ [tools]
447
+ cmake = { command = "cmake", version = ">=3.20" }
448
+ ninja = { command = "ninja" }
449
+ clang = { command = "clang", version = ">=17" }
450
+
451
+ [env]
452
+ CMAKE_PREFIX_PATH = "{conda}"
453
+ ```
454
+
455
+ ### Node.js
456
+ ```toml
457
+ [project]
458
+ name = "web-app"
459
+
460
+ [tools]
461
+ node = { command = "node", version = ">=18" }
462
+ npm = { command = "npm" }
463
+
464
+ [env]
465
+ NODE_ENV = "development"
466
+ ```
467
+
468
+ ### Go
469
+ ```toml
470
+ [project]
471
+ name = "api-server"
472
+
473
+ [tools]
474
+ go = { command = "go", version = ">=1.21" }
475
+
476
+ [env]
477
+ GOPATH = "{home}/go"
478
+
479
+ [paths]
480
+ bin = ["{home}/go/bin"]
481
+ ```
482
+
483
+ ## For AI Agents
484
+
485
+ dekk reduces environment setup from 2000-5000 tokens to ~150 tokens:
486
+
487
+ **Before** (what agents had to explain):
488
+ > Check if conda is installed. If not, install miniforge. Create environment
489
+ > with `conda env create -f environment.yaml`. Activate with `conda activate
490
+ > myenv`. Set MLIR_DIR to the conda prefix. Export LD_LIBRARY_PATH...
491
+
492
+ **After**:
493
+ > Run `myapp install`. The wrapper handles everything.
494
+
495
+ ## Detection API Summary
496
+
497
+ | Module | What it detects |
498
+ |--------|----------------|
499
+ | `PlatformDetector` | OS, arch, distro, WSL, containers, package manager |
500
+ | `CondaDetector` | Conda/mamba environments, packages, validation |
501
+ | `BuildSystemDetector` | 25+ build systems with targets and workspaces |
502
+ | `CompilerDetector` | GCC, Clang, Rust, Go with versions and targets |
503
+ | `CIDetector` | 14 CI providers with git metadata and runner info |
504
+ | `ShellDetector` | 9 shell types with config files and capabilities |
505
+ | `WorkspaceDetector` | Monorepos with dependency graphs and build order |
506
+ | `DependencyChecker` | CLI tool versions against constraints |
507
+ | `VersionManagerDetector` | pyenv, nvm, asdf, rbenv, rustup |
508
+ | `LockfileParser` | 7 lockfile formats across ecosystems |
509
+
510
+ ## Architecture
511
+
512
+ dekk is organized in three tiers:
513
+
514
+ - **Tier 1 (Core)**: Foundational detection and config modules. Platform, conda, deps, workspace, config, remediation.
515
+ - **Tier 2 (Extended)**: Paths, build systems, compilers, shells, toolchains, versions, CI.
516
+ - **Tier 3 (Frameworks)**: Diagnostics, commands, scaffolding.
517
+
518
+ The CLI framework ships in the base `dekk` install.
519
+
520
+ ## Documentation
521
+
522
+ - [Getting Started](docs/getting-started.md)
523
+ - [Architecture](docs/architecture.md)
524
+ - [.dekk.toml Specification](docs/spec.md)
525
+ - [Wrapper Generation](docs/wrapper.md)
526
+ - [Examples by Language](docs/examples-by-language.md)
527
+ - [Contributing](docs/contributing.md)
528
+
529
+ ## License
530
+
531
+ MIT