ghosttrap-cli 0.3.9__tar.gz → 0.3.10__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.9 → ghosttrap_cli-0.3.10}/PKG-INFO +3 -1
- {ghosttrap_cli-0.3.9 → ghosttrap_cli-0.3.10}/README.md +2 -0
- {ghosttrap_cli-0.3.9 → ghosttrap_cli-0.3.10}/ghosttrap_cli/cli.py +48 -0
- {ghosttrap_cli-0.3.9 → ghosttrap_cli-0.3.10}/ghosttrap_cli.egg-info/PKG-INFO +3 -1
- {ghosttrap_cli-0.3.9 → ghosttrap_cli-0.3.10}/pyproject.toml +1 -1
- {ghosttrap_cli-0.3.9 → ghosttrap_cli-0.3.10}/ghosttrap_cli/__init__.py +0 -0
- {ghosttrap_cli-0.3.9 → ghosttrap_cli-0.3.10}/ghosttrap_cli.egg-info/SOURCES.txt +0 -0
- {ghosttrap_cli-0.3.9 → ghosttrap_cli-0.3.10}/ghosttrap_cli.egg-info/dependency_links.txt +0 -0
- {ghosttrap_cli-0.3.9 → ghosttrap_cli-0.3.10}/ghosttrap_cli.egg-info/entry_points.txt +0 -0
- {ghosttrap_cli-0.3.9 → ghosttrap_cli-0.3.10}/ghosttrap_cli.egg-info/requires.txt +0 -0
- {ghosttrap_cli-0.3.9 → ghosttrap_cli-0.3.10}/ghosttrap_cli.egg-info/top_level.txt +0 -0
- {ghosttrap_cli-0.3.9 → ghosttrap_cli-0.3.10}/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.10
|
|
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
|
|
@@ -48,6 +48,8 @@ Your app needs [ghosttrap-sdk](https://github.com/alex-rowley/ghosttrap-sdk) to
|
|
|
48
48
|
| `ghosttrap setup` | Claim a repo, install the Claude Code skill |
|
|
49
49
|
| `ghosttrap peek` | Wait for the next error, print it, exit |
|
|
50
50
|
| `ghosttrap peek --clear` | Skip outstanding errors, then wait for the next one |
|
|
51
|
+
| `ghosttrap last` | Fetch the most recent error and exit (no waiting) |
|
|
52
|
+
| `ghosttrap last --clear` | Fetch the most recent error and skip everything older |
|
|
51
53
|
| `ghosttrap watch` | Stream all errors continuously |
|
|
52
54
|
| `ghosttrap clear` | Skip all outstanding errors |
|
|
53
55
|
|
|
@@ -39,6 +39,8 @@ Your app needs [ghosttrap-sdk](https://github.com/alex-rowley/ghosttrap-sdk) to
|
|
|
39
39
|
| `ghosttrap setup` | Claim a repo, install the Claude Code skill |
|
|
40
40
|
| `ghosttrap peek` | Wait for the next error, print it, exit |
|
|
41
41
|
| `ghosttrap peek --clear` | Skip outstanding errors, then wait for the next one |
|
|
42
|
+
| `ghosttrap last` | Fetch the most recent error and exit (no waiting) |
|
|
43
|
+
| `ghosttrap last --clear` | Fetch the most recent error and skip everything older |
|
|
42
44
|
| `ghosttrap watch` | Stream all errors continuously |
|
|
43
45
|
| `ghosttrap clear` | Skip all outstanding errors |
|
|
44
46
|
|
|
@@ -17,6 +17,7 @@ KNOWN_SKILL_HASHES = {
|
|
|
17
17
|
"0f2d2f4105e393fc69084d404d5a8154ba5d97fd23f92810c51345e3dc68e9a0", # v0.3.0
|
|
18
18
|
"8564b65b8ab5c63283cda1706e30ca62bc4e111d33ba8918220f4b556ad01da1", # v0.3.1..v0.3.3
|
|
19
19
|
"5759b2e0dc8ca47c3801915fd688cc8da878a7ab8d405f5183ffd7e8c8df4c55", # v0.3.4..v0.3.7
|
|
20
|
+
"0651bb4247cf5c68960ff5b63d6a5d0c85ff1ce08e7966ab4823601ff02cf1f4", # v0.3.9
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
__version__ = "0.3.0"
|
|
@@ -77,6 +78,7 @@ Read `~/.ghosttrap/config.json` for state. It contains:
|
|
|
77
78
|
|
|
78
79
|
## Other commands
|
|
79
80
|
|
|
81
|
+
- `ghosttrap last` — fetch the single most recent error and exit immediately, no waiting. Useful when the user wants to look at the latest error without starting a watch. Add `--clear` to also skip everything older in one shot.
|
|
80
82
|
- `ghosttrap clear` — manually skip outstanding errors without waiting. Useful if the user explicitly wants to drop the queue.
|
|
81
83
|
|
|
82
84
|
## Rules
|
|
@@ -367,6 +369,46 @@ def clear():
|
|
|
367
369
|
sys.exit(1)
|
|
368
370
|
|
|
369
371
|
|
|
372
|
+
def last(do_clear=False):
|
|
373
|
+
_require_setup()
|
|
374
|
+
config = _load_config()
|
|
375
|
+
_check_cli_version(config)
|
|
376
|
+
token = _get_repo_token(config)
|
|
377
|
+
server = GHOSTTRAP_SERVER.replace("wss://", "https://").replace("/stream/", "")
|
|
378
|
+
url = f"{server}/last/{token}/"
|
|
379
|
+
try:
|
|
380
|
+
req = urllib.request.Request(url, headers={"User-Agent": "ghosttrap-cli"})
|
|
381
|
+
with urllib.request.urlopen(req, timeout=10) as resp:
|
|
382
|
+
data = json.loads(resp.read())
|
|
383
|
+
except Exception as e:
|
|
384
|
+
print(f"error: {e}", file=sys.stderr)
|
|
385
|
+
sys.exit(1)
|
|
386
|
+
|
|
387
|
+
error = data.get("error")
|
|
388
|
+
if not error:
|
|
389
|
+
print("no errors yet", file=sys.stderr)
|
|
390
|
+
return
|
|
391
|
+
|
|
392
|
+
print(json.dumps({"type": "error", "error": error}))
|
|
393
|
+
sys.stdout.flush()
|
|
394
|
+
|
|
395
|
+
print(f"\n{'='*60}", file=sys.stderr)
|
|
396
|
+
print(f" {error.get('repo', '?')}", file=sys.stderr)
|
|
397
|
+
print(f" {error.get('type', '?')}: {error.get('message', '')}", file=sys.stderr)
|
|
398
|
+
frames = error.get("frames", [])
|
|
399
|
+
if frames:
|
|
400
|
+
f = frames[-1]
|
|
401
|
+
print(f" at {f.get('file', '?')}:{f.get('line', '?')} in {f.get('function', '?')}", file=sys.stderr)
|
|
402
|
+
print(f"{'='*60}", file=sys.stderr)
|
|
403
|
+
|
|
404
|
+
if do_clear:
|
|
405
|
+
try:
|
|
406
|
+
_advance_cursor(config, token)
|
|
407
|
+
except Exception as e:
|
|
408
|
+
print(f"error: {e}", file=sys.stderr)
|
|
409
|
+
sys.exit(1)
|
|
410
|
+
|
|
411
|
+
|
|
370
412
|
def main():
|
|
371
413
|
parser = argparse.ArgumentParser(prog="ghosttrap", description="Watch for errors from ghosttrap.io")
|
|
372
414
|
sub = parser.add_subparsers(dest="command")
|
|
@@ -381,6 +423,9 @@ def main():
|
|
|
381
423
|
peek_parser.add_argument("--server", default=GHOSTTRAP_SERVER, help="WebSocket server URL")
|
|
382
424
|
peek_parser.add_argument("--clear", action="store_true", help="Skip outstanding errors before waiting")
|
|
383
425
|
|
|
426
|
+
last_parser = sub.add_parser("last", help="Fetch the most recent error then exit")
|
|
427
|
+
last_parser.add_argument("--clear", action="store_true", help="Also skip remaining outstanding errors")
|
|
428
|
+
|
|
384
429
|
args = parser.parse_args()
|
|
385
430
|
|
|
386
431
|
if args.command == "setup":
|
|
@@ -406,6 +451,9 @@ def main():
|
|
|
406
451
|
print(f"error: {e}", file=sys.stderr)
|
|
407
452
|
sys.exit(1)
|
|
408
453
|
asyncio.run(peek(args.server, token))
|
|
454
|
+
elif args.command == "last":
|
|
455
|
+
_refresh_skill_if_stale()
|
|
456
|
+
last(do_clear=args.clear)
|
|
409
457
|
else:
|
|
410
458
|
parser.print_help()
|
|
411
459
|
sys.exit(1)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ghosttrap-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.10
|
|
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
|
|
@@ -48,6 +48,8 @@ Your app needs [ghosttrap-sdk](https://github.com/alex-rowley/ghosttrap-sdk) to
|
|
|
48
48
|
| `ghosttrap setup` | Claim a repo, install the Claude Code skill |
|
|
49
49
|
| `ghosttrap peek` | Wait for the next error, print it, exit |
|
|
50
50
|
| `ghosttrap peek --clear` | Skip outstanding errors, then wait for the next one |
|
|
51
|
+
| `ghosttrap last` | Fetch the most recent error and exit (no waiting) |
|
|
52
|
+
| `ghosttrap last --clear` | Fetch the most recent error and skip everything older |
|
|
51
53
|
| `ghosttrap watch` | Stream all errors continuously |
|
|
52
54
|
| `ghosttrap clear` | Skip all outstanding errors |
|
|
53
55
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|