archcheck 0.26.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 (60) hide show
  1. archcheck-0.26.0/LICENSE +21 -0
  2. archcheck-0.26.0/PKG-INFO +172 -0
  3. archcheck-0.26.0/README.md +147 -0
  4. archcheck-0.26.0/pyproject.toml +41 -0
  5. archcheck-0.26.0/setup.cfg +4 -0
  6. archcheck-0.26.0/src/archcheck/__init__.py +4 -0
  7. archcheck-0.26.0/src/archcheck/__main__.py +6 -0
  8. archcheck-0.26.0/src/archcheck/analyzer.py +379 -0
  9. archcheck-0.26.0/src/archcheck/architecture_config.py +154 -0
  10. archcheck-0.26.0/src/archcheck/ast_facts.py +2601 -0
  11. archcheck-0.26.0/src/archcheck/cli.py +287 -0
  12. archcheck-0.26.0/src/archcheck/compile_commands.py +300 -0
  13. archcheck-0.26.0/src/archcheck/concurrency.py +573 -0
  14. archcheck-0.26.0/src/archcheck/contracts.py +219 -0
  15. archcheck-0.26.0/src/archcheck/data_dependencies.py +171 -0
  16. archcheck-0.26.0/src/archcheck/dependency.py +208 -0
  17. archcheck-0.26.0/src/archcheck/dependency_order.py +440 -0
  18. archcheck-0.26.0/src/archcheck/dsm_cluster.py +257 -0
  19. archcheck-0.26.0/src/archcheck/file_metrics.py +89 -0
  20. archcheck-0.26.0/src/archcheck/framework_rules.py +701 -0
  21. archcheck-0.26.0/src/archcheck/gui.py +332 -0
  22. archcheck-0.26.0/src/archcheck/image_facts.py +458 -0
  23. archcheck-0.26.0/src/archcheck/indirection.py +611 -0
  24. archcheck-0.26.0/src/archcheck/keil.py +6 -0
  25. archcheck-0.26.0/src/archcheck/literals.py +54 -0
  26. archcheck-0.26.0/src/archcheck/macro_facts.py +158 -0
  27. archcheck-0.26.0/src/archcheck/model.py +1449 -0
  28. archcheck-0.26.0/src/archcheck/parallel.py +140 -0
  29. archcheck-0.26.0/src/archcheck/path_pruning.py +359 -0
  30. archcheck-0.26.0/src/archcheck/paths.py +33 -0
  31. archcheck-0.26.0/src/archcheck/profiles/generic/heuristics.yaml +31 -0
  32. archcheck-0.26.0/src/archcheck/profiles/mcu/cortex-m-cmsis.yaml +28 -0
  33. archcheck-0.26.0/src/archcheck/profiles/mcu/gd32f30x.yaml +17 -0
  34. archcheck-0.26.0/src/archcheck/profiles/mcu/stm32-hal.yaml +23 -0
  35. archcheck-0.26.0/src/archcheck/profiles/platform/arduino-esp32.yaml +40 -0
  36. archcheck-0.26.0/src/archcheck/profiles/platform/esp-idf.yaml +54 -0
  37. archcheck-0.26.0/src/archcheck/profiles/rtos/cmsis-rtos2.yaml +57 -0
  38. archcheck-0.26.0/src/archcheck/profiles/rtos/freertos.yaml +123 -0
  39. archcheck-0.26.0/src/archcheck/profiles/rtos/posix.yaml +37 -0
  40. archcheck-0.26.0/src/archcheck/profiles/rtos/protothreads.yaml +43 -0
  41. archcheck-0.26.0/src/archcheck/profiles/rtos/zephyr.yaml +61 -0
  42. archcheck-0.26.0/src/archcheck/report.py +219 -0
  43. archcheck-0.26.0/src/archcheck/runtime_units.py +595 -0
  44. archcheck-0.26.0/src/archcheck/semantic.py +2729 -0
  45. archcheck-0.26.0/src/archcheck/templates/report.html +908 -0
  46. archcheck-0.26.0/src/archcheck/time_base.py +291 -0
  47. archcheck-0.26.0/src/archcheck/toolchains/__init__.py +6 -0
  48. archcheck-0.26.0/src/archcheck/toolchains/keil.py +521 -0
  49. archcheck-0.26.0/src/archcheck/yield_locals.py +114 -0
  50. archcheck-0.26.0/src/archcheck.egg-info/PKG-INFO +172 -0
  51. archcheck-0.26.0/src/archcheck.egg-info/SOURCES.txt +58 -0
  52. archcheck-0.26.0/src/archcheck.egg-info/dependency_links.txt +1 -0
  53. archcheck-0.26.0/src/archcheck.egg-info/entry_points.txt +3 -0
  54. archcheck-0.26.0/src/archcheck.egg-info/requires.txt +1 -0
  55. archcheck-0.26.0/src/archcheck.egg-info/top_level.txt +1 -0
  56. archcheck-0.26.0/tests/test_compile_commands.py +154 -0
  57. archcheck-0.26.0/tests/test_data_dependencies.py +87 -0
  58. archcheck-0.26.0/tests/test_enums.py +82 -0
  59. archcheck-0.26.0/tests/test_literals.py +96 -0
  60. archcheck-0.26.0/tests/test_task_priority.py +141 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SHAR-K
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,172 @@
1
+ Metadata-Version: 2.4
2
+ Name: archcheck
3
+ Version: 0.26.0
4
+ Summary: Architecture recovery for C/C++ firmware: entries, tasks, interrupts, shared state and timing as deterministic code facts
5
+ Author: SHAR-K
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/SHAR-K/ArchX
8
+ Project-URL: Demo, https://shar-k.github.io/ArchX/
9
+ Project-URL: Issues, https://github.com/SHAR-K/ArchX/issues
10
+ Keywords: embedded,firmware,architecture-recovery,c,cpp,rtos,freertos,clangd,mcp
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: C
17
+ Classifier: Programming Language :: C++
18
+ Classifier: Topic :: Software Development :: Embedded Systems
19
+ Classifier: Topic :: Software Development :: Quality Assurance
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: PyYAML<7,>=6.0
24
+ Dynamic: license-file
25
+
26
+ # ArchCheck
27
+
28
+ Architecture recovery for C/C++ firmware: ArchCheck reads the source and recovers its **runtime structure** — entry
29
+ points, tasks, ISRs, callbacks, loops, state machines, shared state and concurrency
30
+ boundaries — without running the program, attaching a probe, or calling an LLM.
31
+
32
+ Every finding carries a file, a line and a confidence level. Anything that cannot be
33
+ derived from the source and a rule is reported as unknown, never guessed.
34
+
35
+ ```bash
36
+ pip install archcheck
37
+ archcheck path/to/project --out report/ # or let an agent run it: see the repository README
38
+ ```
39
+
40
+ [Repository](https://github.com/SHAR-K/ArchX) · [Field contract](https://github.com/SHAR-K/ArchX/blob/main/docs/SCHEMA.md) · [Usage](https://github.com/SHAR-K/ArchX/blob/main/docs/USAGE.md) · [Status & known limits](https://github.com/SHAR-K/ArchX/blob/main/docs/ARCHCHECK_STATUS.md) · [Live demo](https://shar-k.github.io/ArchX/)
41
+
42
+ ## Why
43
+
44
+ To see how a firmware actually runs, the standard answer is a runtime tracer:
45
+ instrument the build, flash it, capture a trace. That tells you what the system
46
+ **did**. ArchCheck answers a different question, and it answers it before you have
47
+ a working build to trace:
48
+
49
+ > **What does the code say it will do?**
50
+
51
+ | | Requires | Answers |
52
+ | --- | --- | --- |
53
+ | Percepio Tracealyzer | TraceRecorder instrumentation, a running system | what the system did |
54
+ | Segger SystemView | J-Link probe + instrumentation | what the system did |
55
+ | **ArchCheck** | **a compilation database** | **what the code says it will do** |
56
+
57
+ Useful when you inherit firmware nobody can explain any more, when you want the
58
+ interrupt/task sharing map before a refactor, or when you want an architecture
59
+ check in CI that fails on a new cross-layer call.
60
+
61
+ ## If you can build it, ArchCheck can read it
62
+
63
+ - `compile_commands.json` (CMake, ESP-IDF, Zephyr, Makefile + bear), **or** a Keil
64
+ `.uvprojx` — ArchCheck generates a compatible database from the Keil project itself
65
+ - `clangd` on `PATH` (the AST layer is built on its LSP)
66
+ - Python 3.10+
67
+
68
+ That is the entire prerequisite list. There is no agent to install, no code to
69
+ annotate, and nothing is uploaded anywhere.
70
+
71
+ ## Quick start
72
+
73
+ ```bash
74
+ git clone https://github.com/SHAR-K/archcheck
75
+ cd archcheck && pip install -e .
76
+
77
+ # a CMake / ESP-IDF / Zephyr project
78
+ archcheck /path/to/firmware
79
+
80
+ # a Keil project (pass --keil-target when the project has several targets)
81
+ archcheck /path/to/firmware --keil-project MDK-ARM/app.uvprojx
82
+ ```
83
+
84
+ **Point it at your own firmware.** Three minutes later you have your startup chain,
85
+ your interrupt vectors, and the variables your ISRs share with your tasks — with
86
+ line numbers. That is a better demo than any screenshot here.
87
+
88
+ Output lands in `<project>/.arch-report`: `architecture.json` (the facts),
89
+ `metrics.json`, a Markdown summary, and a single self-contained `report.html`.
90
+
91
+ ## What comes out
92
+
93
+ - **Entry points and startup chain** — `main`, reset handler, `*_init` call chain
94
+ - **Runtime units** — tasks, ISRs, callbacks (including callbacks registered through
95
+ initializer tables, struct fields and function-pointer parameters), each with its
96
+ registration site
97
+ - **Run modes** — periodic / busy-poll / event-driven / one-shot, with the blocking
98
+ call and the period that implies it
99
+ - **Loops** — bounds where they can be derived, and unbounded busy-waits flagged
100
+ - **State machine candidates** — `switch` dispatch variables, states and transitions
101
+ - **Shared state and conflict candidates** — which variables are reached by more than
102
+ one runtime unit, which accesses sit outside a recognised critical section
103
+ - **Image facts** — code/RO/RW/ZI per module from an `armlink` map, kept as a separate
104
+ evidence source from the source-derived facts
105
+ - **Coverage** — which translation units were analysed and which were not, per directory
106
+
107
+ ## Reference projects
108
+
109
+ Two public repositories. Every number below is reproducible on your machine.
110
+
111
+ | | [hoverboard-sideboard-hack-GD](https://github.com/EFeru/hoverboard-sideboard-hack-GD) | [gd32f30x](https://github.com/Jerry-yl/gd32f30x) |
112
+ | --- | ---: | ---: |
113
+ | Model | bare-metal super-loop | FreeRTOS |
114
+ | Translation units | 36 | 51 |
115
+ | Functions | 689 | 871 |
116
+ | ISRs | 13 | 10 |
117
+ | Loops | 55 | 242 |
118
+ | State machine candidates | 13 | 12 |
119
+ | Shared resources | 16 | 25 |
120
+ | Conflict candidates | 0 (see below) | 9 |
121
+ | Wall clock | 9.6 s | 17.0 s |
122
+
123
+ `docs/ARCHCHECK_STATUS.md` §4 has the full tables and the exact commands.
124
+
125
+ ## What it does not do
126
+
127
+ **It does not call an LLM.** Not for facts, not for naming, not for guessing. The
128
+ rule set is data (see below); an agent can propose new rules for you to review, but
129
+ facts only ever come from source plus a rule.
130
+
131
+ **Two known defects, both being worked on:**
132
+
133
+ - **Tasks created through a wrapper are missed.** If your project wraps the RTOS API
134
+ (`OS_TaskCreate` → `xTaskCreate(task, ...)` where the entry arrives as a parameter),
135
+ the task entry is not recovered — on the `gd32f30x` reference project the only task
136
+ reported is FreeRTOS's own idle task. Fix is parameter back-tracking through one
137
+ wrapper hop.
138
+ - **A bare-metal `main` is not counted as the other side of an ISR conflict.** On the
139
+ hoverboard project all 14 `ISR + main` shared variables are found correctly, with
140
+ line numbers and access directions — but the conflict rule only pairs an ISR against
141
+ a `task` / `callback` / `timer`, so it reports zero conflicts. This affects every
142
+ super-loop project.
143
+
144
+ Beyond that: cross-function critical sections need a CFG and are only approximated;
145
+ `yieldLocals` compares source line order, not control flow; sizes require a linker map
146
+ and only `armlink` maps are parsed today. Every approximation is also declared in
147
+ `astFacts.approximations` in the output itself.
148
+
149
+ ## Rules are data
150
+
151
+ The engine knows no API name of its own. FreeRTOS, Zephyr, CMSIS-RTOS2, POSIX,
152
+ protothreads, ESP-IDF, STM32 HAL, GD32 and Cortex-M CMSIS ship as YAML profiles under
153
+ `src/archcheck/profiles/`. Built-in profiles only carry API names you can look up in
154
+ public framework docs or a vendor SDK.
155
+
156
+ Your own wrappers go next to your project, no fork required:
157
+
158
+ ```yaml
159
+ # <project>/framework_rules.yaml
160
+ scheduling: cooperative
161
+ task_create:
162
+ - function: os_task_add
163
+ entry_argument: 0
164
+ ```
165
+
166
+ Adding support for a kernel ArchCheck has never seen is a YAML file, not a patch.
167
+ See [CONTRIBUTING.md](CONTRIBUTING.md) — profile contributions are the most useful
168
+ kind and need no Python.
169
+
170
+ ## License
171
+
172
+ MIT © 2026 SHAR-K
@@ -0,0 +1,147 @@
1
+ # ArchCheck
2
+
3
+ Architecture recovery for C/C++ firmware: ArchCheck reads the source and recovers its **runtime structure** — entry
4
+ points, tasks, ISRs, callbacks, loops, state machines, shared state and concurrency
5
+ boundaries — without running the program, attaching a probe, or calling an LLM.
6
+
7
+ Every finding carries a file, a line and a confidence level. Anything that cannot be
8
+ derived from the source and a rule is reported as unknown, never guessed.
9
+
10
+ ```bash
11
+ pip install archcheck
12
+ archcheck path/to/project --out report/ # or let an agent run it: see the repository README
13
+ ```
14
+
15
+ [Repository](https://github.com/SHAR-K/ArchX) · [Field contract](https://github.com/SHAR-K/ArchX/blob/main/docs/SCHEMA.md) · [Usage](https://github.com/SHAR-K/ArchX/blob/main/docs/USAGE.md) · [Status & known limits](https://github.com/SHAR-K/ArchX/blob/main/docs/ARCHCHECK_STATUS.md) · [Live demo](https://shar-k.github.io/ArchX/)
16
+
17
+ ## Why
18
+
19
+ To see how a firmware actually runs, the standard answer is a runtime tracer:
20
+ instrument the build, flash it, capture a trace. That tells you what the system
21
+ **did**. ArchCheck answers a different question, and it answers it before you have
22
+ a working build to trace:
23
+
24
+ > **What does the code say it will do?**
25
+
26
+ | | Requires | Answers |
27
+ | --- | --- | --- |
28
+ | Percepio Tracealyzer | TraceRecorder instrumentation, a running system | what the system did |
29
+ | Segger SystemView | J-Link probe + instrumentation | what the system did |
30
+ | **ArchCheck** | **a compilation database** | **what the code says it will do** |
31
+
32
+ Useful when you inherit firmware nobody can explain any more, when you want the
33
+ interrupt/task sharing map before a refactor, or when you want an architecture
34
+ check in CI that fails on a new cross-layer call.
35
+
36
+ ## If you can build it, ArchCheck can read it
37
+
38
+ - `compile_commands.json` (CMake, ESP-IDF, Zephyr, Makefile + bear), **or** a Keil
39
+ `.uvprojx` — ArchCheck generates a compatible database from the Keil project itself
40
+ - `clangd` on `PATH` (the AST layer is built on its LSP)
41
+ - Python 3.10+
42
+
43
+ That is the entire prerequisite list. There is no agent to install, no code to
44
+ annotate, and nothing is uploaded anywhere.
45
+
46
+ ## Quick start
47
+
48
+ ```bash
49
+ git clone https://github.com/SHAR-K/archcheck
50
+ cd archcheck && pip install -e .
51
+
52
+ # a CMake / ESP-IDF / Zephyr project
53
+ archcheck /path/to/firmware
54
+
55
+ # a Keil project (pass --keil-target when the project has several targets)
56
+ archcheck /path/to/firmware --keil-project MDK-ARM/app.uvprojx
57
+ ```
58
+
59
+ **Point it at your own firmware.** Three minutes later you have your startup chain,
60
+ your interrupt vectors, and the variables your ISRs share with your tasks — with
61
+ line numbers. That is a better demo than any screenshot here.
62
+
63
+ Output lands in `<project>/.arch-report`: `architecture.json` (the facts),
64
+ `metrics.json`, a Markdown summary, and a single self-contained `report.html`.
65
+
66
+ ## What comes out
67
+
68
+ - **Entry points and startup chain** — `main`, reset handler, `*_init` call chain
69
+ - **Runtime units** — tasks, ISRs, callbacks (including callbacks registered through
70
+ initializer tables, struct fields and function-pointer parameters), each with its
71
+ registration site
72
+ - **Run modes** — periodic / busy-poll / event-driven / one-shot, with the blocking
73
+ call and the period that implies it
74
+ - **Loops** — bounds where they can be derived, and unbounded busy-waits flagged
75
+ - **State machine candidates** — `switch` dispatch variables, states and transitions
76
+ - **Shared state and conflict candidates** — which variables are reached by more than
77
+ one runtime unit, which accesses sit outside a recognised critical section
78
+ - **Image facts** — code/RO/RW/ZI per module from an `armlink` map, kept as a separate
79
+ evidence source from the source-derived facts
80
+ - **Coverage** — which translation units were analysed and which were not, per directory
81
+
82
+ ## Reference projects
83
+
84
+ Two public repositories. Every number below is reproducible on your machine.
85
+
86
+ | | [hoverboard-sideboard-hack-GD](https://github.com/EFeru/hoverboard-sideboard-hack-GD) | [gd32f30x](https://github.com/Jerry-yl/gd32f30x) |
87
+ | --- | ---: | ---: |
88
+ | Model | bare-metal super-loop | FreeRTOS |
89
+ | Translation units | 36 | 51 |
90
+ | Functions | 689 | 871 |
91
+ | ISRs | 13 | 10 |
92
+ | Loops | 55 | 242 |
93
+ | State machine candidates | 13 | 12 |
94
+ | Shared resources | 16 | 25 |
95
+ | Conflict candidates | 0 (see below) | 9 |
96
+ | Wall clock | 9.6 s | 17.0 s |
97
+
98
+ `docs/ARCHCHECK_STATUS.md` §4 has the full tables and the exact commands.
99
+
100
+ ## What it does not do
101
+
102
+ **It does not call an LLM.** Not for facts, not for naming, not for guessing. The
103
+ rule set is data (see below); an agent can propose new rules for you to review, but
104
+ facts only ever come from source plus a rule.
105
+
106
+ **Two known defects, both being worked on:**
107
+
108
+ - **Tasks created through a wrapper are missed.** If your project wraps the RTOS API
109
+ (`OS_TaskCreate` → `xTaskCreate(task, ...)` where the entry arrives as a parameter),
110
+ the task entry is not recovered — on the `gd32f30x` reference project the only task
111
+ reported is FreeRTOS's own idle task. Fix is parameter back-tracking through one
112
+ wrapper hop.
113
+ - **A bare-metal `main` is not counted as the other side of an ISR conflict.** On the
114
+ hoverboard project all 14 `ISR + main` shared variables are found correctly, with
115
+ line numbers and access directions — but the conflict rule only pairs an ISR against
116
+ a `task` / `callback` / `timer`, so it reports zero conflicts. This affects every
117
+ super-loop project.
118
+
119
+ Beyond that: cross-function critical sections need a CFG and are only approximated;
120
+ `yieldLocals` compares source line order, not control flow; sizes require a linker map
121
+ and only `armlink` maps are parsed today. Every approximation is also declared in
122
+ `astFacts.approximations` in the output itself.
123
+
124
+ ## Rules are data
125
+
126
+ The engine knows no API name of its own. FreeRTOS, Zephyr, CMSIS-RTOS2, POSIX,
127
+ protothreads, ESP-IDF, STM32 HAL, GD32 and Cortex-M CMSIS ship as YAML profiles under
128
+ `src/archcheck/profiles/`. Built-in profiles only carry API names you can look up in
129
+ public framework docs or a vendor SDK.
130
+
131
+ Your own wrappers go next to your project, no fork required:
132
+
133
+ ```yaml
134
+ # <project>/framework_rules.yaml
135
+ scheduling: cooperative
136
+ task_create:
137
+ - function: os_task_add
138
+ entry_argument: 0
139
+ ```
140
+
141
+ Adding support for a kernel ArchCheck has never seen is a YAML file, not a patch.
142
+ See [CONTRIBUTING.md](CONTRIBUTING.md) — profile contributions are the most useful
143
+ kind and need no Python.
144
+
145
+ ## License
146
+
147
+ MIT © 2026 SHAR-K
@@ -0,0 +1,41 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "archcheck"
7
+ version = "0.26.0"
8
+ description = "Architecture recovery for C/C++ firmware: entries, tasks, interrupts, shared state and timing as deterministic code facts"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "SHAR-K" }]
14
+ dependencies = ["PyYAML>=6.0,<7"]
15
+ keywords = ["embedded", "firmware", "architecture-recovery", "c", "cpp", "rtos", "freertos", "clangd", "mcp"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Environment :: Console",
19
+ "Intended Audience :: Developers",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: C",
23
+ "Programming Language :: C++",
24
+ "Topic :: Software Development :: Embedded Systems",
25
+ "Topic :: Software Development :: Quality Assurance",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/SHAR-K/ArchX"
30
+ Demo = "https://shar-k.github.io/ArchX/"
31
+ Issues = "https://github.com/SHAR-K/ArchX/issues"
32
+
33
+ [project.scripts]
34
+ archcheck = "archcheck.cli:main"
35
+ archcheck-gui = "archcheck.gui:main"
36
+
37
+ [tool.setuptools.packages.find]
38
+ where = ["src"]
39
+
40
+ [tool.setuptools.package-data]
41
+ archcheck = ["templates/*.html", "profiles/*/*.yaml"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,4 @@
1
+ """Architecture health scanner for C and C++ projects."""
2
+
3
+ __version__ = "0.26.0"
4
+
@@ -0,0 +1,6 @@
1
+ from archcheck.cli import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ raise SystemExit(main())
6
+