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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ghosttrap-cli
3
- Version: 0.3.15
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.15"
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 for the current directory from config."""
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
- if repos:
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
- sub.add_parser("clear", help="Skip all outstanding errors")
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.15
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.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ghosttrap-cli"
7
- version = "0.3.15"
7
+ version = "0.3.16"
8
8
  description = "Watch for errors streaming from ghosttrap.io"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
File without changes