ghosttrap-cli 0.3.15__tar.gz → 0.3.16__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.
- {ghosttrap_cli-0.3.15 → ghosttrap_cli-0.3.16}/PKG-INFO +3 -1
- {ghosttrap_cli-0.3.15 → ghosttrap_cli-0.3.16}/README.md +2 -0
- {ghosttrap_cli-0.3.15 → ghosttrap_cli-0.3.16}/ghosttrap_cli/cli.py +29 -16
- {ghosttrap_cli-0.3.15 → ghosttrap_cli-0.3.16}/ghosttrap_cli.egg-info/PKG-INFO +3 -1
- {ghosttrap_cli-0.3.15 → ghosttrap_cli-0.3.16}/pyproject.toml +1 -1
- {ghosttrap_cli-0.3.15 → ghosttrap_cli-0.3.16}/ghosttrap_cli/__init__.py +0 -0
- {ghosttrap_cli-0.3.15 → ghosttrap_cli-0.3.16}/ghosttrap_cli.egg-info/SOURCES.txt +0 -0
- {ghosttrap_cli-0.3.15 → ghosttrap_cli-0.3.16}/ghosttrap_cli.egg-info/dependency_links.txt +0 -0
- {ghosttrap_cli-0.3.15 → ghosttrap_cli-0.3.16}/ghosttrap_cli.egg-info/entry_points.txt +0 -0
- {ghosttrap_cli-0.3.15 → ghosttrap_cli-0.3.16}/ghosttrap_cli.egg-info/requires.txt +0 -0
- {ghosttrap_cli-0.3.15 → ghosttrap_cli-0.3.16}/ghosttrap_cli.egg-info/top_level.txt +0 -0
- {ghosttrap_cli-0.3.15 → ghosttrap_cli-0.3.16}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ghosttrap-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.16
|
|
4
4
|
Summary: Watch for errors streaming from ghosttrap.io
|
|
5
5
|
Project-URL: Homepage, https://github.com/alex-rowley/ghosttrap-cli
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -54,6 +54,8 @@ Your app needs [ghosttrap-sdk](https://github.com/alex-rowley/ghosttrap-sdk) to
|
|
|
54
54
|
| `ghosttrap clear` | Skip all outstanding errors |
|
|
55
55
|
| `ghosttrap nuke` | Permanently delete every server-side row for the current repo (errors + token). Requires typed confirmation. |
|
|
56
56
|
|
|
57
|
+
`peek`, `watch`, `last`, and `clear` accept `--repo owner/name` to target a specific claimed repo when you're not inside its working tree (e.g. `ghosttrap peek --repo alex-rowley/ghosttrap-cli`). Otherwise they detect the repo from cwd. `nuke` is intentionally cwd-locked.
|
|
58
|
+
|
|
57
59
|
## How it works
|
|
58
60
|
|
|
59
61
|
- **Setup** authenticates with GitHub (via the active `gh` account) to prove you have access to the repo, then saves a repo token locally. If your active `gh` account can't see the repo, setup fails with a clear message; switch with `gh auth switch` and retry.
|
|
@@ -45,6 +45,8 @@ Your app needs [ghosttrap-sdk](https://github.com/alex-rowley/ghosttrap-sdk) to
|
|
|
45
45
|
| `ghosttrap clear` | Skip all outstanding errors |
|
|
46
46
|
| `ghosttrap nuke` | Permanently delete every server-side row for the current repo (errors + token). Requires typed confirmation. |
|
|
47
47
|
|
|
48
|
+
`peek`, `watch`, `last`, and `clear` accept `--repo owner/name` to target a specific claimed repo when you're not inside its working tree (e.g. `ghosttrap peek --repo alex-rowley/ghosttrap-cli`). Otherwise they detect the repo from cwd. `nuke` is intentionally cwd-locked.
|
|
49
|
+
|
|
48
50
|
## How it works
|
|
49
51
|
|
|
50
52
|
- **Setup** authenticates with GitHub (via the active `gh` account) to prove you have access to the repo, then saves a repo token locally. If your active `gh` account can't see the repo, setup fails with a clear message; switch with `gh auth switch` and retry.
|
|
@@ -24,7 +24,7 @@ KNOWN_SKILL_HASHES = {
|
|
|
24
24
|
"d3f594c4c3601a4594c18ebc5e16dfd4abad4ab97d56285ecc20634b919b6731", # v0.3.14
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
__version__ = "0.3.
|
|
27
|
+
__version__ = "0.3.16"
|
|
28
28
|
|
|
29
29
|
GHOSTTRAP_SERVER = "wss://ghosttrap.io/stream/"
|
|
30
30
|
CONFIG_DIR = os.path.expanduser("~/.ghosttrap")
|
|
@@ -201,18 +201,26 @@ def get_gh_token():
|
|
|
201
201
|
sys.exit(1)
|
|
202
202
|
|
|
203
203
|
|
|
204
|
-
def _get_repo_token(config):
|
|
205
|
-
"""Get the repo token
|
|
204
|
+
def _get_repo_token(config, requested=None):
|
|
205
|
+
"""Get the repo token. If `requested` is 'owner/name', match strictly. Else cwd, else first."""
|
|
206
206
|
repos = config.get("repos", {})
|
|
207
|
+
if not repos:
|
|
208
|
+
print("error: no repos configured. run 'ghosttrap setup' first.", file=sys.stderr)
|
|
209
|
+
sys.exit(1)
|
|
210
|
+
if requested:
|
|
211
|
+
for entry in repos.values():
|
|
212
|
+
if f"{entry.get('owner')}/{entry.get('name')}" == requested:
|
|
213
|
+
return entry["token"]
|
|
214
|
+
available = sorted(f"{e['owner']}/{e['name']}" for e in repos.values())
|
|
215
|
+
print(f"error: '{requested}' is not in your config.", file=sys.stderr)
|
|
216
|
+
print(f"available: {', '.join(available)}", file=sys.stderr)
|
|
217
|
+
sys.exit(1)
|
|
207
218
|
cwd_repo = _detect_repo_from_cwd()
|
|
208
219
|
if cwd_repo:
|
|
209
220
|
for entry in repos.values():
|
|
210
221
|
if f"{entry.get('owner')}/{entry.get('name')}" == cwd_repo:
|
|
211
222
|
return entry["token"]
|
|
212
|
-
|
|
213
|
-
return next(iter(repos.values()))["token"]
|
|
214
|
-
print("error: no repos configured. run 'ghosttrap setup' first.", file=sys.stderr)
|
|
215
|
-
sys.exit(1)
|
|
223
|
+
return next(iter(repos.values()))["token"]
|
|
216
224
|
|
|
217
225
|
|
|
218
226
|
async def _connect_and_handle(server_url, token, config, once=False):
|
|
@@ -388,10 +396,10 @@ def _advance_cursor(config, token):
|
|
|
388
396
|
return pending
|
|
389
397
|
|
|
390
398
|
|
|
391
|
-
def clear():
|
|
399
|
+
def clear(requested=None):
|
|
392
400
|
_require_setup()
|
|
393
401
|
config = _load_config()
|
|
394
|
-
token = _get_repo_token(config)
|
|
402
|
+
token = _get_repo_token(config, requested)
|
|
395
403
|
try:
|
|
396
404
|
pending = _advance_cursor(config, token)
|
|
397
405
|
if pending:
|
|
@@ -456,11 +464,11 @@ def nuke():
|
|
|
456
464
|
_save_config(config)
|
|
457
465
|
|
|
458
466
|
|
|
459
|
-
def last(do_clear=False):
|
|
467
|
+
def last(do_clear=False, requested=None):
|
|
460
468
|
_require_setup()
|
|
461
469
|
config = _load_config()
|
|
462
470
|
_check_cli_version(config)
|
|
463
|
-
token = _get_repo_token(config)
|
|
471
|
+
token = _get_repo_token(config, requested)
|
|
464
472
|
server = GHOSTTRAP_SERVER.replace("wss://", "https://").replace("/stream/", "")
|
|
465
473
|
url = f"{server}/last/{token}/"
|
|
466
474
|
try:
|
|
@@ -501,17 +509,22 @@ def main():
|
|
|
501
509
|
sub = parser.add_subparsers(dest="command")
|
|
502
510
|
|
|
503
511
|
sub.add_parser("setup", help="Claim repos and install Claude Code skill")
|
|
504
|
-
|
|
512
|
+
|
|
513
|
+
clear_parser = sub.add_parser("clear", help="Skip all outstanding errors")
|
|
514
|
+
clear_parser.add_argument("--repo", help="Target repo as owner/name (overrides cwd detection)")
|
|
505
515
|
|
|
506
516
|
watch_parser = sub.add_parser("watch", help="Stream errors in real time")
|
|
507
517
|
watch_parser.add_argument("--server", default=GHOSTTRAP_SERVER, help="WebSocket server URL")
|
|
518
|
+
watch_parser.add_argument("--repo", help="Target repo as owner/name (overrides cwd detection)")
|
|
508
519
|
|
|
509
520
|
peek_parser = sub.add_parser("peek", help="Wait for the next error then exit")
|
|
510
521
|
peek_parser.add_argument("--server", default=GHOSTTRAP_SERVER, help="WebSocket server URL")
|
|
511
522
|
peek_parser.add_argument("--clear", action="store_true", help="Skip outstanding errors before waiting")
|
|
523
|
+
peek_parser.add_argument("--repo", help="Target repo as owner/name (overrides cwd detection)")
|
|
512
524
|
|
|
513
525
|
last_parser = sub.add_parser("last", help="Fetch the most recent error then exit")
|
|
514
526
|
last_parser.add_argument("--clear", action="store_true", help="Also skip remaining outstanding errors")
|
|
527
|
+
last_parser.add_argument("--repo", help="Target repo as owner/name (overrides cwd detection)")
|
|
515
528
|
|
|
516
529
|
sub.add_parser("nuke", help="Permanently delete all server data for the current repo")
|
|
517
530
|
|
|
@@ -521,18 +534,18 @@ def main():
|
|
|
521
534
|
token = get_gh_token()
|
|
522
535
|
asyncio.run(setup(GHOSTTRAP_SERVER, token))
|
|
523
536
|
elif args.command == "clear":
|
|
524
|
-
clear()
|
|
537
|
+
clear(requested=args.repo)
|
|
525
538
|
elif args.command == "watch":
|
|
526
539
|
_require_setup()
|
|
527
540
|
_refresh_skill_if_stale()
|
|
528
541
|
config = _load_config()
|
|
529
|
-
token = _get_repo_token(config)
|
|
542
|
+
token = _get_repo_token(config, args.repo)
|
|
530
543
|
asyncio.run(watch(args.server, token))
|
|
531
544
|
elif args.command == "peek":
|
|
532
545
|
_require_setup()
|
|
533
546
|
_refresh_skill_if_stale()
|
|
534
547
|
config = _load_config()
|
|
535
|
-
token = _get_repo_token(config)
|
|
548
|
+
token = _get_repo_token(config, args.repo)
|
|
536
549
|
if args.clear:
|
|
537
550
|
try:
|
|
538
551
|
_advance_cursor(config, token)
|
|
@@ -542,7 +555,7 @@ def main():
|
|
|
542
555
|
asyncio.run(peek(args.server, token))
|
|
543
556
|
elif args.command == "last":
|
|
544
557
|
_refresh_skill_if_stale()
|
|
545
|
-
last(do_clear=args.clear)
|
|
558
|
+
last(do_clear=args.clear, requested=args.repo)
|
|
546
559
|
elif args.command == "nuke":
|
|
547
560
|
nuke()
|
|
548
561
|
else:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ghosttrap-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.16
|
|
4
4
|
Summary: Watch for errors streaming from ghosttrap.io
|
|
5
5
|
Project-URL: Homepage, https://github.com/alex-rowley/ghosttrap-cli
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -54,6 +54,8 @@ Your app needs [ghosttrap-sdk](https://github.com/alex-rowley/ghosttrap-sdk) to
|
|
|
54
54
|
| `ghosttrap clear` | Skip all outstanding errors |
|
|
55
55
|
| `ghosttrap nuke` | Permanently delete every server-side row for the current repo (errors + token). Requires typed confirmation. |
|
|
56
56
|
|
|
57
|
+
`peek`, `watch`, `last`, and `clear` accept `--repo owner/name` to target a specific claimed repo when you're not inside its working tree (e.g. `ghosttrap peek --repo alex-rowley/ghosttrap-cli`). Otherwise they detect the repo from cwd. `nuke` is intentionally cwd-locked.
|
|
58
|
+
|
|
57
59
|
## How it works
|
|
58
60
|
|
|
59
61
|
- **Setup** authenticates with GitHub (via the active `gh` account) to prove you have access to the repo, then saves a repo token locally. If your active `gh` account can't see the repo, setup fails with a clear message; switch with `gh auth switch` and retry.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|