claude-discover 1.9.2 → 1.9.4

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.
@@ -6,10 +6,10 @@
6
6
  <meta charset="UTF-8" />
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
8
  <title>Discover</title>
9
- <script type="module" crossorigin src="./assets/index-BugPzqD2.js"></script>
10
- <link rel="modulepreload" crossorigin href="./assets/vendors-S1fS5xz9.js">
9
+ <script type="module" crossorigin src="./assets/index-B4cvR_aa.js"></script>
10
+ <link rel="modulepreload" crossorigin href="./assets/vendors-JM3FOKMR.js">
11
11
  <link rel="stylesheet" crossorigin href="./assets/vendors-B4XMnGdr.css">
12
- <link rel="stylesheet" crossorigin href="./assets/index-03LlBvFr.css">
12
+ <link rel="stylesheet" crossorigin href="./assets/index-B1hu0QHl.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-discover",
3
- "version": "1.9.2",
3
+ "version": "1.9.4",
4
4
  "type": "module",
5
5
  "description": "Claude Discover — a desktop tool to browse your local Claude Code sessions: conversations, token costs, and captured API traffic",
6
6
  "license": "MIT",
@@ -27,10 +27,10 @@
27
27
  "smoke": "npm pack && npx -y ./claude-discover-${npm_package_version}.tgz",
28
28
  "postinstall": "install-electron",
29
29
  "prepack": "npm run build",
30
- "prepublishOnly": "npm test"
30
+ "prepublishOnly": "npm whoami && npm test"
31
31
  },
32
32
  "dependencies": {
33
- "@anthropic-ai/claude-agent-sdk": "^0.3.220",
33
+ "@anthropic-ai/claude-agent-sdk": "^0.3.266",
34
34
  "@date-fns/tz": "^1.5.0",
35
35
  "chokidar": "^5.0.0",
36
36
  "date-fns": "^4.4.0",
@@ -38,27 +38,28 @@
38
38
  "electron-context-menu": "^4.1.2",
39
39
  "electron-window-state": "^5.0.3",
40
40
  "gpt-tokenizer": "^3.4.0",
41
+ "which": "^7.0.0",
41
42
  "write-file-atomic": "^8.0.0"
42
43
  },
43
44
  "devDependencies": {
44
- "@electron/packager": "^20.0.4",
45
+ "@electron/packager": "^20.3.0",
45
46
  "@fontsource/inter": "^5.3.0",
46
47
  "@fontsource/jetbrains-mono": "^5.3.0",
47
48
  "@tomjs/electron-devtools-installer": "^4.0.1",
48
49
  "@uiw/react-json-view": "^2.0.0-alpha.43",
49
50
  "@vitejs/plugin-react": "^5.2.0",
50
51
  "electron-vite": "^5.0.0",
51
- "highlight.js": "^11.11.1",
52
- "lucide-react": "^1.27.0",
53
- "react": "^19.2.8",
54
- "react-dom": "^19.2.8",
52
+ "highlight.js": "^11.12.0",
53
+ "lucide-react": "^1.43.0",
54
+ "react": "^19.3.0",
55
+ "react-dom": "^19.3.0",
55
56
  "react-markdown": "^10.1.0",
56
- "react-resizable-panels": "^4.12.2",
57
+ "react-resizable-panels": "^4.12.4",
57
58
  "rehype-highlight": "^7.0.2",
58
59
  "remark-gfm": "^4.0.1",
59
60
  "tippy.js": "^6.3.7",
60
61
  "vite": "^7.3.6",
61
- "vitest": "^4.1.10"
62
+ "vitest": "^4.1.11"
62
63
  },
63
64
  "keywords": [
64
65
  "claude",
@@ -1,102 +0,0 @@
1
- #!/usr/bin/env node
2
- /*
3
- Single entry point for every Claude Code hook this app installs — reads the hook event JSON from stdin
4
- and dispatches on hook_event_name; add new hooks as new branches in main(). Standalone (no imports from
5
- src/), wired into <CLAUDE_DIR>/settings.json by the app's ProxySwitch (StatusBar Activate/Deactivate button).
6
-
7
- Currently handled:
8
- - SessionStart → ensureProxy(): revive the request-capture proxy (bin/proxy.mjs) if it's
9
- down. settings.json's env.ANTHROPIC_BASE_URL survives a PC restart or proxy crash, and without this every
10
- Claude Code request would hit a dead port. A SessionStart hook's stdout is injected into the session
11
- context, so only stderr may speak — exit 1 shows the warning without blocking the session.
12
-
13
- Copy-paste into <CLAUDE_DIR>/settings.json (replace the path):
14
- {
15
- "hooks": {
16
- "SessionStart": [
17
- { "hooks": [{ "type": "command", "command": "node /ABSOLUTE/PATH/TO/claude-discover/bin/claude/hooks.mjs" }] }
18
- ]
19
- }
20
- }
21
- */
22
-
23
-
24
- import fs from 'node:fs'
25
- import path from 'node:path'
26
- import { spawn } from 'node:child_process'
27
- import { text } from 'node:stream/consumers'
28
- import { PROXY_URL, PING_ROUTE, PING_RESPONSE, DATA_DIR, ERROR_LOG_PATH } from '../proxy.config.js'
29
-
30
-
31
- const DEBUG_LOG = false // Log every incoming hook event to DEBUG_LOG_FILE
32
- const DEBUG_LOG_FILE = path.join(DATA_DIR, 'hooks.debug.log')
33
- const ERROR_LOG = true // Log hook errors to ERROR_LOG_FILE
34
- const ERROR_LOG_FILE = path.join(DATA_DIR, 'hooks.error.log')
35
-
36
- const CLAUDE_HOOKS = {
37
- SESSION_START: 'SessionStart',
38
- }
39
-
40
- const PROXY_PATH = path.join(import.meta.dirname, '..', 'proxy.mjs')
41
-
42
-
43
- function log(file, data) {
44
- try {
45
- fs.mkdirSync(path.dirname(file), { recursive: true })
46
- fs.appendFileSync(file, `${new Date().toISOString()} ${data}\n`)
47
- } catch {}
48
- }
49
-
50
-
51
- async function ping() {
52
- try {
53
- const res = await fetch(`${PROXY_URL}${PING_ROUTE}`, { signal: AbortSignal.timeout(1000) })
54
- return res.ok && (await res.text()) === PING_RESPONSE
55
- } catch { return false }
56
- }
57
-
58
-
59
- async function ensureProxy() {
60
- if (await ping()) return // the common case — one loopback round-trip per session start
61
-
62
- const child = spawn(process.execPath, [PROXY_PATH], { detached: true, stdio: 'ignore', windowsHide: true })
63
- const exited = new Promise(resolve => child.once('exit', resolve)) // idempotent: exits 0 when one is already listening
64
- child.unref()
65
-
66
- // Poll until it answers (startup includes a ≤5s upstream check), racing the child's exit.
67
- const settle = (async () => {
68
- for (let i = 0; i < 40; i++) {
69
- if (await ping()) return 'up'
70
- await new Promise(r => setTimeout(r, 200))
71
- }
72
- return 'unresponsive'
73
- })()
74
-
75
- const outcome = await Promise.race([exited, settle])
76
- if (outcome === 'up' || await ping()) return // up, or a proxy of ours won the race and is now answering
77
-
78
- // Exit 0 ("already running") + failed ping = a foreign process holds the port Claude Code sends API traffic to
79
- let msg = `capture proxy failed to start (see ${ERROR_LOG_PATH}) — Claude Code cannot reach the API until it runs; disable capture via the app's Stop button to unblock`
80
- if (outcome === 0) msg = `${PROXY_URL} is held by another process that is not the capture proxy — Claude Code is configured to send API traffic there`
81
- if (outcome === 2) msg = 'cannot reach api.anthropic.com — capture proxy not started'
82
- console.error('claude-discover: ' + msg)
83
- process.exitCode = 1
84
- }
85
-
86
-
87
- async function main() {
88
- const raw = await text(process.stdin)
89
- if (DEBUG_LOG) log(DEBUG_LOG_FILE, raw.trim())
90
-
91
- try {
92
- const event = JSON.parse(raw || '{}') // inside the try so a malformed payload is logged, not silently swallowed
93
- if (event.hook_event_name === CLAUDE_HOOKS.SESSION_START) {
94
- await ensureProxy()
95
- }
96
- }
97
- catch (err) {
98
- if (ERROR_LOG) log(ERROR_LOG_FILE, err?.stack || err)
99
- }
100
- }
101
-
102
- main().catch(() => {}).finally(() => process.exit(process.exitCode ?? 0))