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.
Files changed (57) hide show
  1. core_cli-1.0.0/.github/workflows/ci.yml +105 -0
  2. core_cli-1.0.0/.gitignore +8 -0
  3. core_cli-1.0.0/LICENSE +21 -0
  4. core_cli-1.0.0/PKG-INFO +72 -0
  5. core_cli-1.0.0/README.md +46 -0
  6. core_cli-1.0.0/pyproject.toml +50 -0
  7. core_cli-1.0.0/src/core_cli/__init__.py +3 -0
  8. core_cli-1.0.0/src/core_cli/main.py +33 -0
  9. core_cli-1.0.0/src/core_cli/resources/__init__.py +3 -0
  10. core_cli-1.0.0/src/core_cli/resources/code/__init__.py +22 -0
  11. core_cli-1.0.0/src/core_cli/resources/code/actions.py +54 -0
  12. core_cli-1.0.0/src/core_cli/resources/code/audit_duplicates.py +37 -0
  13. core_cli-1.0.0/src/core_cli/resources/code/bridges.py +90 -0
  14. core_cli-1.0.0/src/core_cli/resources/code/check_imports.py +75 -0
  15. core_cli-1.0.0/src/core_cli/resources/code/check_ui.py +61 -0
  16. core_cli-1.0.0/src/core_cli/resources/code/docstrings.py +44 -0
  17. core_cli-1.0.0/src/core_cli/resources/code/fix_atomic.py +57 -0
  18. core_cli-1.0.0/src/core_cli/resources/code/format.py +62 -0
  19. core_cli-1.0.0/src/core_cli/resources/code/hub.py +10 -0
  20. core_cli-1.0.0/src/core_cli/resources/code/integrity.py +75 -0
  21. core_cli-1.0.0/src/core_cli/resources/code/lint.py +37 -0
  22. core_cli-1.0.0/src/core_cli/resources/code/logging.py +55 -0
  23. core_cli-1.0.0/src/core_cli/resources/code/test.py +32 -0
  24. core_cli-1.0.0/src/core_cli/resources/lane/__init__.py +26 -0
  25. core_cli-1.0.0/src/core_cli/resources/lane/claim.py +48 -0
  26. core_cli-1.0.0/src/core_cli/resources/lane/list.py +50 -0
  27. core_cli-1.0.0/src/core_cli/resources/lane/next.py +82 -0
  28. core_cli-1.0.0/src/core_cli/resources/lane/propose.py +119 -0
  29. core_cli-1.0.0/src/core_cli/resources/project/__init__.py +21 -0
  30. core_cli-1.0.0/src/core_cli/resources/project/docs.py +41 -0
  31. core_cli-1.0.0/src/core_cli/resources/project/onboard.py +110 -0
  32. core_cli-1.0.0/src/core_cli/resources/project/scout.py +288 -0
  33. core_cli-1.0.0/src/core_cli/resources/proposals/__init__.py +27 -0
  34. core_cli-1.0.0/src/core_cli/resources/proposals/create.py +99 -0
  35. core_cli-1.0.0/src/core_cli/resources/proposals/integrate.py +57 -0
  36. core_cli-1.0.0/src/core_cli/resources/proposals/list.py +115 -0
  37. core_cli-1.0.0/src/core_cli/resources/proposals/manage.py +183 -0
  38. core_cli-1.0.0/src/core_cli/resources/secrets/__init__.py +10 -0
  39. core_cli-1.0.0/src/core_cli/resources/secrets/hub.py +9 -0
  40. core_cli-1.0.0/src/core_cli/resources/secrets/manage.py +160 -0
  41. core_cli-1.0.0/src/core_cli/resources/symbols/__init__.py +14 -0
  42. core_cli-1.0.0/src/core_cli/resources/symbols/audit.py +56 -0
  43. core_cli-1.0.0/src/core_cli/resources/symbols/fix_ids.py +39 -0
  44. core_cli-1.0.0/src/core_cli/resources/symbols/hub.py +11 -0
  45. core_cli-1.0.0/src/core_cli/resources/symbols/resolve_duplicates.py +37 -0
  46. core_cli-1.0.0/src/core_cli/resources/symbols/sync.py +39 -0
  47. core_cli-1.0.0/src/core_cli/resources/vectors/__init__.py +15 -0
  48. core_cli-1.0.0/src/core_cli/resources/vectors/hub.py +9 -0
  49. core_cli-1.0.0/src/core_cli/resources/vectors/query.py +66 -0
  50. core_cli-1.0.0/src/core_cli/resources/vectors/rebuild.py +71 -0
  51. core_cli-1.0.0/src/core_cli/resources/vectors/status.py +40 -0
  52. core_cli-1.0.0/src/core_cli/resources/vectors/sync.py +50 -0
  53. core_cli-1.0.0/src/core_cli/resources/vectors/sync_code.py +58 -0
  54. core_cli-1.0.0/tests/__init__.py +0 -0
  55. core_cli-1.0.0/tests/test_code.py +343 -0
  56. core_cli-1.0.0/tests/test_lane.py +191 -0
  57. 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
@@ -0,0 +1,8 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .venv/
7
+ .env
8
+ *.pth
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.
@@ -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.
@@ -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,3 @@
1
+ """core-cli — consumer governance CLI for CORE."""
2
+
3
+ from __future__ import annotations
@@ -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,3 @@
1
+ """Consumer resource command packages."""
2
+
3
+ from __future__ import annotations
@@ -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)