kctl-grafana 0.2.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 (40) hide show
  1. kctl_grafana-0.2.0/.gitignore +33 -0
  2. kctl_grafana-0.2.0/PKG-INFO +17 -0
  3. kctl_grafana-0.2.0/README.md +171 -0
  4. kctl_grafana-0.2.0/pyproject.toml +45 -0
  5. kctl_grafana-0.2.0/skills/grafana-admin/SKILL.md +171 -0
  6. kctl_grafana-0.2.0/src/kctl_grafana/__init__.py +3 -0
  7. kctl_grafana-0.2.0/src/kctl_grafana/__main__.py +5 -0
  8. kctl_grafana-0.2.0/src/kctl_grafana/cli.py +146 -0
  9. kctl_grafana-0.2.0/src/kctl_grafana/commands/__init__.py +1 -0
  10. kctl_grafana-0.2.0/src/kctl_grafana/commands/alert.py +163 -0
  11. kctl_grafana-0.2.0/src/kctl_grafana/commands/annotation.py +120 -0
  12. kctl_grafana-0.2.0/src/kctl_grafana/commands/backup.py +175 -0
  13. kctl_grafana-0.2.0/src/kctl_grafana/commands/config_cmd.py +156 -0
  14. kctl_grafana-0.2.0/src/kctl_grafana/commands/dashboard.py +203 -0
  15. kctl_grafana-0.2.0/src/kctl_grafana/commands/datasource.py +146 -0
  16. kctl_grafana-0.2.0/src/kctl_grafana/commands/doctor_cmd.py +82 -0
  17. kctl_grafana-0.2.0/src/kctl_grafana/commands/folder.py +73 -0
  18. kctl_grafana-0.2.0/src/kctl_grafana/commands/health.py +112 -0
  19. kctl_grafana-0.2.0/src/kctl_grafana/commands/selftest.py +98 -0
  20. kctl_grafana-0.2.0/src/kctl_grafana/commands/skill_cmd.py +76 -0
  21. kctl_grafana-0.2.0/src/kctl_grafana/commands/status.py +82 -0
  22. kctl_grafana-0.2.0/src/kctl_grafana/commands/user.py +62 -0
  23. kctl_grafana-0.2.0/src/kctl_grafana/core/__init__.py +1 -0
  24. kctl_grafana-0.2.0/src/kctl_grafana/core/callbacks.py +52 -0
  25. kctl_grafana-0.2.0/src/kctl_grafana/core/client.py +70 -0
  26. kctl_grafana-0.2.0/src/kctl_grafana/core/config.py +222 -0
  27. kctl_grafana-0.2.0/src/kctl_grafana/core/exceptions.py +62 -0
  28. kctl_grafana-0.2.0/src/kctl_grafana/core/output.py +197 -0
  29. kctl_grafana-0.2.0/tests/__init__.py +1 -0
  30. kctl_grafana-0.2.0/tests/conftest.py +61 -0
  31. kctl_grafana-0.2.0/tests/test_alert.py +132 -0
  32. kctl_grafana-0.2.0/tests/test_annotation.py +74 -0
  33. kctl_grafana-0.2.0/tests/test_backup.py +130 -0
  34. kctl_grafana-0.2.0/tests/test_client.py +55 -0
  35. kctl_grafana-0.2.0/tests/test_dashboard.py +165 -0
  36. kctl_grafana-0.2.0/tests/test_datasource.py +113 -0
  37. kctl_grafana-0.2.0/tests/test_folder.py +77 -0
  38. kctl_grafana-0.2.0/tests/test_health.py +95 -0
  39. kctl_grafana-0.2.0/tests/test_smoke.py +79 -0
  40. kctl_grafana-0.2.0/tests/test_user.py +93 -0
@@ -0,0 +1,33 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ *.egg
6
+ dist/
7
+ build/
8
+ .eggs/
9
+
10
+ # Virtual environments
11
+ .venv/
12
+ venv/
13
+
14
+ # IDE
15
+ .idea/
16
+ .vscode/
17
+ *.swp
18
+ *.swo
19
+
20
+ # Testing
21
+ .pytest_cache/
22
+ .coverage
23
+ htmlcov/
24
+ .mypy_cache/
25
+ .ruff_cache/
26
+
27
+ # OS
28
+ .DS_Store
29
+ Thumbs.db
30
+
31
+ # Environment
32
+ .env
33
+ .env.local
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: kctl-grafana
3
+ Version: 0.2.0
4
+ Summary: Kodemeio Grafana CLI — manage Grafana monitoring platform
5
+ Requires-Python: >=3.12
6
+ Requires-Dist: httpx>=0.28.0
7
+ Requires-Dist: kctl-lib>=0.4.0
8
+ Requires-Dist: pydantic>=2.10.0
9
+ Requires-Dist: pyyaml>=6.0.2
10
+ Requires-Dist: rich>=13.9.0
11
+ Requires-Dist: typer>=0.15.0
12
+ Provides-Extra: dev
13
+ Requires-Dist: mypy>=1.14.0; extra == 'dev'
14
+ Requires-Dist: pytest-httpx>=0.35.0; extra == 'dev'
15
+ Requires-Dist: pytest>=8.3.0; extra == 'dev'
16
+ Requires-Dist: ruff>=0.9.0; extra == 'dev'
17
+ Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
@@ -0,0 +1,171 @@
1
+ # kctl-grafana
2
+
3
+ Grafana monitoring platform CLI — manage dashboards, datasources, alerts, users, and backups.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ uv tool install kctl-grafana
9
+ ```
10
+
11
+ Requires `kctl-lib>=0.4.0` (installed automatically).
12
+
13
+ ## Quick Start
14
+
15
+ ```bash
16
+ # Configure a profile
17
+ kctl-grafana config init
18
+
19
+ # Check Grafana connectivity
20
+ kctl-grafana health check
21
+
22
+ # View platform status
23
+ kctl-grafana status overview
24
+
25
+ # List all dashboards
26
+ kctl-grafana dashboard list
27
+
28
+ # Export a dashboard to file
29
+ kctl-grafana dashboard export <uid> --output my-dashboard.json
30
+
31
+ # Add a deploy annotation
32
+ kctl-grafana annotation add "Deployed v1.2.3" --tags deploy,production
33
+
34
+ # Backup all dashboards and datasources
35
+ kctl-grafana backup create --output ./grafana-backup
36
+ ```
37
+
38
+ ## Command Groups
39
+
40
+ | Group | Description | Key Commands |
41
+ |-------|-------------|--------------|
42
+ | `config` | Profile management | `init`, `add`, `use`, `show`, `validate`, `remove`, `set`, `profiles`, `current` |
43
+ | `health` | API health checks | `check`, `detailed` |
44
+ | `status` | Quick overview | `overview` |
45
+ | `dashboard` | Dashboard management | `list`, `show`, `export`, `import`, `search`, `star` |
46
+ | `datasource` | Datasource management | `list`, `show`, `test` |
47
+ | `alert` | Alert rule management | `list`, `show`, `silence`, `contacts` |
48
+ | `folder` | Folder organization | `list`, `create`, `delete` |
49
+ | `annotation` | Deploy markers & events | `add`, `list` |
50
+ | `user` | Organization user management | `list`, `add` |
51
+ | `backup` | Backup and restore | `create`, `restore` |
52
+ | `selftest` | Self-test diagnostics | `run` |
53
+
54
+ ## Command Reference
55
+
56
+ ### dashboard
57
+
58
+ ```bash
59
+ kctl-grafana dashboard list
60
+ kctl-grafana dashboard show <uid>
61
+ kctl-grafana dashboard export <uid> --output dashboard.json
62
+ kctl-grafana dashboard import dashboard.json --folder <folder-uid>
63
+ kctl-grafana dashboard search "kubernetes"
64
+ kctl-grafana dashboard star <uid>
65
+ kctl-grafana dashboard star <uid> --unstar
66
+ ```
67
+
68
+ ### datasource
69
+
70
+ ```bash
71
+ kctl-grafana datasource list
72
+ kctl-grafana datasource show <name>
73
+ kctl-grafana datasource test # Test all datasources
74
+ kctl-grafana datasource test <name> # Test a specific datasource
75
+ ```
76
+
77
+ ### alert
78
+
79
+ ```bash
80
+ kctl-grafana alert list
81
+ kctl-grafana alert show <uid>
82
+ kctl-grafana alert silence <uid> --duration 1h --comment "Maintenance window"
83
+ kctl-grafana alert contacts
84
+ ```
85
+
86
+ ### annotation
87
+
88
+ ```bash
89
+ kctl-grafana annotation add "Deploy v2.0" --tags deploy,prod
90
+ kctl-grafana annotation add "Incident" --dashboard <uid>
91
+ kctl-grafana annotation list --from 24h --tags deploy
92
+ ```
93
+
94
+ ### backup
95
+
96
+ ```bash
97
+ kctl-grafana backup create --output ./backup-2026-04-05
98
+ kctl-grafana backup restore ./backup-2026-04-05
99
+ kctl-grafana backup restore ./backup-2026-04-05 --skip-datasources
100
+ ```
101
+
102
+ ### folder
103
+
104
+ ```bash
105
+ kctl-grafana folder list
106
+ kctl-grafana folder create "Production Dashboards"
107
+ kctl-grafana folder delete <uid> --force
108
+ ```
109
+
110
+ ### user
111
+
112
+ ```bash
113
+ kctl-grafana user list
114
+ kctl-grafana user add user@example.com --role Editor
115
+ ```
116
+
117
+ ## Global Options
118
+
119
+ | Option | Short | Description |
120
+ |--------|-------|-------------|
121
+ | `--profile` | `-p` | Config profile name |
122
+ | `--format` | `-f` | Output format: `pretty`, `json`, `csv`, `yaml` |
123
+ | `--json` | | Shortcut for `--format json` |
124
+ | `--quiet` | `-q` | Suppress info messages |
125
+ | `--no-header` | | Omit headers in CSV output |
126
+ | `--debug` | | Enable debug logging |
127
+ | `--url` | | Grafana API URL override |
128
+ | `--api-key` | | Grafana API key override |
129
+ | `--version` | `-V` | Show version and exit |
130
+
131
+ ## Configuration
132
+
133
+ Config lives in `~/.config/kodemeio/config.yaml` under the `grafana` service key.
134
+
135
+ ```bash
136
+ # Interactive setup
137
+ kctl-grafana config init
138
+
139
+ # Add a named profile
140
+ kctl-grafana config add --profile production \
141
+ --url https://grafana.kodeme.io \
142
+ --api-key <service-account-token>
143
+
144
+ # Switch active profile
145
+ kctl-grafana config use production
146
+
147
+ # Show current config (secrets masked)
148
+ kctl-grafana config show
149
+ ```
150
+
151
+ Example `~/.config/kodemeio/config.yaml` entry:
152
+
153
+ ```yaml
154
+ grafana:
155
+ default_profile: production
156
+ profiles:
157
+ production:
158
+ url: https://grafana.kodeme.io
159
+ api_key: ${GRAFANA_API_KEY}
160
+ ```
161
+
162
+ ## Development
163
+
164
+ ```bash
165
+ cd packages/kctl-grafana
166
+ uv sync --all-extras
167
+ uv run pytest tests/ -v
168
+ uv run mypy src/
169
+ uv run ruff check src/
170
+ uv build
171
+ ```
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "kctl-grafana"
7
+ version = "0.2.0"
8
+ description = "Kodemeio Grafana CLI — manage Grafana monitoring platform"
9
+ requires-python = ">=3.12"
10
+ dependencies = [
11
+ "kctl-lib>=0.4.0",
12
+ "typer>=0.15.0",
13
+ "rich>=13.9.0",
14
+ "pydantic>=2.10.0",
15
+ "pyyaml>=6.0.2",
16
+ "httpx>=0.28.0",
17
+ ]
18
+
19
+ [project.optional-dependencies]
20
+ dev = [
21
+ "pytest>=8.3.0",
22
+ "pytest-httpx>=0.35.0",
23
+ "ruff>=0.9.0",
24
+ "mypy>=1.14.0",
25
+ "types-PyYAML>=6.0.0",
26
+ ]
27
+
28
+ [project.scripts]
29
+ kctl-grafana = "kctl_grafana.cli:_run"
30
+
31
+ [tool.uv.sources]
32
+ kctl-lib = { workspace = true }
33
+
34
+ [project.entry-points."kctl_grafana.plugins"]
35
+
36
+ [tool.hatch.build.targets.wheel]
37
+ packages = ["src/kctl_grafana"]
38
+
39
+ [tool.ruff]
40
+ target-version = "py312"
41
+ line-length = 120
42
+
43
+ [tool.mypy]
44
+ python_version = "3.12"
45
+ strict = true
@@ -0,0 +1,171 @@
1
+ ---
2
+ name: grafana-admin
3
+ description: >
4
+ Grafana monitoring platform administration via kctl-grafana CLI (12 groups, ~33 commands).
5
+ MUST use for ANY kctl-grafana operation.
6
+ Triggers on: "alert", "annotation", "backup", "check", "config", "contacts", "dashboard", "datasource", "deploy", "detailed", "export", "folder", "generate", "health", "import", "init", "kctl-grafana", "overview", "profile", "remove", "restore", "search", "selftest", "silence", "skill", "star", "status", "test", "user".
7
+ Auto-generated: 2026-04-05
8
+ registry_hash: bf42f2813358
9
+ ---
10
+
11
+ # grafana-admin — kctl-grafana CLI Reference
12
+
13
+ > Auto-generated from `kctl-grafana` command registry. Do not edit manually.
14
+ > To regenerate: `kctl-grafana skill generate`
15
+ > To add custom content: edit `SKILL.extra.md` in the same directory.
16
+
17
+ ## Overview
18
+
19
+ **CLI:** `kctl-grafana`
20
+ **Command groups:** 12
21
+ **Total commands:** ~33
22
+ **Install:** `cd cli && uv tool install --editable .`
23
+
24
+ ## Global Options
25
+
26
+ | Flag | Description |
27
+ |------|-------------|
28
+ | `--json` | JSON output |
29
+ | `--quiet`, `-q` | Suppress info messages |
30
+ | `--format`, `-f` | Output format: pretty/json/csv/yaml |
31
+ | `--no-header` | Omit CSV header row |
32
+ | `--profile`, `-p` | Config profile name |
33
+ | `--version`, `-V` | Show version |
34
+
35
+ ## Command Reference
36
+
37
+ ### `kctl-grafana alert`
38
+
39
+ Alert rule management.
40
+
41
+ | Command | Description |
42
+ |---------|-------------|
43
+ | `alert contacts` | List notification contact points. |
44
+ | `alert list` | List alert rules with current state. |
45
+ | `alert show <uid>` | Show alert rule details. |
46
+ | `alert silence <uid> [--duration] [--comment]` | Silence an alert rule for a given duration. |
47
+
48
+ ### `kctl-grafana annotation`
49
+
50
+ Annotation management (deploy markers, events).
51
+
52
+ | Command | Description |
53
+ |---------|-------------|
54
+ | `annotation add <text> [--tags] [--dashboard_uid]` | Add an annotation (useful for deploy markers). |
55
+ | `annotation list [--from_time] [--to_time] [--tags] [--limit]` | List recent annotations. |
56
+
57
+ ### `kctl-grafana backup`
58
+
59
+ Backup and restore dashboards and datasources.
60
+
61
+ | Command | Description |
62
+ |---------|-------------|
63
+ | `backup create [--output_dir]` | Export all dashboards and datasources to a backup directory. |
64
+ | `backup restore <backup_dir> [--skip_datasources] [--skip_dashboards]` | Restore dashboards and datasources from a backup directory. |
65
+
66
+ ### `kctl-grafana config`
67
+
68
+ Manage CLI configuration and profiles.
69
+
70
+ | Command | Description |
71
+ |---------|-------------|
72
+ | `config export` | Export current configuration as YAML. |
73
+ | `config init [--url] [--api_key] [--org_id] [--name]` | Initialize CLI configuration. |
74
+ | `config remove <name> [--force]` | Remove a profile. |
75
+ | `config show` | Show configuration (keys masked). |
76
+ | `config test` | Test API connection. |
77
+ | `config use <name>` | Switch default profile. |
78
+
79
+ ### `kctl-grafana dashboard`
80
+
81
+ Dashboard management.
82
+
83
+ | Command | Description |
84
+ |---------|-------------|
85
+ | `dashboard export <uid> [--output_file]` | Export dashboard JSON to file. |
86
+ | `dashboard import <file_path> [--folder_uid] [--overwrite]` | Import dashboard from JSON file. |
87
+ | `dashboard list` | List all dashboards. |
88
+ | `dashboard search <query>` | Search dashboards by name or tag. |
89
+ | `dashboard show <uid>` | Show dashboard metadata and panel summary. |
90
+ | `dashboard star <uid> [--unstar]` | Star or unstar a dashboard. |
91
+
92
+ ### `kctl-grafana datasource`
93
+
94
+ Datasource management.
95
+
96
+ | Command | Description |
97
+ |---------|-------------|
98
+ | `datasource list` | List all datasources with type and status. |
99
+ | `datasource show <name>` | Show datasource configuration details. |
100
+ | `datasource test [--name]` | Test datasource connectivity. |
101
+
102
+ ### `kctl-grafana folder`
103
+
104
+ Folder organization.
105
+
106
+ | Command | Description |
107
+ |---------|-------------|
108
+ | `folder create <title> [--uid]` | Create a new folder. |
109
+ | `folder delete <uid> [--force]` | Delete a folder and all its dashboards. |
110
+ | `folder list` | List all folders. |
111
+
112
+ ### `kctl-grafana health`
113
+
114
+ Health checks for Grafana API.
115
+
116
+ | Command | Description |
117
+ |---------|-------------|
118
+ | `health check` | Check Grafana API connectivity, version, and org info. |
119
+ | `health detailed` | Detailed health check including all datasources. |
120
+
121
+ ### `kctl-grafana selftest`
122
+
123
+ Self-test diagnostics.
124
+
125
+ | Command | Description |
126
+ |---------|-------------|
127
+ | `selftest run` | Run diagnostic checks for kctl-grafana. |
128
+
129
+ ### `kctl-grafana skill`
130
+
131
+ Claude Code skill management.
132
+
133
+ | Command | Description |
134
+ |---------|-------------|
135
+ | `skill generate [--output] [--install] [--check]` | Auto-generate SKILL.md from CLI command registry. |
136
+
137
+ **Examples:**
138
+ ```bash
139
+ kctl-grafana skill generate
140
+ kctl-grafana skill generate --install
141
+ kctl-grafana skill generate --check
142
+ ```
143
+
144
+ ### `kctl-grafana status`
145
+
146
+ Quick status overview.
147
+
148
+ | Command | Description |
149
+ |---------|-------------|
150
+ | `status overview` | Show Grafana status overview: dashboard count, datasource health, active alerts, version. |
151
+
152
+ ### `kctl-grafana user`
153
+
154
+ Organization user management.
155
+
156
+ | Command | Description |
157
+ |---------|-------------|
158
+ | `user add <email> [--role]` | Add a user to the organization. |
159
+ | `user list` | List organization users. |
160
+
161
+ ## Configuration
162
+
163
+ Shared config: `~/.config/kodemeio/config.yaml`
164
+
165
+ ```bash
166
+ kctl-grafana config init # Interactive setup
167
+ kctl-grafana config show # Show current config
168
+ kctl-grafana config profiles # List profiles
169
+ kctl-grafana config current # Show active profile
170
+ kctl-grafana config validate # Verify config
171
+ ```
@@ -0,0 +1,3 @@
1
+ """kctl-grafana: Kodemeio Grafana CLI."""
2
+
3
+ __version__ = "0.2.0"
@@ -0,0 +1,5 @@
1
+ """Allow running as: python -m kctl_grafana."""
2
+
3
+ from kctl_grafana.cli import _run
4
+
5
+ _run()
@@ -0,0 +1,146 @@
1
+ """Main CLI entry point for kctl-grafana."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ from typing import Annotated
7
+
8
+ import typer
9
+ from kctl_lib import KctlError, handle_cli_error
10
+
11
+ from kctl_grafana import __version__
12
+ from kctl_grafana.commands.alert import app as alert_app
13
+ from kctl_grafana.commands.annotation import app as annotation_app
14
+ from kctl_grafana.commands.backup import app as backup_app
15
+ from kctl_grafana.commands.config_cmd import app as config_app
16
+ from kctl_grafana.commands.dashboard import app as dashboard_app
17
+ from kctl_grafana.commands.datasource import app as datasource_app
18
+ from kctl_grafana.commands.folder import app as folder_app
19
+ from kctl_grafana.commands.health import app as health_app
20
+ from kctl_grafana.commands.selftest import app as selftest_app
21
+ from kctl_grafana.commands.status import app as status_app
22
+ from kctl_grafana.commands.user import app as user_app
23
+ from kctl_grafana.core.callbacks import AppContext
24
+ from kctl_grafana.commands.doctor_cmd import app as doctor_app
25
+ from kctl_grafana.commands.skill_cmd import app as skill_app
26
+ from kctl_lib.self_update import notify_if_outdated
27
+
28
+
29
+ def version_callback(value: bool) -> None:
30
+ if value:
31
+ typer.echo(f"kctl-grafana {__version__}")
32
+ raise typer.Exit()
33
+
34
+
35
+ app = typer.Typer(
36
+ name="kctl-grafana",
37
+ help="Kodemeio Grafana CLI - manage your Grafana monitoring platform.",
38
+ no_args_is_help=True,
39
+ rich_markup_mode="rich",
40
+ pretty_exceptions_enable=False,
41
+ )
42
+
43
+
44
+ @app.callback()
45
+ def main(
46
+ ctx: typer.Context,
47
+ json_output: Annotated[bool, typer.Option("--json", help="Output as JSON (shortcut for --format json)")] = False,
48
+ quiet: Annotated[bool, typer.Option("--quiet", "-q", help="Suppress info messages")] = False,
49
+ output_format: Annotated[
50
+ str, typer.Option("--format", "-f", help="Output format: pretty, json, csv, yaml")
51
+ ] = "pretty",
52
+ no_header: Annotated[bool, typer.Option("--no-header", help="Omit headers in CSV output")] = False,
53
+ debug: Annotated[bool, typer.Option("--debug", help="Enable debug logging")] = False,
54
+ profile: Annotated[str | None, typer.Option("--profile", "-p", help="Config profile name")] = None,
55
+ url: Annotated[str | None, typer.Option("--url", help="API URL override")] = None,
56
+ api_key: Annotated[str | None, typer.Option("--api-key", help="API key override")] = None,
57
+ version: Annotated[
58
+ bool, typer.Option("--version", "-V", callback=version_callback, is_eager=True, help="Show version")
59
+ ] = False,
60
+ ) -> None:
61
+ """Kodemeio Grafana CLI."""
62
+ import os
63
+
64
+ if debug:
65
+ os.environ["KCTL_DEBUG"] = "1"
66
+
67
+ effective_format = "json" if json_output else output_format
68
+
69
+ ctx.ensure_object(dict)
70
+ ctx.obj = AppContext(
71
+ json_mode=json_output or effective_format == "json",
72
+ quiet=quiet,
73
+ format=effective_format,
74
+ no_header=no_header,
75
+ debug=debug,
76
+ profile=profile,
77
+ url_override=url,
78
+ api_key_override=api_key,
79
+ )
80
+ notify_if_outdated(ctx.obj.output, "kctl-grafana", __version__)
81
+
82
+
83
+ # Command groups
84
+ app.add_typer(config_app, name="config")
85
+ app.add_typer(health_app, name="health")
86
+ app.add_typer(status_app, name="status")
87
+ app.add_typer(dashboard_app, name="dashboard")
88
+ app.add_typer(datasource_app, name="datasource")
89
+ app.add_typer(alert_app, name="alert")
90
+ app.add_typer(folder_app, name="folder")
91
+ app.add_typer(annotation_app, name="annotation")
92
+ app.add_typer(user_app, name="user")
93
+ app.add_typer(backup_app, name="backup")
94
+ app.add_typer(selftest_app, name="selftest")
95
+ app.add_typer(doctor_app, name="doctor")
96
+ app.add_typer(skill_app, name="skill", hidden=True)
97
+
98
+
99
+ @app.command("self-update")
100
+ def self_update_cmd(ctx: typer.Context) -> None:
101
+ """Check for updates and upgrade kctl-grafana."""
102
+ actx = ctx.obj
103
+ out = actx.output
104
+
105
+ from kctl_lib.self_update import check_update
106
+ from kctl_lib.self_update import update as do_update
107
+
108
+ latest = check_update("kctl-grafana", __version__)
109
+ if latest:
110
+ out.info(f"Updating to {latest}...")
111
+ do_update("kctl-grafana")
112
+ out.success(f"Updated to {latest}")
113
+ else:
114
+ out.success("Already up to date")
115
+
116
+
117
+ @app.command()
118
+ def completions(
119
+ shell: Annotated[str, typer.Argument(help="Shell type: zsh, bash, fish")] = "zsh",
120
+ install: Annotated[bool, typer.Option("--install", help="Install completions")] = False,
121
+ ) -> None:
122
+ """Generate or install shell completions."""
123
+ from kctl_lib.completions import get_completion_script, install_completions
124
+
125
+ if install:
126
+ path = install_completions("kctl-grafana", shell)
127
+ if path:
128
+ typer.echo(f"Completions installed to {path}")
129
+ else:
130
+ typer.echo(f"Could not install completions for {shell}", err=True)
131
+ raise typer.Exit(code=1)
132
+ else:
133
+ script = get_completion_script("kctl-grafana", shell)
134
+ typer.echo(script)
135
+
136
+
137
+ def _run() -> None:
138
+ """Entry point with error handling."""
139
+ try:
140
+ app()
141
+ except KctlError as e:
142
+ handle_cli_error(e)
143
+
144
+
145
+ if __name__ == "__main__":
146
+ _run()
@@ -0,0 +1 @@
1
+ """CLI command modules for kctl-grafana."""