agentkit-cli 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## v0.1.0 (2026-03-12)
4
+
5
+ Initial release.
6
+
7
+ ### Added
8
+ - `agentkit init` — initialize project, detect tools, create `.agentkit.yaml`
9
+ - `agentkit run` — sequential pipeline runner (generate → lint → benchmark → reflect)
10
+ - `agentkit status` — health check with tool versions and last run summary
11
+ - `--json` flag on `run` and `status` for machine-readable output
12
+ - `--skip` flag on `run` to skip individual steps
13
+ - `--benchmark` flag to opt-in to the coderace benchmark step
14
+ - Rich terminal output throughout
15
+ - 25+ tests with typer CliRunner
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 mikiships
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,148 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentkit-cli
3
+ Version: 0.1.0
4
+ Summary: Unified CLI for the Agent Quality Toolkit (agentmd, coderace, agentlint, agentreflect)
5
+ Project-URL: Homepage, https://github.com/mikiships/agentkit-cli
6
+ Project-URL: Repository, https://github.com/mikiships/agentkit-cli
7
+ Project-URL: Changelog, https://github.com/mikiships/agentkit-cli/blob/main/CHANGELOG.md
8
+ Author-email: mikiships <frank.michaels2123@gmail.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: agents,ai,benchmark,cli,llm,quality,toolkit
12
+ Classifier: Development Status :: 3 - Alpha
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.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Software Development :: Quality Assurance
20
+ Classifier: Topic :: Software Development :: Testing
21
+ Requires-Python: >=3.11
22
+ Requires-Dist: rich>=13.0.0
23
+ Requires-Dist: typer>=0.9.0
24
+ Description-Content-Type: text/markdown
25
+
26
+ # agentkit-cli
27
+
28
+ **One install to rule them all.**
29
+
30
+ ```bash
31
+ pip install agentkit-cli
32
+ ```
33
+
34
+ Get the full Agent Quality Toolkit pipeline in a single command — no more juggling four separate `pip install` steps.
35
+
36
+ ---
37
+
38
+ ## What is it?
39
+
40
+ `agentkit-cli` is a unified meta-CLI that wraps the **Agent Quality Toolkit quartet**:
41
+
42
+ | Tool | Purpose |
43
+ |------|---------|
44
+ | [agentmd](https://pypi.org/project/agentmd/) | Generate CLAUDE.md context files |
45
+ | [agentlint](https://pypi.org/project/agentlint/) | Lint AI context files and git diffs |
46
+ | [coderace](https://pypi.org/project/coderace/) | Benchmark AI coding performance |
47
+ | [agentreflect](https://pypi.org/project/agentreflect/) | Generate reflection reports from failures |
48
+
49
+ ## Pipeline Overview
50
+
51
+ ```
52
+ agentkit run
53
+
54
+ ├── 1. agentmd generate → produces CLAUDE.md
55
+ ├── 2. agentlint check-context → lints CLAUDE.md
56
+ ├── 3. agentlint (diff) → lints recent changes
57
+ ├── 4. coderace benchmark → (opt-in via --benchmark)
58
+ └── 5. agentreflect generate → reflection on failures
59
+ ```
60
+
61
+ Zero to full pipeline in 30 seconds.
62
+
63
+ ---
64
+
65
+ ## Installation
66
+
67
+ ```bash
68
+ pip install agentkit-cli
69
+ ```
70
+
71
+ Install the quartet tools too:
72
+
73
+ ```bash
74
+ pip install agentmd agentlint coderace agentreflect
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Usage
80
+
81
+ ### `agentkit init`
82
+
83
+ Initialize agentkit in a project. Checks which tools are installed and creates `.agentkit.yaml`.
84
+
85
+ ```bash
86
+ agentkit init
87
+ agentkit init --path /my/project
88
+ ```
89
+
90
+ Creates `.agentkit.yaml`:
91
+
92
+ ```yaml
93
+ tools:
94
+ coderace: true
95
+ agentmd: true
96
+ agentlint: true
97
+ agentreflect: true
98
+ defaults:
99
+ min_score: 80
100
+ context_file: CLAUDE.md
101
+ ```
102
+
103
+ ---
104
+
105
+ ### `agentkit run`
106
+
107
+ Run the full quality pipeline sequentially.
108
+
109
+ ```bash
110
+ agentkit run
111
+ agentkit run --path /my/project
112
+ agentkit run --skip generate
113
+ agentkit run --skip lint
114
+ agentkit run --skip benchmark
115
+ agentkit run --skip reflect
116
+ agentkit run --benchmark # include benchmark step
117
+ agentkit run --json # emit summary as JSON
118
+ agentkit run --notes "regression after refactor"
119
+ ```
120
+
121
+ Missing tools are skipped automatically with a warning — you don't need all four installed.
122
+
123
+ ---
124
+
125
+ ### `agentkit status`
126
+
127
+ Quick health check: tool versions, config presence, last run summary.
128
+
129
+ ```bash
130
+ agentkit status
131
+ agentkit status --path /my/project
132
+ agentkit status --json
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Links
138
+
139
+ - [agentmd](https://pypi.org/project/agentmd/)
140
+ - [agentlint](https://pypi.org/project/agentlint/)
141
+ - [coderace](https://pypi.org/project/coderace/)
142
+ - [agentreflect](https://pypi.org/project/agentreflect/)
143
+
144
+ ---
145
+
146
+ ## License
147
+
148
+ MIT
@@ -0,0 +1,123 @@
1
+ # agentkit-cli
2
+
3
+ **One install to rule them all.**
4
+
5
+ ```bash
6
+ pip install agentkit-cli
7
+ ```
8
+
9
+ Get the full Agent Quality Toolkit pipeline in a single command — no more juggling four separate `pip install` steps.
10
+
11
+ ---
12
+
13
+ ## What is it?
14
+
15
+ `agentkit-cli` is a unified meta-CLI that wraps the **Agent Quality Toolkit quartet**:
16
+
17
+ | Tool | Purpose |
18
+ |------|---------|
19
+ | [agentmd](https://pypi.org/project/agentmd/) | Generate CLAUDE.md context files |
20
+ | [agentlint](https://pypi.org/project/agentlint/) | Lint AI context files and git diffs |
21
+ | [coderace](https://pypi.org/project/coderace/) | Benchmark AI coding performance |
22
+ | [agentreflect](https://pypi.org/project/agentreflect/) | Generate reflection reports from failures |
23
+
24
+ ## Pipeline Overview
25
+
26
+ ```
27
+ agentkit run
28
+
29
+ ├── 1. agentmd generate → produces CLAUDE.md
30
+ ├── 2. agentlint check-context → lints CLAUDE.md
31
+ ├── 3. agentlint (diff) → lints recent changes
32
+ ├── 4. coderace benchmark → (opt-in via --benchmark)
33
+ └── 5. agentreflect generate → reflection on failures
34
+ ```
35
+
36
+ Zero to full pipeline in 30 seconds.
37
+
38
+ ---
39
+
40
+ ## Installation
41
+
42
+ ```bash
43
+ pip install agentkit-cli
44
+ ```
45
+
46
+ Install the quartet tools too:
47
+
48
+ ```bash
49
+ pip install agentmd agentlint coderace agentreflect
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Usage
55
+
56
+ ### `agentkit init`
57
+
58
+ Initialize agentkit in a project. Checks which tools are installed and creates `.agentkit.yaml`.
59
+
60
+ ```bash
61
+ agentkit init
62
+ agentkit init --path /my/project
63
+ ```
64
+
65
+ Creates `.agentkit.yaml`:
66
+
67
+ ```yaml
68
+ tools:
69
+ coderace: true
70
+ agentmd: true
71
+ agentlint: true
72
+ agentreflect: true
73
+ defaults:
74
+ min_score: 80
75
+ context_file: CLAUDE.md
76
+ ```
77
+
78
+ ---
79
+
80
+ ### `agentkit run`
81
+
82
+ Run the full quality pipeline sequentially.
83
+
84
+ ```bash
85
+ agentkit run
86
+ agentkit run --path /my/project
87
+ agentkit run --skip generate
88
+ agentkit run --skip lint
89
+ agentkit run --skip benchmark
90
+ agentkit run --skip reflect
91
+ agentkit run --benchmark # include benchmark step
92
+ agentkit run --json # emit summary as JSON
93
+ agentkit run --notes "regression after refactor"
94
+ ```
95
+
96
+ Missing tools are skipped automatically with a warning — you don't need all four installed.
97
+
98
+ ---
99
+
100
+ ### `agentkit status`
101
+
102
+ Quick health check: tool versions, config presence, last run summary.
103
+
104
+ ```bash
105
+ agentkit status
106
+ agentkit status --path /my/project
107
+ agentkit status --json
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Links
113
+
114
+ - [agentmd](https://pypi.org/project/agentmd/)
115
+ - [agentlint](https://pypi.org/project/agentlint/)
116
+ - [coderace](https://pypi.org/project/coderace/)
117
+ - [agentreflect](https://pypi.org/project/agentreflect/)
118
+
119
+ ---
120
+
121
+ ## License
122
+
123
+ MIT
@@ -0,0 +1,3 @@
1
+ """agentkit-cli: Unified CLI for the Agent Quality Toolkit."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1 @@
1
+ # commands package
@@ -0,0 +1,63 @@
1
+ """agentkit init command."""
2
+ from __future__ import annotations
3
+
4
+ from pathlib import Path
5
+ from typing import Optional
6
+
7
+ import typer
8
+ from rich.console import Console
9
+ from rich.panel import Panel
10
+ from rich.table import Table
11
+ from rich import print as rprint
12
+
13
+ from agentkit_cli.tools import QUARTET_TOOLS, is_installed, INSTALL_HINTS
14
+ from agentkit_cli.config import find_project_root, config_path, config_exists, write_default_config
15
+
16
+ console = Console()
17
+
18
+
19
+ def init_command(
20
+ path: Optional[Path] = typer.Option(None, "--path", "-p", help="Project root (default: git root or cwd)"),
21
+ ) -> None:
22
+ """Initialize agentkit in a project directory."""
23
+ root = path or find_project_root()
24
+ console.print(f"\n[bold]Initializing agentkit in:[/bold] {root}\n")
25
+
26
+ # Check quartet tools
27
+ table = Table(title="Agent Quality Toolkit — Tool Status", show_header=True)
28
+ table.add_column("Tool", style="bold")
29
+ table.add_column("Status")
30
+ table.add_column("Install Command")
31
+
32
+ missing = []
33
+ for tool in QUARTET_TOOLS:
34
+ if is_installed(tool):
35
+ table.add_row(tool, "[green]✓ installed[/green]", "")
36
+ else:
37
+ table.add_row(tool, "[red]✗ missing[/red]", INSTALL_HINTS.get(tool, f"pip install {tool}"))
38
+ missing.append(tool)
39
+
40
+ console.print(table)
41
+
42
+ # Write config
43
+ cfg_path = config_path(root)
44
+ if config_exists(root):
45
+ console.print(f"\n[yellow]Config already exists:[/yellow] {cfg_path}")
46
+ else:
47
+ written = write_default_config(root)
48
+ console.print(f"\n[green]Created config:[/green] {written}")
49
+
50
+ # Print install instructions for missing tools
51
+ if missing:
52
+ console.print("\n[yellow]Install missing tools:[/yellow]")
53
+ for tool in missing:
54
+ console.print(f" pip install {tool}")
55
+
56
+ # Next steps
57
+ next_steps = "\n".join([
58
+ "1. Install any missing tools (see above)",
59
+ "2. Run [bold]agentkit run[/bold] to execute the full quality pipeline",
60
+ "3. Run [bold]agentkit status[/bold] to check your setup at any time",
61
+ ])
62
+ console.print(Panel(next_steps, title="Next Steps", border_style="blue"))
63
+ console.print()
@@ -0,0 +1,173 @@
1
+ """agentkit run command — sequential pipeline runner."""
2
+ from __future__ import annotations
3
+
4
+ import json
5
+ import time
6
+ from datetime import datetime, timezone
7
+ from pathlib import Path
8
+ from typing import List, Optional
9
+
10
+ import typer
11
+ from rich.console import Console
12
+ from rich.table import Table
13
+
14
+ from agentkit_cli.tools import is_installed, run_tool, INSTALL_HINTS
15
+ from agentkit_cli.config import find_project_root, save_last_run
16
+
17
+ console = Console()
18
+
19
+ STEP_TOOL_MAP = {
20
+ "generate": "agentmd",
21
+ "lint": "agentlint",
22
+ "benchmark": "coderace",
23
+ "reflect": "agentreflect",
24
+ }
25
+
26
+
27
+ def _run_step(name: str, tool: str, args: list[str], cwd: str) -> dict:
28
+ """Execute one pipeline step; return result dict."""
29
+ start = time.monotonic()
30
+ if not is_installed(tool):
31
+ return {
32
+ "step": name,
33
+ "tool": tool,
34
+ "status": "skipped",
35
+ "reason": f"not installed — {INSTALL_HINTS.get(tool, f'pip install {tool}')}",
36
+ "duration": 0.0,
37
+ "output": "",
38
+ }
39
+ try:
40
+ result = run_tool(tool, args, cwd=cwd)
41
+ duration = time.monotonic() - start
42
+ success = result.returncode == 0
43
+ return {
44
+ "step": name,
45
+ "tool": tool,
46
+ "status": "pass" if success else "fail",
47
+ "returncode": result.returncode,
48
+ "duration": round(duration, 2),
49
+ "output": (result.stdout + result.stderr).strip(),
50
+ }
51
+ except Exception as e:
52
+ return {
53
+ "step": name,
54
+ "tool": tool,
55
+ "status": "error",
56
+ "reason": str(e),
57
+ "duration": round(time.monotonic() - start, 2),
58
+ "output": "",
59
+ }
60
+
61
+
62
+ def run_command(
63
+ path: Optional[Path] = typer.Option(None, "--path", "-p", help="Project directory to run against"),
64
+ skip: Optional[List[str]] = typer.Option(None, "--skip", help="Steps to skip: generate, lint, benchmark, reflect"),
65
+ benchmark: bool = typer.Option(False, "--benchmark", help="Include benchmark step (skipped by default)"),
66
+ json_output: bool = typer.Option(False, "--json", help="Output summary JSON"),
67
+ notes: Optional[str] = typer.Option(None, "--notes", help="Notes passed to agentreflect"),
68
+ ) -> None:
69
+ """Run the full Agent Quality pipeline."""
70
+ root = path or find_project_root()
71
+ cwd_str = str(root)
72
+ skip_set = set(s.lower() for s in (skip or []))
73
+
74
+ # Benchmark is opt-in
75
+ if not benchmark:
76
+ skip_set.add("benchmark")
77
+
78
+ console.print(f"\n[bold]agentkit run[/bold] — project: {root}\n")
79
+
80
+ context_file = root / "CLAUDE.md"
81
+ results = []
82
+
83
+ # Step 1: generate
84
+ if "generate" not in skip_set:
85
+ console.print("[dim]→ agentmd generate ...[/dim]")
86
+ r = _run_step("generate", "agentmd", ["generate", cwd_str], cwd_str)
87
+ results.append(r)
88
+ else:
89
+ results.append({"step": "generate", "tool": "agentmd", "status": "skipped", "reason": "user skipped", "duration": 0.0})
90
+
91
+ # Step 2: lint context file
92
+ if "lint" not in skip_set:
93
+ lint_args = ["check-context", str(context_file)] if context_file.exists() else ["check-context", cwd_str]
94
+ console.print("[dim]→ agentlint check-context ...[/dim]")
95
+ r = _run_step("lint-context", "agentlint", lint_args, cwd_str)
96
+ results.append(r)
97
+
98
+ # Step 3: lint diffs
99
+ console.print("[dim]→ agentlint (diff) ...[/dim]")
100
+ r2 = _run_step("lint-diff", "agentlint", [cwd_str], cwd_str)
101
+ results.append(r2)
102
+ else:
103
+ results.append({"step": "lint-context", "tool": "agentlint", "status": "skipped", "reason": "user skipped", "duration": 0.0})
104
+ results.append({"step": "lint-diff", "tool": "agentlint", "status": "skipped", "reason": "user skipped", "duration": 0.0})
105
+
106
+ # Step 4: benchmark (opt-in)
107
+ if "benchmark" not in skip_set:
108
+ console.print("[dim]→ coderace benchmark ...[/dim]")
109
+ r = _run_step("benchmark", "coderace", ["benchmark", cwd_str], cwd_str)
110
+ results.append(r)
111
+ else:
112
+ results.append({"step": "benchmark", "tool": "coderace", "status": "skipped", "reason": "opt-in only (use --benchmark)", "duration": 0.0})
113
+
114
+ # Step 5: reflect
115
+ if "reflect" not in skip_set:
116
+ reflect_args = ["generate", "--notes", notes or "agentkit run completed", cwd_str]
117
+ console.print("[dim]→ agentreflect generate ...[/dim]")
118
+ r = _run_step("reflect", "agentreflect", reflect_args, cwd_str)
119
+ results.append(r)
120
+ else:
121
+ results.append({"step": "reflect", "tool": "agentreflect", "status": "skipped", "reason": "user skipped", "duration": 0.0})
122
+
123
+ # Display table
124
+ table = Table(title="Pipeline Results", show_header=True)
125
+ table.add_column("Step", style="bold")
126
+ table.add_column("Tool")
127
+ table.add_column("Status")
128
+ table.add_column("Duration")
129
+ table.add_column("Notes", max_width=50)
130
+
131
+ status_colors = {"pass": "green", "fail": "red", "skipped": "yellow", "error": "red"}
132
+
133
+ for r in results:
134
+ status = r.get("status", "unknown")
135
+ color = status_colors.get(status, "white")
136
+ duration = f"{r.get('duration', 0):.2f}s" if r.get("duration") else ""
137
+ note = r.get("reason", "") or (r.get("output", "")[:60] if r.get("output") else "")
138
+ table.add_row(
139
+ r["step"],
140
+ r.get("tool", ""),
141
+ f"[{color}]{status}[/{color}]",
142
+ duration,
143
+ note,
144
+ )
145
+
146
+ console.print()
147
+ console.print(table)
148
+
149
+ # Save last run
150
+ summary = {
151
+ "timestamp": datetime.now(timezone.utc).isoformat(),
152
+ "project": cwd_str,
153
+ "steps": results,
154
+ "total": len(results),
155
+ "passed": sum(1 for r in results if r.get("status") == "pass"),
156
+ "failed": sum(1 for r in results if r.get("status") == "fail"),
157
+ "skipped": sum(1 for r in results if r.get("status") == "skipped"),
158
+ }
159
+ try:
160
+ save_last_run(summary, root)
161
+ except Exception:
162
+ pass
163
+
164
+ if json_output:
165
+ console.print("\n[bold]JSON Output:[/bold]")
166
+ print(json.dumps(summary, indent=2))
167
+
168
+ # Final status
169
+ if summary["failed"] > 0:
170
+ console.print(f"\n[red]Pipeline completed with {summary['failed']} failure(s).[/red]")
171
+ raise typer.Exit(code=1)
172
+ else:
173
+ console.print(f"\n[green]Pipeline complete.[/green] {summary['passed']} passed, {summary['skipped']} skipped.\n")
@@ -0,0 +1,97 @@
1
+ """agentkit status command."""
2
+ from __future__ import annotations
3
+
4
+ import json
5
+ from pathlib import Path
6
+ from typing import Optional
7
+
8
+ import typer
9
+ from rich.console import Console
10
+ from rich.table import Table
11
+
12
+ from agentkit_cli.tools import tool_status
13
+ from agentkit_cli.config import find_project_root, config_exists, load_last_run
14
+
15
+ console = Console()
16
+
17
+
18
+ def status_command(
19
+ path: Optional[Path] = typer.Option(None, "--path", "-p", help="Project directory to check"),
20
+ json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
21
+ ) -> None:
22
+ """Show health status of the Agent Quality Toolkit."""
23
+ root = path or find_project_root()
24
+ console.print(f"\n[bold]agentkit status[/bold] — project: {root}\n")
25
+
26
+ # Tool table
27
+ tool_table = Table(title="Quartet Tools", show_header=True)
28
+ tool_table.add_column("Tool", style="bold")
29
+ tool_table.add_column("Status")
30
+ tool_table.add_column("Version")
31
+ tool_table.add_column("Path")
32
+
33
+ ts = tool_status()
34
+ for tool, info in ts.items():
35
+ if info["installed"]:
36
+ status_str = "[green]✓ installed[/green]"
37
+ version_str = info.get("version") or "—"
38
+ path_str = info.get("path") or "—"
39
+ else:
40
+ status_str = "[red]✗ missing[/red]"
41
+ version_str = "—"
42
+ path_str = "—"
43
+ tool_table.add_row(tool, status_str, version_str, path_str)
44
+
45
+ console.print(tool_table)
46
+
47
+ # Project files table
48
+ files_table = Table(title="Project Files", show_header=True)
49
+ files_table.add_column("File", style="bold")
50
+ files_table.add_column("Status")
51
+
52
+ config_ok = config_exists(root)
53
+ claude_ok = (root / "CLAUDE.md").exists()
54
+ last_run_ok = (root / ".agentkit-last-run.json").exists()
55
+
56
+ files_table.add_row(
57
+ ".agentkit.yaml",
58
+ "[green]✓ exists[/green]" if config_ok else "[yellow]✗ missing — run agentkit init[/yellow]",
59
+ )
60
+ files_table.add_row(
61
+ "CLAUDE.md",
62
+ "[green]✓ exists[/green]" if claude_ok else "[yellow]✗ missing[/yellow]",
63
+ )
64
+ files_table.add_row(
65
+ ".agentkit-last-run.json",
66
+ "[green]✓ exists[/green]" if last_run_ok else "[dim]not found[/dim]",
67
+ )
68
+
69
+ console.print(files_table)
70
+
71
+ # Last run summary
72
+ last_run = load_last_run(root)
73
+ if last_run:
74
+ lr_table = Table(title="Last Run Summary", show_header=True)
75
+ lr_table.add_column("Key", style="bold")
76
+ lr_table.add_column("Value")
77
+ lr_table.add_row("Timestamp", last_run.get("timestamp", "—"))
78
+ lr_table.add_row("Passed", str(last_run.get("passed", "—")))
79
+ lr_table.add_row("Failed", str(last_run.get("failed", "—")))
80
+ lr_table.add_row("Skipped", str(last_run.get("skipped", "—")))
81
+ console.print(lr_table)
82
+
83
+ if json_output:
84
+ output = {
85
+ "project": str(root),
86
+ "tools": ts,
87
+ "files": {
88
+ ".agentkit.yaml": config_ok,
89
+ "CLAUDE.md": claude_ok,
90
+ ".agentkit-last-run.json": last_run_ok,
91
+ },
92
+ "last_run": last_run,
93
+ }
94
+ console.print("\n[bold]JSON Output:[/bold]")
95
+ print(json.dumps(output, indent=2))
96
+
97
+ console.print()