core-cli 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.
- core_cli-1.0.0/.github/workflows/ci.yml +105 -0
- core_cli-1.0.0/.gitignore +8 -0
- core_cli-1.0.0/LICENSE +21 -0
- core_cli-1.0.0/PKG-INFO +72 -0
- core_cli-1.0.0/README.md +46 -0
- core_cli-1.0.0/pyproject.toml +50 -0
- core_cli-1.0.0/src/core_cli/__init__.py +3 -0
- core_cli-1.0.0/src/core_cli/main.py +33 -0
- core_cli-1.0.0/src/core_cli/resources/__init__.py +3 -0
- core_cli-1.0.0/src/core_cli/resources/code/__init__.py +22 -0
- core_cli-1.0.0/src/core_cli/resources/code/actions.py +54 -0
- core_cli-1.0.0/src/core_cli/resources/code/audit_duplicates.py +37 -0
- core_cli-1.0.0/src/core_cli/resources/code/bridges.py +90 -0
- core_cli-1.0.0/src/core_cli/resources/code/check_imports.py +75 -0
- core_cli-1.0.0/src/core_cli/resources/code/check_ui.py +61 -0
- core_cli-1.0.0/src/core_cli/resources/code/docstrings.py +44 -0
- core_cli-1.0.0/src/core_cli/resources/code/fix_atomic.py +57 -0
- core_cli-1.0.0/src/core_cli/resources/code/format.py +62 -0
- core_cli-1.0.0/src/core_cli/resources/code/hub.py +10 -0
- core_cli-1.0.0/src/core_cli/resources/code/integrity.py +75 -0
- core_cli-1.0.0/src/core_cli/resources/code/lint.py +37 -0
- core_cli-1.0.0/src/core_cli/resources/code/logging.py +55 -0
- core_cli-1.0.0/src/core_cli/resources/code/test.py +32 -0
- core_cli-1.0.0/src/core_cli/resources/lane/__init__.py +26 -0
- core_cli-1.0.0/src/core_cli/resources/lane/claim.py +48 -0
- core_cli-1.0.0/src/core_cli/resources/lane/list.py +50 -0
- core_cli-1.0.0/src/core_cli/resources/lane/next.py +82 -0
- core_cli-1.0.0/src/core_cli/resources/lane/propose.py +119 -0
- core_cli-1.0.0/src/core_cli/resources/project/__init__.py +21 -0
- core_cli-1.0.0/src/core_cli/resources/project/docs.py +41 -0
- core_cli-1.0.0/src/core_cli/resources/project/onboard.py +110 -0
- core_cli-1.0.0/src/core_cli/resources/project/scout.py +288 -0
- core_cli-1.0.0/src/core_cli/resources/proposals/__init__.py +27 -0
- core_cli-1.0.0/src/core_cli/resources/proposals/create.py +99 -0
- core_cli-1.0.0/src/core_cli/resources/proposals/integrate.py +57 -0
- core_cli-1.0.0/src/core_cli/resources/proposals/list.py +115 -0
- core_cli-1.0.0/src/core_cli/resources/proposals/manage.py +183 -0
- core_cli-1.0.0/src/core_cli/resources/secrets/__init__.py +10 -0
- core_cli-1.0.0/src/core_cli/resources/secrets/hub.py +9 -0
- core_cli-1.0.0/src/core_cli/resources/secrets/manage.py +160 -0
- core_cli-1.0.0/src/core_cli/resources/symbols/__init__.py +14 -0
- core_cli-1.0.0/src/core_cli/resources/symbols/audit.py +56 -0
- core_cli-1.0.0/src/core_cli/resources/symbols/fix_ids.py +39 -0
- core_cli-1.0.0/src/core_cli/resources/symbols/hub.py +11 -0
- core_cli-1.0.0/src/core_cli/resources/symbols/resolve_duplicates.py +37 -0
- core_cli-1.0.0/src/core_cli/resources/symbols/sync.py +39 -0
- core_cli-1.0.0/src/core_cli/resources/vectors/__init__.py +15 -0
- core_cli-1.0.0/src/core_cli/resources/vectors/hub.py +9 -0
- core_cli-1.0.0/src/core_cli/resources/vectors/query.py +66 -0
- core_cli-1.0.0/src/core_cli/resources/vectors/rebuild.py +71 -0
- core_cli-1.0.0/src/core_cli/resources/vectors/status.py +40 -0
- core_cli-1.0.0/src/core_cli/resources/vectors/sync.py +50 -0
- core_cli-1.0.0/src/core_cli/resources/vectors/sync_code.py +58 -0
- core_cli-1.0.0/tests/__init__.py +0 -0
- core_cli-1.0.0/tests/test_code.py +343 -0
- core_cli-1.0.0/tests/test_lane.py +191 -0
- core_cli-1.0.0/tests/test_proposals.py +350 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
tags: ["v*"]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main]
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
lint:
|
|
12
|
+
name: Lint
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Install ruff
|
|
22
|
+
run: pip install ruff
|
|
23
|
+
|
|
24
|
+
- name: ruff check
|
|
25
|
+
run: ruff check src/
|
|
26
|
+
|
|
27
|
+
typecheck:
|
|
28
|
+
name: Type check
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v4
|
|
32
|
+
|
|
33
|
+
- uses: actions/setup-python@v5
|
|
34
|
+
with:
|
|
35
|
+
python-version: "3.12"
|
|
36
|
+
|
|
37
|
+
- name: Install mypy + stubs
|
|
38
|
+
run: pip install mypy types-PyYAML
|
|
39
|
+
|
|
40
|
+
- name: mypy
|
|
41
|
+
# core-runtime ships no type stubs; ignore-missing-imports preserves
|
|
42
|
+
# checking of core-cli's own code without requiring stub packages.
|
|
43
|
+
run: mypy src/ --ignore-missing-imports --no-error-summary
|
|
44
|
+
|
|
45
|
+
test:
|
|
46
|
+
name: Test
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/checkout@v4
|
|
50
|
+
|
|
51
|
+
- uses: actions/setup-python@v5
|
|
52
|
+
with:
|
|
53
|
+
python-version: "3.12"
|
|
54
|
+
|
|
55
|
+
- name: Install package + dev deps
|
|
56
|
+
# core-runtime is on PyPI (>=2.8.0); installs as a transitive dep.
|
|
57
|
+
run: pip install -e ".[dev]"
|
|
58
|
+
|
|
59
|
+
- name: Run tests
|
|
60
|
+
run: pytest tests/ -v
|
|
61
|
+
|
|
62
|
+
build:
|
|
63
|
+
name: Build distribution
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
steps:
|
|
66
|
+
- uses: actions/checkout@v4
|
|
67
|
+
|
|
68
|
+
- uses: actions/setup-python@v5
|
|
69
|
+
with:
|
|
70
|
+
python-version: "3.12"
|
|
71
|
+
|
|
72
|
+
- name: Build sdist + wheel
|
|
73
|
+
run: |
|
|
74
|
+
pip install build
|
|
75
|
+
python -m build
|
|
76
|
+
|
|
77
|
+
- name: Upload distribution artifacts
|
|
78
|
+
uses: actions/upload-artifact@v4
|
|
79
|
+
with:
|
|
80
|
+
name: dist
|
|
81
|
+
path: dist/
|
|
82
|
+
if-no-files-found: error
|
|
83
|
+
retention-days: 7
|
|
84
|
+
|
|
85
|
+
publish:
|
|
86
|
+
name: Publish to PyPI
|
|
87
|
+
# Only publish on version tags; all checks must pass first.
|
|
88
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
89
|
+
needs: [lint, typecheck, test, build]
|
|
90
|
+
runs-on: ubuntu-latest
|
|
91
|
+
# "pypi" environment must be configured in GitHub repo Settings → Environments.
|
|
92
|
+
# The matching Trusted Publisher must be registered at pypi.org/manage/account/publishing/
|
|
93
|
+
# with: project=core-cli, owner=DariuszNewecki, repo=core-cli, workflow=ci.yml, env=pypi.
|
|
94
|
+
environment: pypi
|
|
95
|
+
permissions:
|
|
96
|
+
id-token: write # required for OIDC Trusted Publisher token exchange
|
|
97
|
+
steps:
|
|
98
|
+
- name: Download distribution artifacts
|
|
99
|
+
uses: actions/download-artifact@v4
|
|
100
|
+
with:
|
|
101
|
+
name: dist
|
|
102
|
+
path: dist/
|
|
103
|
+
|
|
104
|
+
- name: Publish to PyPI (Trusted Publisher OIDC)
|
|
105
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
core_cli-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Dariusz Newecki
|
|
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.
|
core_cli-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: core-cli
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Consumer governance CLI for CORE — pure HTTP client for governing repositories against CORE constitutional rules.
|
|
5
|
+
Project-URL: Homepage, https://github.com/DariuszNewecki/CORE
|
|
6
|
+
Project-URL: Repository, https://github.com/DariuszNewecki/core-cli
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/DariuszNewecki/core-cli/issues
|
|
8
|
+
Author-email: Dariusz Newecki <d.newecki@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: cli,code-quality,constitutional-ai,developer-tools,governance
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development
|
|
19
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Requires-Dist: core-runtime>=2.8.0
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
24
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# core-cli
|
|
28
|
+
|
|
29
|
+
Consumer governance CLI for [CORE](https://github.com/DariuszNewecki/CORE) — pure HTTP client for governing repositories against CORE constitutional rules.
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install core-cli
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
core lane list
|
|
41
|
+
core proposals list
|
|
42
|
+
core code audit_duplicates --help
|
|
43
|
+
core symbols audit --help
|
|
44
|
+
core vectors query --help
|
|
45
|
+
core project onboard --help
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Requires a running CORE instance. Configure via environment:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
export CORE_API_URL=http://localhost:8000
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Commands
|
|
55
|
+
|
|
56
|
+
| Namespace | Commands |
|
|
57
|
+
|-----------|----------|
|
|
58
|
+
| `lane` | `list`, `next`, `claim`, `propose` |
|
|
59
|
+
| `proposals` | `list`, `create`, `show`, `approve`, `reject`, `execute` |
|
|
60
|
+
| `secrets` | manage encrypted secrets |
|
|
61
|
+
| `code` | `actions`, `audit_duplicates`, `bridges`, `check_imports`, `check_ui`, `docstrings`, `fix_atomic`, `format`, `integrity`, `lint`, `logging`, `test` |
|
|
62
|
+
| `symbols` | `audit`, `fix_ids`, `resolve_duplicates`, `sync` |
|
|
63
|
+
| `vectors` | `query`, `rebuild`, `status`, `sync`, `sync_code` |
|
|
64
|
+
| `project` | `docs`, `onboard`, `scout` |
|
|
65
|
+
|
|
66
|
+
## Architecture
|
|
67
|
+
|
|
68
|
+
All commands communicate exclusively over the CORE HTTP API — no in-process access required.
|
|
69
|
+
`core-cli` depends on `core-runtime` for shared HTTP client infrastructure (`api.cli.*`)
|
|
70
|
+
and CLI utilities (`cli.utils.*`).
|
|
71
|
+
|
|
72
|
+
See [ADR-146](https://github.com/DariuszNewecki/CORE/blob/main/.specs/decisions/ADR-146-cli-consumer-operator-split.md) for the consumer/operator split rationale.
|
core_cli-1.0.0/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# core-cli
|
|
2
|
+
|
|
3
|
+
Consumer governance CLI for [CORE](https://github.com/DariuszNewecki/CORE) — pure HTTP client for governing repositories against CORE constitutional rules.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install core-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
core lane list
|
|
15
|
+
core proposals list
|
|
16
|
+
core code audit_duplicates --help
|
|
17
|
+
core symbols audit --help
|
|
18
|
+
core vectors query --help
|
|
19
|
+
core project onboard --help
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Requires a running CORE instance. Configure via environment:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
export CORE_API_URL=http://localhost:8000
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Commands
|
|
29
|
+
|
|
30
|
+
| Namespace | Commands |
|
|
31
|
+
|-----------|----------|
|
|
32
|
+
| `lane` | `list`, `next`, `claim`, `propose` |
|
|
33
|
+
| `proposals` | `list`, `create`, `show`, `approve`, `reject`, `execute` |
|
|
34
|
+
| `secrets` | manage encrypted secrets |
|
|
35
|
+
| `code` | `actions`, `audit_duplicates`, `bridges`, `check_imports`, `check_ui`, `docstrings`, `fix_atomic`, `format`, `integrity`, `lint`, `logging`, `test` |
|
|
36
|
+
| `symbols` | `audit`, `fix_ids`, `resolve_duplicates`, `sync` |
|
|
37
|
+
| `vectors` | `query`, `rebuild`, `status`, `sync`, `sync_code` |
|
|
38
|
+
| `project` | `docs`, `onboard`, `scout` |
|
|
39
|
+
|
|
40
|
+
## Architecture
|
|
41
|
+
|
|
42
|
+
All commands communicate exclusively over the CORE HTTP API — no in-process access required.
|
|
43
|
+
`core-cli` depends on `core-runtime` for shared HTTP client infrastructure (`api.cli.*`)
|
|
44
|
+
and CLI utilities (`cli.utils.*`).
|
|
45
|
+
|
|
46
|
+
See [ADR-146](https://github.com/DariuszNewecki/CORE/blob/main/.specs/decisions/ADR-146-cli-consumer-operator-split.md) for the consumer/operator split rationale.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "core-cli"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Consumer governance CLI for CORE — pure HTTP client for governing repositories against CORE constitutional rules."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.12"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Dariusz Newecki", email = "d.newecki@gmail.com" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["governance", "cli", "code-quality", "constitutional-ai", "developer-tools"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Topic :: Software Development",
|
|
21
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
22
|
+
"Environment :: Console",
|
|
23
|
+
"Intended Audience :: Developers",
|
|
24
|
+
"Development Status :: 4 - Beta",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"core-runtime>=2.8.0",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.optional-dependencies]
|
|
31
|
+
dev = [
|
|
32
|
+
"pytest>=8.0",
|
|
33
|
+
"pytest-asyncio>=0.23",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.scripts]
|
|
37
|
+
core = "core_cli.main:app"
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/DariuszNewecki/CORE"
|
|
41
|
+
Repository = "https://github.com/DariuszNewecki/core-cli"
|
|
42
|
+
"Bug Tracker" = "https://github.com/DariuszNewecki/core-cli/issues"
|
|
43
|
+
|
|
44
|
+
[tool.hatch.build.targets.wheel]
|
|
45
|
+
packages = ["src/core_cli"]
|
|
46
|
+
|
|
47
|
+
[tool.pytest.ini_options]
|
|
48
|
+
asyncio_mode = "auto"
|
|
49
|
+
pythonpath = ["src"]
|
|
50
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""core-cli entry point — consumer governance CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from core_cli.resources.code import app as code_app
|
|
8
|
+
from core_cli.resources.lane import app as lane_app
|
|
9
|
+
from core_cli.resources.project import app as project_app
|
|
10
|
+
from core_cli.resources.proposals import app as proposals_app
|
|
11
|
+
from core_cli.resources.secrets import app as secrets_app
|
|
12
|
+
from core_cli.resources.symbols import app as symbols_app
|
|
13
|
+
from core_cli.resources.vectors import app as vectors_app
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# ID: 92ffef66-e5d7-48ae-929e-a82f136a9719
|
|
17
|
+
app = typer.Typer(
|
|
18
|
+
name="core",
|
|
19
|
+
help="CORE consumer governance CLI — govern your project against CORE constitutional rules.",
|
|
20
|
+
no_args_is_help=True,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
app.add_typer(lane_app, name="lane")
|
|
24
|
+
app.add_typer(proposals_app, name="proposals")
|
|
25
|
+
app.add_typer(secrets_app, name="secrets")
|
|
26
|
+
app.add_typer(code_app, name="code")
|
|
27
|
+
app.add_typer(symbols_app, name="symbols")
|
|
28
|
+
app.add_typer(vectors_app, name="vectors")
|
|
29
|
+
app.add_typer(project_app, name="project")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
if __name__ == "__main__":
|
|
33
|
+
app()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Consumer codebase commands — quality, style, and verification over HTTP."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from . import ( # noqa: F401
|
|
6
|
+
actions,
|
|
7
|
+
audit_duplicates,
|
|
8
|
+
bridges,
|
|
9
|
+
check_imports,
|
|
10
|
+
check_ui,
|
|
11
|
+
docstrings,
|
|
12
|
+
fix_atomic,
|
|
13
|
+
format,
|
|
14
|
+
integrity,
|
|
15
|
+
lint,
|
|
16
|
+
logging,
|
|
17
|
+
test,
|
|
18
|
+
)
|
|
19
|
+
from .hub import app
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = ["app"]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# src/cli/resources/code/actions.py
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
from rich.table import Table
|
|
6
|
+
|
|
7
|
+
from api.cli import CoreApiClient
|
|
8
|
+
from cli.utils import core_command
|
|
9
|
+
from shared.cli.command_meta import (
|
|
10
|
+
CommandBehavior,
|
|
11
|
+
CommandExposure,
|
|
12
|
+
CommandLayer,
|
|
13
|
+
command_meta,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from .hub import app
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
console = Console()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@app.command("actions")
|
|
24
|
+
@command_meta(
|
|
25
|
+
canonical_name="code.actions",
|
|
26
|
+
behavior=CommandBehavior.READ,
|
|
27
|
+
layer=CommandLayer.BODY,
|
|
28
|
+
exposure=CommandExposure.GOVERNOR_ONLY,
|
|
29
|
+
summary="List all registered Atomic Actions showing their IDs, categories, impact levels, and descriptions.",
|
|
30
|
+
dangerous=False,
|
|
31
|
+
)
|
|
32
|
+
@core_command(dangerous=False, requires_context=False)
|
|
33
|
+
# ID: 4f8e13a3-f017-4d0f-a6ef-340f81d05341
|
|
34
|
+
async def list_actions_cmd() -> None:
|
|
35
|
+
"""
|
|
36
|
+
List all registered Atomic Actions (Body Capabilities).
|
|
37
|
+
Shows IDs, categories, and impact levels for autonomous building blocks.
|
|
38
|
+
"""
|
|
39
|
+
client = CoreApiClient()
|
|
40
|
+
payload = await client.list_actions()
|
|
41
|
+
actions = payload.get("actions", [])
|
|
42
|
+
table = Table(title="Registered Atomic Actions", header_style="bold green")
|
|
43
|
+
table.add_column("Action ID", style="cyan")
|
|
44
|
+
table.add_column("Category", style="blue")
|
|
45
|
+
table.add_column("Impact", style="magenta")
|
|
46
|
+
table.add_column("Description")
|
|
47
|
+
for action in sorted(actions, key=lambda a: a.get("action_id", "")):
|
|
48
|
+
table.add_row(
|
|
49
|
+
action.get("action_id", ""),
|
|
50
|
+
action.get("category", ""),
|
|
51
|
+
action.get("impact_level", ""),
|
|
52
|
+
action.get("description", ""),
|
|
53
|
+
)
|
|
54
|
+
console.print(table)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# src/core_cli/resources/code/audit_duplicates.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import typer
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
|
|
7
|
+
from api.cli import CoreApiClient
|
|
8
|
+
from cli.utils import core_command
|
|
9
|
+
|
|
10
|
+
from .hub import app
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
console = Console()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@app.command("audit-duplicates")
|
|
17
|
+
@core_command(dangerous=False, requires_context=False)
|
|
18
|
+
# ID: 2ad098e5-aa8a-4e12-89e4-be20d2e12e03
|
|
19
|
+
async def audit_duplicates_cmd(
|
|
20
|
+
threshold: float = typer.Option(0.96, help="Similarity threshold (0.0-1.0)."),
|
|
21
|
+
) -> None:
|
|
22
|
+
"""
|
|
23
|
+
Perform a semantic scan to find duplicate logic across the codebase.
|
|
24
|
+
Helps enforce the 'dry_by_design' constitutional principle.
|
|
25
|
+
"""
|
|
26
|
+
client = CoreApiClient()
|
|
27
|
+
result = await client.inspect.analysis_duplicates(threshold=threshold)
|
|
28
|
+
if result.get("ok"):
|
|
29
|
+
console.print(
|
|
30
|
+
f"[green]✓ Duplicates scan complete (threshold={threshold}).[/green]"
|
|
31
|
+
)
|
|
32
|
+
note = result.get("note", "")
|
|
33
|
+
if note:
|
|
34
|
+
console.print(f"[dim]{note}[/dim]")
|
|
35
|
+
else:
|
|
36
|
+
console.print(f"[red]✗ Duplicates scan failed: {result.get('error')}[/red]")
|
|
37
|
+
raise typer.Exit(1)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# src/core_cli/resources/code/bridges.py
|
|
2
|
+
"""CLI command: list declared architecture bridge points (issue #617)."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import typer
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
from rich.table import Table
|
|
9
|
+
|
|
10
|
+
from api.cli import CoreApiClient
|
|
11
|
+
from cli.utils import core_command
|
|
12
|
+
|
|
13
|
+
from .hub import app
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@app.command("bridges")
|
|
20
|
+
@core_command(dangerous=False, requires_context=False)
|
|
21
|
+
# ID: 5b2e91f3-a4c8-4d7e-b6f0-8c1a9d2e3f04
|
|
22
|
+
async def list_bridges_cmd(
|
|
23
|
+
consuming: str | None = typer.Option(
|
|
24
|
+
None,
|
|
25
|
+
"--consuming",
|
|
26
|
+
"-c",
|
|
27
|
+
help="Filter by consuming type (e.g. AuditFinding, Proposal).",
|
|
28
|
+
),
|
|
29
|
+
) -> None:
|
|
30
|
+
"""
|
|
31
|
+
List declared architecture bridge points.
|
|
32
|
+
|
|
33
|
+
Each bridge is a constitutionally-declared data-flow crossing where
|
|
34
|
+
information moves between CORE layers. Use --consuming to find bridges
|
|
35
|
+
that consume a specific data type.
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
core code bridges --consuming AuditFinding
|
|
39
|
+
"""
|
|
40
|
+
client = CoreApiClient()
|
|
41
|
+
result = await client.inspect.analysis_bridges(consuming=consuming)
|
|
42
|
+
|
|
43
|
+
if not result.get("available"):
|
|
44
|
+
console.print(f"[red]✗ Bridges unavailable: {result.get('error')}[/red]")
|
|
45
|
+
raise typer.Exit(1)
|
|
46
|
+
|
|
47
|
+
bridges = result.get("bridges", [])
|
|
48
|
+
if not bridges:
|
|
49
|
+
if consuming:
|
|
50
|
+
console.print(
|
|
51
|
+
f"[yellow]No bridges found consuming type '{consuming}'.[/yellow]"
|
|
52
|
+
)
|
|
53
|
+
else:
|
|
54
|
+
console.print("[yellow]No bridge declarations found.[/yellow]")
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
title = (
|
|
58
|
+
f"Architecture Bridges (consuming '{consuming}')"
|
|
59
|
+
if consuming
|
|
60
|
+
else "Architecture Bridges"
|
|
61
|
+
)
|
|
62
|
+
table = Table(title=title, header_style="bold cyan", show_lines=True)
|
|
63
|
+
table.add_column("ID", style="cyan", no_wrap=True)
|
|
64
|
+
table.add_column("Bridge Class", style="bold")
|
|
65
|
+
table.add_column("Layer", style="blue")
|
|
66
|
+
table.add_column("Source", style="dim")
|
|
67
|
+
table.add_column("Sink Target", style="green")
|
|
68
|
+
table.add_column("Attribution", style="magenta")
|
|
69
|
+
table.add_column("ADRs", style="dim")
|
|
70
|
+
|
|
71
|
+
for bridge in bridges:
|
|
72
|
+
source = bridge.get("source_layer") or (
|
|
73
|
+
bridge.get("source_context", "")[:40]
|
|
74
|
+
)
|
|
75
|
+
attr_mechanism = bridge.get("attribution_mechanism", "")
|
|
76
|
+
attr_field = bridge.get("attribution_field")
|
|
77
|
+
attribution = (
|
|
78
|
+
f"{attr_mechanism} → {attr_field}" if attr_field else attr_mechanism
|
|
79
|
+
)
|
|
80
|
+
table.add_row(
|
|
81
|
+
bridge.get("id", ""),
|
|
82
|
+
bridge.get("bridge_class", ""),
|
|
83
|
+
bridge.get("bridge_layer", ""),
|
|
84
|
+
source,
|
|
85
|
+
bridge.get("sink_target", ""),
|
|
86
|
+
attribution,
|
|
87
|
+
", ".join(bridge.get("authority_adrs", [])),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
console.print(table)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# src/cli/resources/code/check_imports.py
|
|
2
|
+
"""
|
|
3
|
+
Import integrity check command.
|
|
4
|
+
|
|
5
|
+
Routes through POST /v1/quality/imports for constitutional compliance.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
|
|
12
|
+
import typer
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
from rich.table import Table
|
|
15
|
+
|
|
16
|
+
from api.cli import CoreApiClient
|
|
17
|
+
from cli.utils import core_command
|
|
18
|
+
|
|
19
|
+
from .hub import app
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
console = Console()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@app.command("check-imports")
|
|
27
|
+
@core_command(dangerous=False, requires_context=False)
|
|
28
|
+
# ID: 53db749b-a5cf-44e4-8e7f-47e6499aec0b
|
|
29
|
+
async def check_imports_cmd(ctx: typer.Context) -> None:
|
|
30
|
+
"""
|
|
31
|
+
Verify all import statements resolve to existing modules.
|
|
32
|
+
|
|
33
|
+
Checks for:
|
|
34
|
+
- F821: References to undefined names (moved/deleted modules)
|
|
35
|
+
- F401: Stale imports left after refactoring
|
|
36
|
+
|
|
37
|
+
Enforces:
|
|
38
|
+
- code.imports.must_resolve
|
|
39
|
+
- code.imports.no_stale_namespace
|
|
40
|
+
"""
|
|
41
|
+
console.rule("[bold cyan]Import Integrity Check[/bold cyan]")
|
|
42
|
+
console.print("[dim]Scanning src/ for unresolvable imports (F821, F401)...[/dim]\n")
|
|
43
|
+
client = CoreApiClient()
|
|
44
|
+
result = await client.quality_imports()
|
|
45
|
+
if result.get("status") == "ok":
|
|
46
|
+
console.print("[bold green]✅ All imports resolve cleanly.[/bold green]")
|
|
47
|
+
return
|
|
48
|
+
violations = result.get("violations", [])
|
|
49
|
+
violation_count = len(violations)
|
|
50
|
+
console.print(
|
|
51
|
+
f"[bold red]❌ {violation_count} unresolvable import(s) found.[/bold red]\n"
|
|
52
|
+
)
|
|
53
|
+
if violations:
|
|
54
|
+
table = Table(
|
|
55
|
+
title="Import Violations", show_header=True, header_style="bold red"
|
|
56
|
+
)
|
|
57
|
+
table.add_column("File", style="cyan", overflow="fold")
|
|
58
|
+
table.add_column("Line", style="yellow", justify="right", width=6)
|
|
59
|
+
table.add_column("Rule", style="magenta", width=6)
|
|
60
|
+
table.add_column("Message", style="white", overflow="fold")
|
|
61
|
+
for v in violations:
|
|
62
|
+
table.add_row(
|
|
63
|
+
v.get("file", ""),
|
|
64
|
+
str(v.get("line", "")),
|
|
65
|
+
v.get("rule", ""),
|
|
66
|
+
v.get("message", ""),
|
|
67
|
+
)
|
|
68
|
+
console.print(table)
|
|
69
|
+
console.print(
|
|
70
|
+
"\n[dim]Fix: Update stale import paths or remove unused imports.[/dim]"
|
|
71
|
+
)
|
|
72
|
+
console.print(
|
|
73
|
+
"[dim]Rule: code.imports.must_resolve (.intent/rules/code/imports.json)[/dim]"
|
|
74
|
+
)
|
|
75
|
+
raise typer.Exit(code=1)
|