ghosttrap-cli 0.3.7__tar.gz → 0.3.9__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.7
3
+ Version: 0.3.9
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
@@ -2,6 +2,7 @@
2
2
 
3
3
  import argparse
4
4
  import asyncio
5
+ import hashlib
5
6
  import json
6
7
  import os
7
8
  import subprocess
@@ -11,6 +12,13 @@ import urllib.request
11
12
 
12
13
  import websockets
13
14
 
15
+ KNOWN_SKILL_HASHES = {
16
+ "aeda67bc5971bd8af4d7ebe819ebcce5acead562fa618227a1798b4b5ae7143e", # v0.2.0
17
+ "0f2d2f4105e393fc69084d404d5a8154ba5d97fd23f92810c51345e3dc68e9a0", # v0.3.0
18
+ "8564b65b8ab5c63283cda1706e30ca62bc4e111d33ba8918220f4b556ad01da1", # v0.3.1..v0.3.3
19
+ "5759b2e0dc8ca47c3801915fd688cc8da878a7ab8d405f5183ffd7e8c8df4c55", # v0.3.4..v0.3.7
20
+ }
21
+
14
22
  __version__ = "0.3.0"
15
23
 
16
24
  GHOSTTRAP_SERVER = "wss://ghosttrap.io/stream/"
@@ -59,14 +67,18 @@ Read `~/.ghosttrap/config.json` for state. It contains:
59
67
  1. Detect the current repo from `git config --get remote.origin.url`.
60
68
  2. Look it up in the config. If the repo isn't there, tell the user to run `ghosttrap setup`.
61
69
  3. If `sdk_installed` is false or missing: install the SDK (`pip install ghosttrap-sdk`), wire `ghosttrap.init("<token>")` into the app startup. For Django projects, also add `"ghosttrap.django.GhostTrapApp"` to INSTALLED_APPS (re-attaches logging handler after Django's dictConfig) and `"ghosttrap.django.GhostTrapMiddleware"` to MIDDLEWARE (catches unhandled view exceptions). The SDK auto-hooks into Celery task_failure if Celery is installed, and attaches a logging handler for logger.exception() calls. Use whatever pattern the project already uses for configuration (env vars, settings files, hardcoded — match the existing style). Then update the config: set `sdk_installed: true`, `sdk_version`, `init_file` to record what you did.
62
- 4. Run `ghosttrap peek` with `run_in_background: true`.
70
+ 4. Run `ghosttrap peek --clear` with `run_in_background: true`. The `--clear` flag skips any stale backlog from prior sessions so you only get fresh errors.
63
71
 
64
72
  ## When peek returns
65
73
 
66
- 1. **Immediately restart peek** in the background before doing anything else — this ensures you're listening for the next error while you work on the current one.
74
+ 1. **Immediately restart peek** in the background before doing anything else — this ensures you're listening for the next error while you work on the current one. Use plain `ghosttrap peek` here (no `--clear`) — you only want to skip backlog at session start.
67
75
  2. Read the JSON output: `error.repo`, `error.type`, `error.message`, `error.traceback` (list of strings), `error.frames` (list of `{file, line, function, code}`).
68
76
  3. Open the file from the last frame, diagnose, fix.
69
77
 
78
+ ## Other commands
79
+
80
+ - `ghosttrap clear` — manually skip outstanding errors without waiting. Useful if the user explicitly wants to drop the queue.
81
+
70
82
  ## Rules
71
83
 
72
84
  - Always `run_in_background: true` for peek — it blocks.
@@ -251,6 +263,18 @@ def _write_skill():
251
263
  f.write(SKILL_CONTENT)
252
264
 
253
265
 
266
+ def _refresh_skill_if_stale():
267
+ if not os.path.exists(SKILL_FILE):
268
+ return
269
+ with open(SKILL_FILE) as f:
270
+ content = f.read()
271
+ if content == SKILL_CONTENT:
272
+ return
273
+ if hashlib.sha256(content.encode()).hexdigest() in KNOWN_SKILL_HASHES:
274
+ _write_skill()
275
+ print("ghosttrap skill file updated", file=sys.stderr)
276
+
277
+
254
278
  async def setup(server_url, token):
255
279
  config = _load_config()
256
280
 
@@ -366,11 +390,13 @@ def main():
366
390
  clear()
367
391
  elif args.command == "watch":
368
392
  _require_setup()
393
+ _refresh_skill_if_stale()
369
394
  config = _load_config()
370
395
  token = _get_repo_token(config)
371
396
  asyncio.run(watch(args.server, token))
372
397
  elif args.command == "peek":
373
398
  _require_setup()
399
+ _refresh_skill_if_stale()
374
400
  config = _load_config()
375
401
  token = _get_repo_token(config)
376
402
  if args.clear:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ghosttrap-cli
3
- Version: 0.3.7
3
+ Version: 0.3.9
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ghosttrap-cli"
7
- version = "0.3.7"
7
+ version = "0.3.9"
8
8
  description = "Watch for errors streaming from ghosttrap.io"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
File without changes
File without changes