claudeye 0.2.2 → 0.3.0

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.

Potentially problematic release.


This version of claudeye might be problematic. Click here for more details.

Files changed (191) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +1 -0
  3. package/.next/standalone/.next/build-manifest.json +5 -5
  4. package/.next/standalone/.next/routes-manifest.json +9 -0
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
  6. package/.next/standalone/.next/server/app/_global-error/page.js +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +2 -2
  10. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +3 -3
  17. package/.next/standalone/.next/server/app/_not-found/page.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  21. package/.next/standalone/.next/server/app/_not-found.rsc +5 -5
  22. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +5 -5
  23. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  24. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +5 -5
  25. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  26. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  27. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  28. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route/app-paths-manifest.json +3 -0
  29. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route/build-manifest.json +11 -0
  30. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route/server-reference-manifest.json +4 -0
  31. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +6 -0
  32. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.map +5 -0
  33. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -0
  34. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route_client-reference-manifest.js +2 -0
  35. package/.next/standalone/.next/server/app/icon.png/route.js +2 -1
  36. package/.next/standalone/.next/server/app/icon.png/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
  38. package/.next/standalone/.next/server/app/page.js +1 -1
  39. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  41. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +3 -3
  42. package/.next/standalone/.next/server/app/project/[name]/page.js +1 -1
  43. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +3 -3
  46. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +1 -1
  47. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +35 -5
  48. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +4 -3
  49. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  51. package/.next/standalone/.next/server/app-paths-manifest.json +1 -0
  52. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f408c708._.js +21 -0
  53. package/.next/standalone/.next/server/chunks/[root-of-the-server]__fde83e67._.js +3 -0
  54. package/.next/standalone/.next/server/chunks/ce889_server_app_api_download_[project]_[session]_route_actions_bbdd823f.js +3 -0
  55. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_64175717.js +3 -0
  56. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__070e2009._.js +1 -1
  57. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0a745465._.js +3 -0
  58. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__bc37261c._.js → [root-of-the-server]__14f58da3._.js} +2 -2
  59. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__164d9311._.js +3 -0
  60. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__2822fd21._.js +6 -0
  61. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__31b4c2fd._.js +3 -0
  62. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__45656df2._.js → [root-of-the-server]__4e339665._.js} +2 -2
  63. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__55018089._.js +3 -0
  64. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__6313e929._.js +3 -0
  65. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__7e21395a._.js +1 -1
  66. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__ee388ee0._.js +3 -0
  67. package/.next/standalone/.next/server/chunks/ssr/_0b4924bd._.js +3 -0
  68. package/.next/standalone/.next/server/chunks/ssr/{node_modules_9e089768._.js → _1404b353._.js} +2 -2
  69. package/.next/standalone/.next/server/chunks/ssr/_3d21dde5._.js +8 -0
  70. package/.next/standalone/.next/server/chunks/ssr/_fd9b1ff7._.js +3 -0
  71. package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_7769b563._.js → node_modules_next_dist_esm_eedfc1fd._.js} +2 -2
  72. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  73. package/.next/standalone/.next/server/pages/404.html +2 -2
  74. package/.next/standalone/.next/server/pages/500.html +2 -2
  75. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/server-reference-manifest.json +35 -5
  77. package/.next/standalone/.next/static/chunks/0e266948a26a3cdf.js +1 -0
  78. package/.next/standalone/.next/static/chunks/2774382cf796393c.js +4 -0
  79. package/.next/standalone/.next/static/chunks/6189ca16caad4352.js +3 -0
  80. package/.next/standalone/.next/static/chunks/8111dbe882e31821.js +1 -0
  81. package/.next/standalone/.next/static/chunks/{5a424275276f2bb9.js → bdeaeb8c9876394b.js} +1 -1
  82. package/.next/standalone/.next/static/chunks/cdbb6932218650fd.js +1 -0
  83. package/.next/standalone/.next/static/chunks/ea03555bb726c073.css +1 -0
  84. package/.next/standalone/.next/static/chunks/f091501564eb2ea3.js +4 -0
  85. package/.next/standalone/.next/static/chunks/{turbopack-2315171089e56fad.js → turbopack-fc1f23734a087d36.js} +1 -1
  86. package/.next/standalone/README.md +528 -41
  87. package/.next/standalone/app/actions/run-enrichments.ts +26 -5
  88. package/.next/standalone/app/actions/run-evals.ts +26 -5
  89. package/.next/standalone/app/actions/run-subagent-enrichments.ts +89 -0
  90. package/.next/standalone/app/actions/run-subagent-evals.ts +88 -0
  91. package/.next/standalone/app/api/download/[project]/[session]/route.ts +49 -0
  92. package/.next/standalone/app/components/copy-button.tsx +37 -0
  93. package/.next/standalone/app/components/enrichment-results-panel.tsx +33 -13
  94. package/.next/standalone/app/components/eval-results-panel.tsx +33 -13
  95. package/.next/standalone/app/components/log-viewer/entry-row.tsx +43 -14
  96. package/.next/standalone/app/components/log-viewer/queue-divider.tsx +50 -7
  97. package/.next/standalone/app/components/log-viewer/tool-input-output.tsx +13 -3
  98. package/.next/standalone/app/components/project-list.tsx +11 -11
  99. package/.next/standalone/app/components/raw-log-viewer.tsx +80 -11
  100. package/.next/standalone/app/components/refresh-button.tsx +79 -0
  101. package/.next/standalone/app/components/sessions-list.tsx +23 -14
  102. package/.next/standalone/app/project/[name]/session/[sessionId]/page.tsx +23 -12
  103. package/.next/standalone/bin/claudeye.mjs +112 -25
  104. package/.next/standalone/components/navbar.tsx +2 -0
  105. package/.next/standalone/dist/app.js +10 -4
  106. package/.next/standalone/dist/condition-registry.js +20 -0
  107. package/.next/standalone/dist/enrich-registry.js +26 -3
  108. package/.next/standalone/dist/enrich-runner.js +68 -13
  109. package/.next/standalone/dist/registry.js +26 -3
  110. package/.next/standalone/dist/runner.js +78 -20
  111. package/.next/standalone/dist/server-spawn.js +58 -34
  112. package/.next/standalone/lib/cache/hash.ts +67 -0
  113. package/.next/standalone/lib/cache/index.ts +9 -0
  114. package/.next/standalone/lib/cache/local-backend.ts +81 -0
  115. package/.next/standalone/lib/cache/manager.ts +127 -0
  116. package/.next/standalone/lib/cache/types.ts +19 -0
  117. package/.next/standalone/lib/evals/app.ts +30 -7
  118. package/.next/standalone/lib/evals/condition-registry.ts +26 -0
  119. package/.next/standalone/lib/evals/enrich-registry.ts +29 -3
  120. package/.next/standalone/lib/evals/enrich-runner.ts +68 -14
  121. package/.next/standalone/lib/evals/enrich-types.ts +6 -1
  122. package/.next/standalone/lib/evals/index.ts +3 -1
  123. package/.next/standalone/lib/evals/registry.ts +29 -4
  124. package/.next/standalone/lib/evals/runner.ts +77 -20
  125. package/.next/standalone/lib/evals/server-spawn.ts +67 -41
  126. package/.next/standalone/lib/evals/types.ts +16 -0
  127. package/.next/standalone/lib/log-format.ts +22 -1
  128. package/.next/standalone/package-lock.json +244 -308
  129. package/.next/standalone/package.json +1 -1
  130. package/.next/standalone/scripts/dev.ts +3 -1
  131. package/.next/standalone/scripts/parse-script-args.ts +30 -2
  132. package/.next/standalone/scripts/start.ts +3 -1
  133. package/.next/standalone/tsconfig.tsbuildinfo +1 -1
  134. package/README.md +528 -41
  135. package/bin/claudeye.mjs +112 -25
  136. package/dist/app.d.ts +17 -3
  137. package/dist/app.d.ts.map +1 -1
  138. package/dist/app.js +10 -4
  139. package/dist/app.js.map +1 -1
  140. package/dist/condition-registry.d.ts +9 -0
  141. package/dist/condition-registry.d.ts.map +1 -0
  142. package/dist/condition-registry.js +20 -0
  143. package/dist/condition-registry.js.map +1 -0
  144. package/dist/enrich-registry.d.ts +5 -1
  145. package/dist/enrich-registry.d.ts.map +1 -1
  146. package/dist/enrich-registry.js +26 -3
  147. package/dist/enrich-registry.js.map +1 -1
  148. package/dist/enrich-runner.d.ts +3 -3
  149. package/dist/enrich-runner.d.ts.map +1 -1
  150. package/dist/enrich-runner.js +68 -13
  151. package/dist/enrich-runner.js.map +1 -1
  152. package/dist/enrich-types.d.ts +6 -1
  153. package/dist/enrich-types.d.ts.map +1 -1
  154. package/dist/index.d.ts +2 -2
  155. package/dist/index.d.ts.map +1 -1
  156. package/dist/registry.d.ts +5 -2
  157. package/dist/registry.d.ts.map +1 -1
  158. package/dist/registry.js +26 -3
  159. package/dist/registry.js.map +1 -1
  160. package/dist/runner.d.ts +2 -2
  161. package/dist/runner.d.ts.map +1 -1
  162. package/dist/runner.js +78 -20
  163. package/dist/runner.js.map +1 -1
  164. package/dist/server-spawn.d.ts +2 -1
  165. package/dist/server-spawn.d.ts.map +1 -1
  166. package/dist/server-spawn.js +58 -34
  167. package/dist/server-spawn.js.map +1 -1
  168. package/dist/types.d.ts +14 -0
  169. package/dist/types.d.ts.map +1 -1
  170. package/package.json +1 -1
  171. package/.next/standalone/.next/server/chunks/[root-of-the-server]__24a1e50a._.js +0 -21
  172. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__32f115c9._.js +0 -6
  173. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__476a1712._.js +0 -3
  174. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__4ddcabf2._.js +0 -3
  175. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__ad593585._.js +0 -3
  176. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__afd8e13b._.js +0 -3
  177. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__dd7ee810._.js +0 -3
  178. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__ff3004de._.js +0 -3
  179. package/.next/standalone/.next/server/chunks/ssr/_53472598._.js +0 -3
  180. package/.next/standalone/.next/server/chunks/ssr/_863b6ca8._.js +0 -3
  181. package/.next/standalone/.next/server/chunks/ssr/_f7347c74._.js +0 -5
  182. package/.next/standalone/.next/static/chunks/2243ff2814e7a781.js +0 -3
  183. package/.next/standalone/.next/static/chunks/50531467396cea91.css +0 -1
  184. package/.next/standalone/.next/static/chunks/8f288c01f8d7ef2d.js +0 -1
  185. package/.next/standalone/.next/static/chunks/abab1b00b2788443.js +0 -4
  186. package/.next/standalone/.next/static/chunks/d250d7f6f0a8c325.js +0 -1
  187. package/.next/standalone/.next/static/chunks/d7a572a8b7eb1ec8.js +0 -1
  188. package/.next/standalone/.next/static/chunks/fb1b0b9da3f03023.js +0 -4
  189. /package/.next/standalone/.next/static/{LoGIEEP4cORCqcFv-Ywg0 → 5JsV7rfAEOIwNOQPaX3UP}/_buildManifest.js +0 -0
  190. /package/.next/standalone/.next/static/{LoGIEEP4cORCqcFv-Ywg0 → 5JsV7rfAEOIwNOQPaX3UP}/_clientMiddlewareManifest.json +0 -0
  191. /package/.next/standalone/.next/static/{LoGIEEP4cORCqcFv-Ywg0 → 5JsV7rfAEOIwNOQPaX3UP}/_ssgManifest.js +0 -0
@@ -7,8 +7,8 @@ import { spawn, execSync } from "node:child_process";
7
7
  import { createServer } from "node:net";
8
8
  import { resolve, dirname } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
10
- import { existsSync } from "node:fs";
11
- import { homedir, platform } from "node:os";
10
+ import { existsSync, rmSync } from "node:fs";
11
+ import { homedir, platform, networkInterfaces } from "node:os";
12
12
 
13
13
  const __filename = fileURLToPath(import.meta.url);
14
14
  const __dirname = dirname(__filename);
@@ -27,7 +27,13 @@ Options:
27
27
  --projects-path, -p <path> Path to Claude projects directory
28
28
  (default: ~/.claude/projects)
29
29
  --port <number> Preferred port (default: 8020)
30
+ --host <address> Host to bind to (default: localhost)
31
+ Use 0.0.0.0 for LAN access
30
32
  --evals <path> Path to evals/enrichments file (JS/TS module)
33
+ --cache <on|off> Enable/disable caching (default: on)
34
+ --cache-path <path> Custom cache directory
35
+ (default: ~/.claudeye/cache)
36
+ --cache-clear Clear all cached results and exit
31
37
  --no-open Don't auto-open the browser
32
38
  -h, --help Show this help message
33
39
  `.trim();
@@ -36,8 +42,12 @@ Options:
36
42
  const args = process.argv.slice(2);
37
43
  let projectsPath = resolve(homedir(), ".claude", "projects");
38
44
  let preferredPort = 8020;
45
+ let preferredHost = "localhost";
39
46
  let autoOpen = true;
40
47
  let evalsPath = "";
48
+ let cacheMode = "on";
49
+ let cachePath = "";
50
+ let cacheClear = false;
41
51
 
42
52
  /** Read the next value for a flag, supporting both `--flag value` and `--flag=value`. */
43
53
  function readFlagValue(flag, idx) {
@@ -74,10 +84,30 @@ for (let i = 0; i < args.length; i++) {
74
84
  preferredPort = parseInt(inlineValue ?? readFlagValue(flag, i), 10) || 8020;
75
85
  if (inlineValue === null) i++;
76
86
  break;
87
+ case "--host":
88
+ preferredHost = inlineValue ?? readFlagValue(flag, i);
89
+ if (inlineValue === null) i++;
90
+ break;
77
91
  case "--evals":
78
92
  evalsPath = resolve(inlineValue ?? readFlagValue(flag, i));
79
93
  if (inlineValue === null) i++;
80
94
  break;
95
+ case "--cache":
96
+ cacheMode = inlineValue ?? readFlagValue(flag, i);
97
+ if (inlineValue === null) i++;
98
+ if (cacheMode !== "on" && cacheMode !== "off") {
99
+ console.error(`Error: --cache must be "on" or "off"\n`);
100
+ console.log(HELP);
101
+ process.exit(1);
102
+ }
103
+ break;
104
+ case "--cache-path":
105
+ cachePath = resolve(inlineValue ?? readFlagValue(flag, i));
106
+ if (inlineValue === null) i++;
107
+ break;
108
+ case "--cache-clear":
109
+ cacheClear = true;
110
+ break;
81
111
  case "--no-open":
82
112
  autoOpen = false;
83
113
  break;
@@ -88,6 +118,19 @@ for (let i = 0; i < args.length; i++) {
88
118
  }
89
119
  }
90
120
 
121
+ // ── Cache clear (standalone action) ──────────────────────────────────────────
122
+ if (cacheClear) {
123
+ const clearPath = cachePath || resolve(homedir(), ".claudeye", "cache");
124
+ try {
125
+ rmSync(clearPath, { recursive: true, force: true });
126
+ console.log(`Cache cleared: ${clearPath}`);
127
+ } catch (err) {
128
+ console.error(`Failed to clear cache: ${err.message}`);
129
+ process.exit(1);
130
+ }
131
+ process.exit(0);
132
+ }
133
+
91
134
  // ── Validate ────────────────────────────────────────────────────────────────
92
135
  if (!existsSync(serverScript)) {
93
136
  console.error(
@@ -104,21 +147,37 @@ if (!existsSync(projectsPath)) {
104
147
  );
105
148
  }
106
149
 
150
+ // ── Network address detection ────────────────────────────────────────────────
151
+ function getNetworkAddress() {
152
+ for (const addrs of Object.values(networkInterfaces())) {
153
+ for (const iface of addrs) {
154
+ if (iface.family === "IPv4" && !iface.internal) {
155
+ return iface.address;
156
+ }
157
+ }
158
+ }
159
+ return "0.0.0.0";
160
+ }
161
+
107
162
  // ── Port selection ──────────────────────────────────────────────────────────
108
- function findAvailablePort(preferred) {
163
+ function resolveBindAddress(host) {
164
+ return host === "localhost" ? "127.0.0.1" : host;
165
+ }
166
+
167
+ function findAvailablePort(preferred, host) {
168
+ const bindAddr = resolveBindAddress(host);
109
169
  return new Promise((resolve, reject) => {
110
170
  const srv = createServer();
111
- srv.listen(preferred, "127.0.0.1", () => {
171
+ srv.listen(preferred, bindAddr, () => {
112
172
  srv.close(() => resolve(preferred));
113
173
  });
114
174
  srv.on("error", () => {
115
- // Preferred port busy — let the OS pick one
116
- const srv2 = createServer();
117
- srv2.listen(0, "127.0.0.1", () => {
118
- const port = srv2.address().port;
119
- srv2.close(() => resolve(port));
175
+ const fallback = createServer();
176
+ fallback.listen(0, bindAddr, () => {
177
+ const port = fallback.address().port;
178
+ fallback.close(() => resolve(port));
120
179
  });
121
- srv2.on("error", reject);
180
+ fallback.on("error", reject);
122
181
  });
123
182
  });
124
183
  }
@@ -153,34 +212,62 @@ async function waitForServer(url, timeoutMs = 15_000, intervalMs = 150) {
153
212
  throw new Error("Server readiness timeout");
154
213
  }
155
214
 
215
+ // ── Startup logging ─────────────────────────────────────────────────────────
216
+ function logServerInfo(port, localUrl) {
217
+ console.log(`Starting Claudeye dashboard...`);
218
+ console.log(` Projects: ${projectsPath}`);
219
+ if (evalsPath) console.log(` Evals: ${evalsPath}`);
220
+ if (cacheMode === "off") {
221
+ console.log(` Cache: disabled`);
222
+ } else {
223
+ const displayPath = cachePath || resolve(homedir(), ".claudeye", "cache");
224
+ console.log(` Cache: local (${displayPath})`);
225
+ }
226
+ if (preferredHost === "0.0.0.0") {
227
+ console.log(` Local: ${localUrl}`);
228
+ console.log(` Network: http://${getNetworkAddress()}:${port}`);
229
+ } else {
230
+ console.log(` URL: http://${preferredHost}:${port}`);
231
+ }
232
+ console.log();
233
+ }
234
+
156
235
  // ── Main ────────────────────────────────────────────────────────────────────
157
236
  async function main() {
158
- const port = await findAvailablePort(preferredPort);
237
+ const port = await findAvailablePort(preferredPort, preferredHost);
159
238
  if (port !== preferredPort) {
160
239
  console.log(`Port ${preferredPort} is busy, using port ${port} instead.`);
161
240
  }
162
241
 
163
- const url = `http://localhost:${port}`;
164
- console.log(`Starting Claudeye dashboard...`);
165
- console.log(` Projects: ${projectsPath}`);
166
- if (evalsPath) console.log(` Evals: ${evalsPath}`);
167
- console.log(` URL: ${url}\n`);
242
+ const localUrl = `http://localhost:${port}`;
243
+ logServerInfo(port, localUrl);
244
+
245
+ const env = {
246
+ ...process.env,
247
+ PORT: String(port),
248
+ HOSTNAME: preferredHost,
249
+ CLAUDE_PROJECTS_PATH: projectsPath,
250
+ };
251
+ if (evalsPath) {
252
+ env.CLAUDEYE_EVALS_MODULE = evalsPath;
253
+ env.CLAUDEYE_DIST_PATH = resolve(packageRoot, "dist");
254
+ }
255
+ if (cacheMode === "off") {
256
+ env.CLAUDEYE_CACHE = "off";
257
+ }
258
+ if (cachePath) {
259
+ env.CLAUDEYE_CACHE_PATH = cachePath;
260
+ }
168
261
 
169
262
  const child = spawn(process.execPath, [serverScript], {
170
263
  cwd: standaloneDir,
171
264
  stdio: "inherit",
172
- env: {
173
- ...process.env,
174
- PORT: String(port),
175
- HOSTNAME: "localhost",
176
- CLAUDE_PROJECTS_PATH: projectsPath,
177
- ...(evalsPath ? { CLAUDEYE_EVALS_MODULE: evalsPath, CLAUDEYE_DIST_PATH: resolve(packageRoot, "dist") } : {}),
178
- },
265
+ env,
179
266
  });
180
267
 
181
268
  if (autoOpen) {
182
- waitForServer(url).then(() => openBrowser(url)).catch(() => {
183
- console.warn(`\nServer did not respond within 15 s.\nOpen manually: ${url}\n`);
269
+ waitForServer(localUrl).then(() => openBrowser(localUrl)).catch(() => {
270
+ console.warn(`\nServer did not respond within 15 s.\nOpen manually: ${localUrl}\n`);
184
271
  });
185
272
  }
186
273
 
@@ -5,6 +5,7 @@ import React from "react";
5
5
  import { Logo } from "@/components/logo";
6
6
  import { ThemeToggle } from "@/components/theme-toggle";
7
7
  import { ReachDevelopers } from "@/components/reach-developers";
8
+ import { RefreshButton } from "@/app/components/refresh-button";
8
9
 
9
10
  export const Navbar: React.FC = () => {
10
11
  return (
@@ -31,6 +32,7 @@ export const Navbar: React.FC = () => {
31
32
  </div>
32
33
  </div>
33
34
  <div className="flex items-center gap-2">
35
+ <RefreshButton />
34
36
  <ReachDevelopers />
35
37
  <ThemeToggle />
36
38
  </div>
@@ -45,15 +45,20 @@ exports.createApp = createApp;
45
45
  */
46
46
  const registry_1 = require("./registry");
47
47
  const enrich_registry_1 = require("./enrich-registry");
48
+ const condition_registry_1 = require("./condition-registry");
48
49
  const LOADING_KEY = "__CLAUDEYE_LOADING_EVALS__";
49
50
  function createApp() {
50
51
  const app = {
51
- eval(name, fn) {
52
- (0, registry_1.registerEval)(name, fn);
52
+ condition(fn) {
53
+ (0, condition_registry_1.setGlobalCondition)(fn);
53
54
  return app;
54
55
  },
55
- enrich(name, fn) {
56
- (0, enrich_registry_1.registerEnricher)(name, fn);
56
+ eval(name, fn, options) {
57
+ (0, registry_1.registerEval)(name, fn, options === null || options === void 0 ? void 0 : options.condition, options === null || options === void 0 ? void 0 : options.scope, options === null || options === void 0 ? void 0 : options.subagentType);
58
+ return app;
59
+ },
60
+ enrich(name, fn, options) {
61
+ (0, enrich_registry_1.registerEnricher)(name, fn, options === null || options === void 0 ? void 0 : options.condition, options === null || options === void 0 ? void 0 : options.scope, options === null || options === void 0 ? void 0 : options.subagentType);
57
62
  return app;
58
63
  },
59
64
  async listen(port, options) {
@@ -69,6 +74,7 @@ function createApp() {
69
74
  const { spawnServer } = await Promise.resolve().then(() => __importStar(require("./server-spawn")));
70
75
  await spawnServer((_a = port !== null && port !== void 0 ? port : options === null || options === void 0 ? void 0 : options.port) !== null && _a !== void 0 ? _a : 8020, {
71
76
  open: (_b = options === null || options === void 0 ? void 0 : options.open) !== null && _b !== void 0 ? _b : true,
77
+ host: options === null || options === void 0 ? void 0 : options.host,
72
78
  });
73
79
  },
74
80
  };
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setGlobalCondition = setGlobalCondition;
4
+ exports.getGlobalCondition = getGlobalCondition;
5
+ exports.clearGlobalCondition = clearGlobalCondition;
6
+ const REGISTRY_KEY = "__CLAUDEYE_CONDITION_REGISTRY__";
7
+ function setGlobalCondition(fn) {
8
+ const g = globalThis;
9
+ g[REGISTRY_KEY] = fn;
10
+ }
11
+ function getGlobalCondition() {
12
+ var _a;
13
+ const g = globalThis;
14
+ return (_a = g[REGISTRY_KEY]) !== null && _a !== void 0 ? _a : null;
15
+ }
16
+ function clearGlobalCondition() {
17
+ const g = globalThis;
18
+ g[REGISTRY_KEY] = null;
19
+ }
20
+ //# sourceMappingURL=condition-registry.js.map
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerEnricher = registerEnricher;
4
4
  exports.getRegisteredEnrichers = getRegisteredEnrichers;
5
+ exports.getSessionScopedEnrichers = getSessionScopedEnrichers;
6
+ exports.getSubagentScopedEnrichers = getSubagentScopedEnrichers;
7
+ exports.hasSubagentEnrichers = hasSubagentEnrichers;
5
8
  exports.hasEnrichers = hasEnrichers;
6
9
  exports.clearEnrichers = clearEnrichers;
7
10
  const REGISTRY_KEY = "__CLAUDEYE_ENRICHER_REGISTRY__";
@@ -12,20 +15,40 @@ function getRegistry() {
12
15
  }
13
16
  return g[REGISTRY_KEY];
14
17
  }
15
- function registerEnricher(name, fn) {
18
+ function registerEnricher(name, fn, condition, scope = 'session', subagentType) {
16
19
  const registry = getRegistry();
20
+ const entry = { name, fn, scope };
21
+ if (condition)
22
+ entry.condition = condition;
23
+ if (subagentType)
24
+ entry.subagentType = subagentType;
17
25
  // Replace if an enricher with the same name already exists
18
26
  const idx = registry.findIndex((e) => e.name === name);
19
27
  if (idx >= 0) {
20
- registry[idx] = { name, fn };
28
+ registry[idx] = entry;
21
29
  }
22
30
  else {
23
- registry.push({ name, fn });
31
+ registry.push(entry);
24
32
  }
25
33
  }
26
34
  function getRegisteredEnrichers() {
27
35
  return getRegistry();
28
36
  }
37
+ function getSessionScopedEnrichers() {
38
+ return getRegistry().filter((e) => e.scope === 'session' || e.scope === 'both');
39
+ }
40
+ function getSubagentScopedEnrichers(subagentType) {
41
+ return getRegistry().filter((e) => {
42
+ if (e.scope !== 'subagent' && e.scope !== 'both')
43
+ return false;
44
+ if (e.subagentType && subagentType && e.subagentType !== subagentType)
45
+ return false;
46
+ return true;
47
+ });
48
+ }
49
+ function hasSubagentEnrichers() {
50
+ return getRegistry().some((e) => e.scope === 'subagent' || e.scope === 'both');
51
+ }
29
52
  function hasEnrichers() {
30
53
  return getRegistry().length > 0;
31
54
  }
@@ -6,33 +6,88 @@ exports.runAllEnrichers = runAllEnrichers;
6
6
  * Each enricher is individually try/caught so one failure doesn't block others.
7
7
  */
8
8
  const enrich_registry_1 = require("./enrich-registry");
9
- async function runAllEnrichers(entries, stats, projectName, sessionId) {
10
- const registeredEnrichers = (0, enrich_registry_1.getRegisteredEnrichers)();
9
+ const condition_registry_1 = require("./condition-registry");
10
+ async function runAllEnrichers(entries, stats, projectName, sessionId, enrichersToRun, contextOverrides) {
11
+ const registeredEnrichers = enrichersToRun !== null && enrichersToRun !== void 0 ? enrichersToRun : (0, enrich_registry_1.getRegisteredEnrichers)();
11
12
  const results = [];
12
13
  const overallStart = performance.now();
13
- for (const { name, fn } of registeredEnrichers) {
14
- const start = performance.now();
14
+ const context = Object.assign({ entries, stats, projectName, sessionId, scope: 'session' }, contextOverrides);
15
+ // Check global condition first
16
+ const globalCondition = (0, condition_registry_1.getGlobalCondition)();
17
+ let globalSkip = false;
18
+ if (globalCondition) {
15
19
  try {
16
- const data = await fn({ entries, stats, projectName, sessionId });
17
- const durationMs = Math.round(performance.now() - start);
18
- results.push({ name, data, durationMs });
20
+ const result = await globalCondition(context);
21
+ if (!result)
22
+ globalSkip = true;
19
23
  }
20
- catch (err) {
21
- const durationMs = Math.round(performance.now() - start);
24
+ catch (_a) {
25
+ globalSkip = true;
26
+ }
27
+ }
28
+ if (globalSkip) {
29
+ // All enrichers skipped due to global condition
30
+ for (const { name } of registeredEnrichers) {
22
31
  results.push({
23
32
  name,
24
33
  data: {},
25
- durationMs,
26
- error: err instanceof Error ? err.message : String(err),
34
+ durationMs: 0,
35
+ skipped: true,
27
36
  });
28
37
  }
29
38
  }
39
+ else {
40
+ for (const { name, fn, condition } of registeredEnrichers) {
41
+ // Check per-enrichment condition
42
+ if (condition) {
43
+ try {
44
+ const shouldRun = await condition(context);
45
+ if (!shouldRun) {
46
+ results.push({
47
+ name,
48
+ data: {},
49
+ durationMs: 0,
50
+ skipped: true,
51
+ });
52
+ continue;
53
+ }
54
+ }
55
+ catch (err) {
56
+ results.push({
57
+ name,
58
+ data: {},
59
+ durationMs: 0,
60
+ error: `Condition error: ${err instanceof Error ? err.message : String(err)}`,
61
+ });
62
+ continue;
63
+ }
64
+ }
65
+ const start = performance.now();
66
+ try {
67
+ const data = await fn(context);
68
+ const durationMs = Math.round(performance.now() - start);
69
+ results.push({ name, data, durationMs });
70
+ }
71
+ catch (err) {
72
+ const durationMs = Math.round(performance.now() - start);
73
+ results.push({
74
+ name,
75
+ data: {},
76
+ durationMs,
77
+ error: err instanceof Error ? err.message : String(err),
78
+ });
79
+ }
80
+ }
81
+ }
30
82
  const totalDurationMs = Math.round(performance.now() - overallStart);
31
83
  let errorCount = 0;
84
+ let skippedCount = 0;
32
85
  for (const r of results) {
33
- if (r.error)
86
+ if (r.skipped)
87
+ skippedCount++;
88
+ else if (r.error)
34
89
  errorCount++;
35
90
  }
36
- return { results, totalDurationMs, errorCount };
91
+ return { results, totalDurationMs, errorCount, skippedCount };
37
92
  }
38
93
  //# sourceMappingURL=enrich-runner.js.map
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerEval = registerEval;
4
4
  exports.getRegisteredEvals = getRegisteredEvals;
5
+ exports.getSessionScopedEvals = getSessionScopedEvals;
6
+ exports.getSubagentScopedEvals = getSubagentScopedEvals;
7
+ exports.hasSubagentEvals = hasSubagentEvals;
5
8
  exports.hasEvals = hasEvals;
6
9
  exports.clearEvals = clearEvals;
7
10
  const REGISTRY_KEY = "__CLAUDEYE_EVAL_REGISTRY__";
@@ -12,20 +15,40 @@ function getRegistry() {
12
15
  }
13
16
  return g[REGISTRY_KEY];
14
17
  }
15
- function registerEval(name, fn) {
18
+ function registerEval(name, fn, condition, scope = 'session', subagentType) {
16
19
  const registry = getRegistry();
20
+ const entry = { name, fn, scope };
21
+ if (condition)
22
+ entry.condition = condition;
23
+ if (subagentType)
24
+ entry.subagentType = subagentType;
17
25
  // Replace if an eval with the same name already exists
18
26
  const idx = registry.findIndex((e) => e.name === name);
19
27
  if (idx >= 0) {
20
- registry[idx] = { name, fn };
28
+ registry[idx] = entry;
21
29
  }
22
30
  else {
23
- registry.push({ name, fn });
31
+ registry.push(entry);
24
32
  }
25
33
  }
26
34
  function getRegisteredEvals() {
27
35
  return getRegistry();
28
36
  }
37
+ function getSessionScopedEvals() {
38
+ return getRegistry().filter((e) => e.scope === 'session' || e.scope === 'both');
39
+ }
40
+ function getSubagentScopedEvals(subagentType) {
41
+ return getRegistry().filter((e) => {
42
+ if (e.scope !== 'subagent' && e.scope !== 'both')
43
+ return false;
44
+ if (e.subagentType && subagentType && e.subagentType !== subagentType)
45
+ return false;
46
+ return true;
47
+ });
48
+ }
49
+ function hasSubagentEvals() {
50
+ return getRegistry().some((e) => e.scope === 'subagent' || e.scope === 'both');
51
+ }
29
52
  function hasEvals() {
30
53
  return getRegistry().length > 0;
31
54
  }
@@ -6,52 +6,110 @@ exports.runAllEvals = runAllEvals;
6
6
  * Each eval is individually try/caught so one failure doesn't block others.
7
7
  */
8
8
  const registry_1 = require("./registry");
9
+ const condition_registry_1 = require("./condition-registry");
9
10
  function clampScore(score) {
10
11
  if (score === undefined || score === null)
11
12
  return 1;
12
13
  return Math.max(0, Math.min(1, score));
13
14
  }
14
- async function runAllEvals(entries, stats, projectName, sessionId) {
15
- const registeredEvals = (0, registry_1.getRegisteredEvals)();
15
+ async function runAllEvals(entries, stats, projectName, sessionId, evalsToRun, contextOverrides) {
16
+ const registeredEvals = evalsToRun !== null && evalsToRun !== void 0 ? evalsToRun : (0, registry_1.getRegisteredEvals)();
16
17
  const results = [];
17
18
  const overallStart = performance.now();
18
- for (const { name, fn } of registeredEvals) {
19
- const start = performance.now();
19
+ const context = Object.assign({ entries, stats, projectName, sessionId, scope: 'session' }, contextOverrides);
20
+ // Check global condition first
21
+ const globalCondition = (0, condition_registry_1.getGlobalCondition)();
22
+ let globalSkip = false;
23
+ if (globalCondition) {
20
24
  try {
21
- const result = await fn({ entries, stats, projectName, sessionId });
22
- const durationMs = Math.round(performance.now() - start);
23
- results.push({
24
- name,
25
- pass: result.pass,
26
- score: clampScore(result.score),
27
- message: result.message,
28
- metadata: result.metadata,
29
- durationMs,
30
- });
25
+ const result = await globalCondition(context);
26
+ if (!result)
27
+ globalSkip = true;
28
+ }
29
+ catch (_a) {
30
+ globalSkip = true;
31
31
  }
32
- catch (err) {
33
- const durationMs = Math.round(performance.now() - start);
32
+ }
33
+ if (globalSkip) {
34
+ // All evals skipped due to global condition
35
+ for (const { name } of registeredEvals) {
34
36
  results.push({
35
37
  name,
36
38
  pass: false,
37
39
  score: 0,
38
- durationMs,
39
- error: err instanceof Error ? err.message : String(err),
40
+ durationMs: 0,
41
+ skipped: true,
40
42
  });
41
43
  }
42
44
  }
45
+ else {
46
+ for (const { name, fn, condition } of registeredEvals) {
47
+ // Check per-eval condition
48
+ if (condition) {
49
+ try {
50
+ const shouldRun = await condition(context);
51
+ if (!shouldRun) {
52
+ results.push({
53
+ name,
54
+ pass: false,
55
+ score: 0,
56
+ durationMs: 0,
57
+ skipped: true,
58
+ });
59
+ continue;
60
+ }
61
+ }
62
+ catch (err) {
63
+ results.push({
64
+ name,
65
+ pass: false,
66
+ score: 0,
67
+ durationMs: 0,
68
+ error: `Condition error: ${err instanceof Error ? err.message : String(err)}`,
69
+ });
70
+ continue;
71
+ }
72
+ }
73
+ const start = performance.now();
74
+ try {
75
+ const result = await fn(context);
76
+ const durationMs = Math.round(performance.now() - start);
77
+ results.push({
78
+ name,
79
+ pass: result.pass,
80
+ score: clampScore(result.score),
81
+ message: result.message,
82
+ metadata: result.metadata,
83
+ durationMs,
84
+ });
85
+ }
86
+ catch (err) {
87
+ const durationMs = Math.round(performance.now() - start);
88
+ results.push({
89
+ name,
90
+ pass: false,
91
+ score: 0,
92
+ durationMs,
93
+ error: err instanceof Error ? err.message : String(err),
94
+ });
95
+ }
96
+ }
97
+ }
43
98
  const totalDurationMs = Math.round(performance.now() - overallStart);
44
99
  let passCount = 0;
45
100
  let failCount = 0;
46
101
  let errorCount = 0;
102
+ let skippedCount = 0;
47
103
  for (const r of results) {
48
- if (r.error)
104
+ if (r.skipped)
105
+ skippedCount++;
106
+ else if (r.error)
49
107
  errorCount++;
50
108
  else if (r.pass)
51
109
  passCount++;
52
110
  else
53
111
  failCount++;
54
112
  }
55
- return { results, totalDurationMs, passCount, failCount, errorCount };
113
+ return { results, totalDurationMs, passCount, failCount, errorCount, skippedCount };
56
114
  }
57
115
  //# sourceMappingURL=runner.js.map