navig-github 0.2.4__tar.gz → 0.3.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 (51) hide show
  1. navig_github-0.3.0/PKG-INFO +165 -0
  2. navig_github-0.3.0/README.md +133 -0
  3. navig_github-0.3.0/navig_github/_typed_path.py +28 -0
  4. navig_github-0.3.0/navig_github/cli.py +19 -0
  5. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/commands/github.py +60 -52
  6. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/analytics.py +1 -1
  7. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/cli.py +16 -15
  8. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/incremental.py +1 -1
  9. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/scheduler.py +1 -1
  10. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/templates.py +1 -1
  11. navig_github-0.3.0/navig_github.egg-info/PKG-INFO +165 -0
  12. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github.egg-info/SOURCES.txt +2 -0
  13. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github.egg-info/entry_points.txt +3 -0
  14. navig_github-0.3.0/navig_github.egg-info/requires.txt +10 -0
  15. {navig_github-0.2.4 → navig_github-0.3.0}/pyproject.toml +30 -11
  16. navig_github-0.2.4/PKG-INFO +0 -75
  17. navig_github-0.2.4/README.md +0 -48
  18. navig_github-0.2.4/navig_github.egg-info/PKG-INFO +0 -75
  19. navig_github-0.2.4/navig_github.egg-info/requires.txt +0 -4
  20. {navig_github-0.2.4 → navig_github-0.3.0}/LICENSE +0 -0
  21. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/__init__.py +0 -0
  22. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/commands/__init__.py +0 -0
  23. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/__init__.py +0 -0
  24. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/__main__.py +0 -0
  25. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/attachments.py +0 -0
  26. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/config.py +0 -0
  27. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/diff.py +0 -0
  28. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/gists.py +0 -0
  29. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/git_utils.py +0 -0
  30. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/github_api.py +0 -0
  31. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/mirror.py +0 -0
  32. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/models.py +0 -0
  33. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/notifications.py +0 -0
  34. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/restore.py +0 -0
  35. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/rich_utils.py +0 -0
  36. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/transfer.py +0 -0
  37. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/validation.py +0 -0
  38. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/engine/verify.py +0 -0
  39. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/plugin.py +0 -0
  40. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github/skills/github-ops/SKILL.md +0 -0
  41. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github.egg-info/dependency_links.txt +0 -0
  42. {navig_github-0.2.4 → navig_github-0.3.0}/navig_github.egg-info/top_level.txt +0 -0
  43. {navig_github-0.2.4 → navig_github-0.3.0}/setup.cfg +0 -0
  44. {navig_github-0.2.4 → navig_github-0.3.0}/tests/test_analytics_no_wipe.py +0 -0
  45. {navig_github-0.2.4 → navig_github-0.3.0}/tests/test_backup_history_wire.py +0 -0
  46. {navig_github-0.2.4 → navig_github-0.3.0}/tests/test_config.py +0 -0
  47. {navig_github-0.2.4 → navig_github-0.3.0}/tests/test_debrand_stores.py +0 -0
  48. {navig_github-0.2.4 → navig_github-0.3.0}/tests/test_incremental.py +0 -0
  49. {navig_github-0.2.4 → navig_github-0.3.0}/tests/test_scheduler_migration.py +0 -0
  50. {navig_github-0.2.4 → navig_github-0.3.0}/tests/test_scheduler_no_wipe.py +0 -0
  51. {navig_github-0.2.4 → navig_github-0.3.0}/tests/test_templates_no_wipe.py +0 -0
@@ -0,0 +1,165 @@
1
+ Metadata-Version: 2.4
2
+ Name: navig-github
3
+ Version: 0.3.0
4
+ Summary: The full GitHub toolbox (backup, mirror, export, manage): its own navig-github command, and `navig github` inside navig.
5
+ Author-email: NAVIG Development Team <opensource@navig.run>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://navig.run
8
+ Project-URL: Documentation, https://navig.run/docs
9
+ Keywords: navig,cli,agent,automation,plugin,github,git,backup,mirror
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Utilities
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: navig-sdk>=2.7.0
23
+ Requires-Dist: typer>=0.14.0
24
+ Requires-Dist: rich>=13.7.0
25
+ Requires-Dist: pyyaml>=6.0
26
+ Requires-Dist: requests>=2.31.0
27
+ Requires-Dist: python-dotenv>=1.0.0
28
+ Requires-Dist: schedule>=1.2.0
29
+ Provides-Extra: vault
30
+ Requires-Dist: navig-vault>=0.7.0; extra == "vault"
31
+ Dynamic: license-file
32
+
33
+ # navig-github
34
+
35
+ <!-- navig:plugin-card:start -->
36
+ <!-- Generated by scripts/gen_plugin_catalog.py — edit the plugin's pyproject.toml, not this block. -->
37
+
38
+ > The full GitHub toolbox (backup, mirror, export, manage): its own navig-github command, and `navig github` inside navig.
39
+
40
+ **Works on its own** — its own CLI, no navig required · v0.3.0 · [PyPI](https://pypi.org/project/navig-github/)
41
+
42
+ **On its own** (no navig needed)
43
+
44
+ ```bash
45
+ pip install navig-github
46
+ navig-github --help # no navig needed
47
+ ```
48
+
49
+ **With navig**
50
+
51
+ ```bash
52
+ pip install "navig[github]"
53
+ navig github --help
54
+ ```
55
+
56
+ <details><summary>Commands</summary>
57
+
58
+ | Command | What it does |
59
+ |---|---|
60
+ | `navig github analytics` | Analyze backup directory and generate statistics report. |
61
+ | `navig github analytics-history` | Show backup history and statistics. |
62
+ | `navig github attachments` | Download attachments (images, files) from issues and pull requests. |
63
+ | `navig github backup` | 📦 Clone / mirror every repo for a user (or --org organisation). |
64
+ | `navig github clone` | ⬇️ Clone a single repository (with the full toolbox if available, else plain git). |
65
+ | `navig github config-delete` | Delete a saved backup profile. |
66
+ | `navig github config-export` | Export a profile to a file for sharing. |
67
+ | `navig github config-import` | Import a profile from a file. |
68
+ | `navig github config-list` | List all saved backup profiles. |
69
+ | `navig github config-load` | Load and display a saved backup profile. |
70
+ | `navig github config-save` | Save a backup configuration profile. |
71
+ | `navig github delete` | Delete a GitHub repository. |
72
+ | `navig github diff` | Compare two backup directories and show differences. |
73
+ | `navig github discussions` | Export all discussions from a GitHub repository. |
74
+ | `navig github followers` | Export followers (and optionally following) for a GitHub user. |
75
+ | `navig github gists` | Backup all gists for a user. |
76
+ | `navig github issues` | Export all issues from a GitHub repository. |
77
+ | `navig github labels` | Export all labels from a GitHub repository. |
78
+ | `navig github milestones` | Export all milestones from a GitHub repository. |
79
+ | `navig github notify-status` | Show notification configuration status. |
80
+ | `navig github notify-test` | Test all configured notification providers. |
81
+ | `navig github org` | Backup all repositories for a GitHub organization. |
82
+ | `navig github profile` | Export GitHub user profile information. |
83
+ | `navig github projects` | Export GitHub Projects (v2) for a user/org or repository. |
84
+ | `navig github pulls` | Export all pull requests from a GitHub repository. |
85
+ | `navig github releases` | Download all releases and assets from a GitHub repository. |
86
+ | `navig github repo` | Backup a single GitHub repository with optional data exports. |
87
+ | `navig github restore-issues` | Restore issues from a backup to a GitHub repository. |
88
+ | `navig github restore-labels` | Restore labels from a backup to a GitHub repository. |
89
+ | `navig github restore-milestones` | Restore milestones from a backup to a GitHub repository. |
90
+ | `navig github restore-releases` | Restore releases from a backup to a GitHub repository. |
91
+ | `navig github schedule-add` | Add a scheduled backup. |
92
+ | `navig github schedule-list` | List all scheduled backups. |
93
+ | `navig github schedule-remove` | Remove a scheduled backup. |
94
+ | `navig github schedule-run` | Run the backup scheduler daemon. |
95
+ | `navig github search` | 🔍 Search GitHub and clone matching repositories. |
96
+ | `navig github secrets` | Export repository secrets (names only, not values). |
97
+ | `navig github snapshot` | Create a snapshot of the current backup state for later comparison. |
98
+ | `navig github starred` | Mirror all repositories starred by a user. |
99
+ | `navig github status` | ℹ️ Show engine installation status and token configuration. |
100
+ | `navig github template-create` | Create a custom backup template. |
101
+ | `navig github template-delete` | Delete a custom template (built-in templates cannot be deleted). |
102
+ | `navig github template-show` | Show details of a backup template. |
103
+ | `navig github template-use` | Run a backup using a template. |
104
+ | `navig github templates` | List available backup templates. |
105
+ | `navig github token remove` | 🗑 Remove the stored GitHub token. |
106
+ | `navig github token set` | 🔑 Save a GitHub token for navig github to use automatically. |
107
+ | `navig github token show` | 🔍 Display where the current GitHub token comes from (masked). |
108
+ | `navig github transfer` | Transfer repository(ies) to a GitHub organization. |
109
+ | `navig github user` | Backup all repositories for a GitHub user. |
110
+ | `navig github verify` | Verify backup integrity. |
111
+ | `navig github watched` | Mirror all repositories watched by a user. |
112
+ | `navig github webhooks` | Export webhooks configuration from a GitHub repository. |
113
+ | `navig github wiki` | Backup a repository's wiki (if it exists). |
114
+ | `navig github workflows` | Backup GitHub Actions workflows from a repository. |
115
+
116
+ </details>
117
+
118
+ <!-- navig:plugin-card:end -->
119
+
120
+ NAVIG GitHub module — the **full GitHub toolbox** (backup, mirror, export, restore,
121
+ analytics, scheduling) wired natively into `navig github`. A first-party navig plugin
122
+ (free, toggleable).
123
+
124
+ **License:** Apache-2.0 · **Version:** 0.2.0
125
+
126
+ ## What it is
127
+
128
+ `navig-github` is a **first-party NAVIG plugin** — it extends NAVIG itself (CLI verbs +
129
+ gateway routes), and it is free and toggleable. Plugins are different from
130
+ *blocks*: a plugin adds capabilities to the platform; a block is an outcome you
131
+ *apply* with `navig apply`.
132
+
133
+ The GitHub engine is bundled in-package (`navig_github.engine`) and
134
+ mounted **in-process**: every engine command is a `navig github` subcommand, and a
135
+ group callback injects the vault token (`github_token`) into `GITHUB_TOKEN` so the
136
+ whole surface authenticates automatically.
137
+
138
+ ```
139
+ navig github token set <PAT> # store the token in the navig vault, once
140
+ navig github backup <user> -y # mirror every repo (curated wrapper)
141
+ navig github issues owner/repo # export issues (in-process)
142
+ navig github releases owner/repo # download releases + assets
143
+ navig github verify ./mirrors # backup integrity check
144
+ navig github --help # the full surface, grouped by panels
145
+ ```
146
+
147
+ ## Install
148
+
149
+ It ships in the NAVIG monorepo and loads automatically when NAVIG is installed.
150
+ To add/enable it explicitly:
151
+
152
+ ```
153
+ navig plugin add navig-github
154
+ ```
155
+
156
+ Check wiring and toggle state:
157
+
158
+ ```
159
+ navig store list
160
+ ```
161
+
162
+ ## Development
163
+
164
+ This package lives in the NAVIG monorepo under `plugins/navig-github/`. It registers via
165
+ the `navig.plugins` entry-point group; CLI verbs register via `navig.commands`.
@@ -0,0 +1,133 @@
1
+ # navig-github
2
+
3
+ <!-- navig:plugin-card:start -->
4
+ <!-- Generated by scripts/gen_plugin_catalog.py — edit the plugin's pyproject.toml, not this block. -->
5
+
6
+ > The full GitHub toolbox (backup, mirror, export, manage): its own navig-github command, and `navig github` inside navig.
7
+
8
+ **Works on its own** — its own CLI, no navig required · v0.3.0 · [PyPI](https://pypi.org/project/navig-github/)
9
+
10
+ **On its own** (no navig needed)
11
+
12
+ ```bash
13
+ pip install navig-github
14
+ navig-github --help # no navig needed
15
+ ```
16
+
17
+ **With navig**
18
+
19
+ ```bash
20
+ pip install "navig[github]"
21
+ navig github --help
22
+ ```
23
+
24
+ <details><summary>Commands</summary>
25
+
26
+ | Command | What it does |
27
+ |---|---|
28
+ | `navig github analytics` | Analyze backup directory and generate statistics report. |
29
+ | `navig github analytics-history` | Show backup history and statistics. |
30
+ | `navig github attachments` | Download attachments (images, files) from issues and pull requests. |
31
+ | `navig github backup` | 📦 Clone / mirror every repo for a user (or --org organisation). |
32
+ | `navig github clone` | ⬇️ Clone a single repository (with the full toolbox if available, else plain git). |
33
+ | `navig github config-delete` | Delete a saved backup profile. |
34
+ | `navig github config-export` | Export a profile to a file for sharing. |
35
+ | `navig github config-import` | Import a profile from a file. |
36
+ | `navig github config-list` | List all saved backup profiles. |
37
+ | `navig github config-load` | Load and display a saved backup profile. |
38
+ | `navig github config-save` | Save a backup configuration profile. |
39
+ | `navig github delete` | Delete a GitHub repository. |
40
+ | `navig github diff` | Compare two backup directories and show differences. |
41
+ | `navig github discussions` | Export all discussions from a GitHub repository. |
42
+ | `navig github followers` | Export followers (and optionally following) for a GitHub user. |
43
+ | `navig github gists` | Backup all gists for a user. |
44
+ | `navig github issues` | Export all issues from a GitHub repository. |
45
+ | `navig github labels` | Export all labels from a GitHub repository. |
46
+ | `navig github milestones` | Export all milestones from a GitHub repository. |
47
+ | `navig github notify-status` | Show notification configuration status. |
48
+ | `navig github notify-test` | Test all configured notification providers. |
49
+ | `navig github org` | Backup all repositories for a GitHub organization. |
50
+ | `navig github profile` | Export GitHub user profile information. |
51
+ | `navig github projects` | Export GitHub Projects (v2) for a user/org or repository. |
52
+ | `navig github pulls` | Export all pull requests from a GitHub repository. |
53
+ | `navig github releases` | Download all releases and assets from a GitHub repository. |
54
+ | `navig github repo` | Backup a single GitHub repository with optional data exports. |
55
+ | `navig github restore-issues` | Restore issues from a backup to a GitHub repository. |
56
+ | `navig github restore-labels` | Restore labels from a backup to a GitHub repository. |
57
+ | `navig github restore-milestones` | Restore milestones from a backup to a GitHub repository. |
58
+ | `navig github restore-releases` | Restore releases from a backup to a GitHub repository. |
59
+ | `navig github schedule-add` | Add a scheduled backup. |
60
+ | `navig github schedule-list` | List all scheduled backups. |
61
+ | `navig github schedule-remove` | Remove a scheduled backup. |
62
+ | `navig github schedule-run` | Run the backup scheduler daemon. |
63
+ | `navig github search` | 🔍 Search GitHub and clone matching repositories. |
64
+ | `navig github secrets` | Export repository secrets (names only, not values). |
65
+ | `navig github snapshot` | Create a snapshot of the current backup state for later comparison. |
66
+ | `navig github starred` | Mirror all repositories starred by a user. |
67
+ | `navig github status` | ℹ️ Show engine installation status and token configuration. |
68
+ | `navig github template-create` | Create a custom backup template. |
69
+ | `navig github template-delete` | Delete a custom template (built-in templates cannot be deleted). |
70
+ | `navig github template-show` | Show details of a backup template. |
71
+ | `navig github template-use` | Run a backup using a template. |
72
+ | `navig github templates` | List available backup templates. |
73
+ | `navig github token remove` | 🗑 Remove the stored GitHub token. |
74
+ | `navig github token set` | 🔑 Save a GitHub token for navig github to use automatically. |
75
+ | `navig github token show` | 🔍 Display where the current GitHub token comes from (masked). |
76
+ | `navig github transfer` | Transfer repository(ies) to a GitHub organization. |
77
+ | `navig github user` | Backup all repositories for a GitHub user. |
78
+ | `navig github verify` | Verify backup integrity. |
79
+ | `navig github watched` | Mirror all repositories watched by a user. |
80
+ | `navig github webhooks` | Export webhooks configuration from a GitHub repository. |
81
+ | `navig github wiki` | Backup a repository's wiki (if it exists). |
82
+ | `navig github workflows` | Backup GitHub Actions workflows from a repository. |
83
+
84
+ </details>
85
+
86
+ <!-- navig:plugin-card:end -->
87
+
88
+ NAVIG GitHub module — the **full GitHub toolbox** (backup, mirror, export, restore,
89
+ analytics, scheduling) wired natively into `navig github`. A first-party navig plugin
90
+ (free, toggleable).
91
+
92
+ **License:** Apache-2.0 · **Version:** 0.2.0
93
+
94
+ ## What it is
95
+
96
+ `navig-github` is a **first-party NAVIG plugin** — it extends NAVIG itself (CLI verbs +
97
+ gateway routes), and it is free and toggleable. Plugins are different from
98
+ *blocks*: a plugin adds capabilities to the platform; a block is an outcome you
99
+ *apply* with `navig apply`.
100
+
101
+ The GitHub engine is bundled in-package (`navig_github.engine`) and
102
+ mounted **in-process**: every engine command is a `navig github` subcommand, and a
103
+ group callback injects the vault token (`github_token`) into `GITHUB_TOKEN` so the
104
+ whole surface authenticates automatically.
105
+
106
+ ```
107
+ navig github token set <PAT> # store the token in the navig vault, once
108
+ navig github backup <user> -y # mirror every repo (curated wrapper)
109
+ navig github issues owner/repo # export issues (in-process)
110
+ navig github releases owner/repo # download releases + assets
111
+ navig github verify ./mirrors # backup integrity check
112
+ navig github --help # the full surface, grouped by panels
113
+ ```
114
+
115
+ ## Install
116
+
117
+ It ships in the NAVIG monorepo and loads automatically when NAVIG is installed.
118
+ To add/enable it explicitly:
119
+
120
+ ```
121
+ navig plugin add navig-github
122
+ ```
123
+
124
+ Check wiring and toggle state:
125
+
126
+ ```
127
+ navig store list
128
+ ```
129
+
130
+ ## Development
131
+
132
+ This package lives in the NAVIG monorepo under `plugins/navig-github/`. It registers via
133
+ the `navig.plugins` entry-point group; CLI verbs register via `navig.commands`.
@@ -0,0 +1,28 @@
1
+ """Resolve a path the operator TYPED against the directory they typed it in.
2
+
3
+ ``navig`` chdir's into the active space before a command runs, so a relative path
4
+ resolved with a bare ``Path(x)`` lands inside the space, not where the operator stands.
5
+ Core's ``navig.platform.paths.resolve_user_path`` fixes that; this shim uses it when the
6
+ installed core has it and otherwise reads the same ``NAVIG_INVOCATION_CWD`` variable, so
7
+ the plugin keeps working against an older core (and standalone, where cwd is correct).
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import os
13
+ from pathlib import Path
14
+
15
+ try:
16
+ from navig.platform.paths import resolve_user_path
17
+ except ImportError: # core older than the helper
18
+
19
+ def resolve_user_path(given: Path | str) -> Path:
20
+ p = Path(given).expanduser()
21
+ if p.is_absolute():
22
+ return p.resolve()
23
+ origin = os.environ.get("NAVIG_INVOCATION_CWD")
24
+ base = Path(origin) if origin and Path(origin).is_dir() else Path.cwd()
25
+ return (base / p).resolve()
26
+
27
+
28
+ __all__ = ["resolve_user_path"]
@@ -0,0 +1,19 @@
1
+ """Standalone entry point for the ``navig-github`` console script.
2
+
3
+ Installs and runs without navig: the same ``github_app`` Typer app navig mounts as
4
+ ``navig github``. One command surface, two front doors.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from navig_sdk.cli import run
10
+
11
+ from navig_github.commands.github import github_app
12
+
13
+
14
+ def main() -> None:
15
+ run(github_app, "navig-github")
16
+
17
+
18
+ if __name__ == "__main__":
19
+ main()
@@ -16,6 +16,7 @@ Token resolution order:
16
16
  4. No token → public repos only (curated `clone` falls back to plain git)
17
17
  """
18
18
 
19
+ import importlib
19
20
  import os
20
21
  import subprocess
21
22
  from pathlib import Path
@@ -23,11 +24,17 @@ from typing import Annotated
23
24
 
24
25
  import typer
25
26
 
26
- from navig.core.yaml_io import load_yaml_for_update, safe_load_yaml
27
- from navig.lazy_loader import lazy_import
28
- from navig.platform.paths import config_dir
27
+ # navig-sdk, not navig.*: this plugin runs as `navig github` inside navig AND as its own
28
+ # `navig-github` command with no navig installed. Each helper is navig's own when navig is
29
+ # present, and a faithful standalone copy when it is not.
30
+ from navig_sdk import console as ch
31
+ from navig_sdk.files import atomic_write_yaml, load_yaml_for_update, safe_load_yaml
32
+ from navig_sdk.host import config_dir, navig_available
29
33
 
30
- ch = lazy_import("navig.console_helper")
34
+
35
+ def _cmd() -> str:
36
+ """How the user invokes this tool here: `navig github` inside navig, else `navig-github`."""
37
+ return "navig github" if navig_available() else "navig-github"
31
38
 
32
39
  github_app = typer.Typer(
33
40
  name="github",
@@ -63,27 +70,9 @@ def _resolve_github_token() -> str | None:
63
70
  Returns None if not found anywhere.
64
71
  """
65
72
  # 1 — navig vault
66
- try:
67
- from navig.vault import get_vault # type: ignore
68
-
69
- vault = get_vault()
70
- secret = vault.get("github_token", caller="navig-github")
71
- if secret is not None:
72
- # Credential exposes the decrypted payload via `.data` / `.get_secret()`
73
- # — there is NO `.value` attribute. The token is stored under "value"
74
- # (also accept "token"/"api_key" for older entries).
75
- tok = None
76
- data = getattr(secret, "data", None)
77
- if isinstance(data, dict):
78
- tok = data.get("value") or data.get("token") or data.get("api_key")
79
- if not tok and hasattr(secret, "get_secret"):
80
- tok = secret.get_secret("value") or secret.get_secret("token")
81
- if not tok:
82
- tok = getattr(secret, "value", None)
83
- if tok:
84
- return str(tok)
85
- except Exception: # noqa: BLE001
86
- pass # best-effort; failure is non-critical
73
+ tok = _vault_token()
74
+ if tok:
75
+ return tok
87
76
 
88
77
  # 2 — env var
89
78
  token = os.environ.get("GITHUB_TOKEN", "").strip()
@@ -103,6 +92,32 @@ def _resolve_github_token() -> str | None:
103
92
  return None
104
93
 
105
94
 
95
+ def _vault_token(caller: str = "navig-github") -> str | None:
96
+ """The token stored in the shared navig vault (`github_token`), or None.
97
+
98
+ navig-vault is its own package, so this works with or without navig; with navig
99
+ installed it is the very vault navig reads.
100
+ """
101
+ try:
102
+ from navig_vault.core import get_vault
103
+
104
+ secret = get_vault().get("github_token", caller=caller)
105
+ except Exception: # noqa: BLE001 - no vault / locked vault = no token, never a crash
106
+ return None
107
+ if secret is None:
108
+ return None
109
+ # A Credential exposes its payload via `.data` / `.get_secret()` — there is NO
110
+ # `.value` attribute. The token is stored under "value" ("token"/"api_key" for
111
+ # older entries).
112
+ tok = None
113
+ data = getattr(secret, "data", None)
114
+ if isinstance(data, dict):
115
+ tok = data.get("value") or data.get("token") or data.get("api_key")
116
+ if not tok and hasattr(secret, "get_secret"):
117
+ tok = secret.get_secret("value") or secret.get_secret("token")
118
+ return str(tok) if tok else None
119
+
120
+
106
121
  def _engine_available() -> bool:
107
122
  """Return True if the bundled GitHub engine is importable."""
108
123
  try:
@@ -138,21 +153,25 @@ def _run_engine(args: list[str], token: str | None) -> None:
138
153
  if token:
139
154
  os.environ["GITHUB_TOKEN"] = token
140
155
 
141
- import click
142
- from navig_github.engine.cli import app as engine_cli
143
156
  from typer.main import get_command
144
157
 
158
+ from navig_github.engine.cli import app as engine_cli
159
+
160
+ # the click Typer runs on — Typer 0.27 vendors it and ships no `click` package, so take
161
+ # it from Typer's own Context base class (what navig.core.click_compat does).
162
+ click_pkg = typer.Context.__mro__[1].__module__.rsplit(".", 1)[0]
163
+ _click_exc = importlib.import_module(f"{click_pkg}.exceptions")
145
164
  cmd = get_command(engine_cli)
146
165
  try:
147
- cmd.main(list(args), prog_name="navig github", standalone_mode=False)
148
- except click.exceptions.Exit as exc: # typer.Exit inside the engine lands here
166
+ cmd.main(list(args), prog_name=_cmd(), standalone_mode=False)
167
+ except typer.Exit as exc: # typer.Exit inside the engine lands here
149
168
  code = exc.exit_code or 0
150
169
  if code:
151
170
  raise typer.Exit(code) from None
152
- except click.exceptions.Abort:
171
+ except _click_exc.Abort:
153
172
  ch.warning("Aborted.")
154
173
  raise typer.Exit(1) from None
155
- except click.ClickException as exc:
174
+ except _click_exc.ClickException as exc:
156
175
  exc.show()
157
176
  raise typer.Exit(exc.exit_code) from None
158
177
  except KeyboardInterrupt:
@@ -252,7 +271,7 @@ def gh_search(
252
271
  if not resolved_token:
253
272
  ch.warning(
254
273
  "No GitHub token found. Using unauthenticated access (60 req/hour).\n"
255
- "Set one with: navig github token set <your-token>"
274
+ f"Set one with: {_cmd()} token set <your-token>"
256
275
  )
257
276
 
258
277
  if not _require_engine():
@@ -312,7 +331,7 @@ def gh_backup(
312
331
  if not resolved_token:
313
332
  ch.warning(
314
333
  "No GitHub token found — only public repos accessible.\n"
315
- "Set a token with: navig github token set <your-token>"
334
+ f"Set a token with: {_cmd()} token set <your-token>"
316
335
  )
317
336
 
318
337
  if not _require_engine():
@@ -400,7 +419,7 @@ def token_set(
400
419
  """
401
420
  if use_vault:
402
421
  try:
403
- from navig.vault import get_vault # type: ignore
422
+ from navig_vault.core import get_vault
404
423
 
405
424
  vault = get_vault()
406
425
  existing = vault.get("github_token", caller="navig-github.token_set")
@@ -425,8 +444,6 @@ def token_set(
425
444
  cfg_path.parent.mkdir(parents=True, exist_ok=True)
426
445
  cfg = load_yaml_for_update(cfg_path)
427
446
  cfg.setdefault("github", {})["token"] = value
428
- from navig.core.yaml_io import atomic_write_yaml
429
-
430
447
  atomic_write_yaml(cfg, cfg_path)
431
448
  ch.success(f"GitHub token saved to {cfg_path}")
432
449
  except Exception as exc:
@@ -447,16 +464,9 @@ def token_show():
447
464
  masked = token[:6] + "..." + token[-4:]
448
465
  ch.success(f"GitHub token found: {masked}")
449
466
  # Identify source
450
- try:
451
- from navig.vault import get_vault # type: ignore
452
-
453
- v = get_vault()
454
- s = v.get("github_token", caller="navig-github.token_show")
455
- if s and getattr(s, "value", None) == token:
456
- ch.info("Source: navig vault")
457
- return
458
- except Exception: # noqa: BLE001
459
- pass # best-effort; failure is non-critical
467
+ if _vault_token("navig-github.token_show") == token:
468
+ ch.info("Source: navig vault")
469
+ return
460
470
  if os.environ.get("GITHUB_TOKEN", "").strip() == token:
461
471
  ch.info("Source: GITHUB_TOKEN env var")
462
472
  else:
@@ -464,8 +474,8 @@ def token_show():
464
474
  else:
465
475
  ch.warning(
466
476
  "No GitHub token configured.\n"
467
- "Set one with: navig github token set <your-token>\n"
468
- "Without a token, navig github only accesses public repos at low rate limits."
477
+ f"Set one with: {_cmd()} token set <your-token>\n"
478
+ "Without a token, only public repos are reachable, at low rate limits."
469
479
  )
470
480
 
471
481
 
@@ -481,7 +491,7 @@ def token_remove():
481
491
 
482
492
  # Vault
483
493
  try:
484
- from navig.vault import get_vault # type: ignore
494
+ from navig_vault.core import get_vault
485
495
 
486
496
  vault = get_vault()
487
497
  secret = vault.get("github_token", caller="navig-github.token_remove")
@@ -499,8 +509,6 @@ def token_remove():
499
509
  cfg = load_yaml_for_update(cfg_path)
500
510
  if cfg.get("github", {}).get("token"):
501
511
  cfg["github"].pop("token")
502
- from navig.core.yaml_io import atomic_write_yaml
503
-
504
512
  atomic_write_yaml(cfg, cfg_path)
505
513
  ch.success(f"GitHub token removed from {cfg_path}")
506
514
  removed = True
@@ -542,7 +550,7 @@ def gh_status():
542
550
  else:
543
551
  ch.warning(
544
552
  "No GitHub token — only public repos accessible at low rate limits.\n"
545
- "Set one with: navig github token set <your-token>"
553
+ f"Set one with: {_cmd()} token set <your-token>"
546
554
  )
547
555
 
548
556
  if engine_missing:
@@ -12,7 +12,7 @@ from datetime import datetime
12
12
  from pathlib import Path
13
13
  from typing import Any
14
14
 
15
- from navig.core.json_io import JsonReadError, atomic_write_json, load_json_for_update
15
+ from navig_sdk.files import JsonReadError, atomic_write_json, load_json_for_update
16
16
 
17
17
 
18
18
  @dataclass