@tonyclaw/agent-inspector 3.0.45 → 3.0.47

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.
Files changed (343) hide show
  1. package/.output/{nitro.json → backend/nitro.json} +3 -3
  2. package/.output/backend-public/assets/index-D4LX-sw-.js +11 -0
  3. package/.output/cli.js +8018 -5451
  4. package/.output/server/_libs/extend.mjs +4 -8
  5. package/.output/server/_libs/jszip.mjs +9 -35
  6. package/.output/server/_libs/react-dom.mjs +2 -3
  7. package/.output/server/_libs/react.mjs +1 -27
  8. package/.output/server/_libs/tanstack__react-router.mjs +1 -329
  9. package/.output/server/_libs/tanstack__router-core.mjs +42 -100
  10. package/.output/server/_libs/use-sync-external-store.mjs +1 -64
  11. package/.output/server/_libs/ws.mjs +1 -1
  12. package/.output/server/_ssr/index.mjs +4 -4
  13. package/.output/server/_ssr/{publicBasePathContext-5264L3rX.mjs → publicBasePathContext-IH2ilOfu.mjs} +52 -24
  14. package/.output/server/_ssr/{router-BJ_ltLim.mjs → router-BwZEsYfS.mjs} +19794 -19444
  15. package/.output/server/_ssr/{start-C6MjPjxp.mjs → start-COQu_AgD.mjs} +1 -1
  16. package/.output/server/_tanstack-start-manifest_v-DnbdNeun.mjs +4 -0
  17. package/.output/server/index.mjs +5 -145
  18. package/.output/{public/assets/CompareDrawer-B3_TLTJh.js → ui/assets/CompareDrawer-V-8lPASC.js} +1 -1
  19. package/.output/{public/assets/InspectorPet-Cpn6hv4P.js → ui/assets/InspectorPet-D4CVnfdf.js} +1 -1
  20. package/.output/ui/assets/ProxyViewerContainer-CO3ZVHLX.js +59 -0
  21. package/.output/{public/assets/ReplayDialog-B3EKVdJk.js → ui/assets/ReplayDialog-CpGyTLtt.js} +1 -1
  22. package/.output/{public/assets/RequestAnatomy-COOQjyUC.js → ui/assets/RequestAnatomy-BLuJL9dZ.js} +1 -1
  23. package/.output/ui/assets/ResponseView-BuSC-CH7.js +2 -0
  24. package/.output/ui/assets/StreamingChunkSequence-DeA-JJKa.js +1 -0
  25. package/.output/{public/assets/_sessionId-zbgYl7ZJ.js → ui/assets/_sessionId-8HuHFhjo.js} +1 -1
  26. package/.output/{public/assets/_sessionId-BJlM3nmt.js → ui/assets/_sessionId-Chp67th6.js} +1 -1
  27. package/.output/ui/assets/favicon-DYEkHSNl.svg +21 -0
  28. package/.output/ui/assets/index-BvXp42al.css +1 -0
  29. package/.output/{public/assets/index-xF_NY8Yb.js → ui/assets/index-DPmKK_5d.js} +5 -5
  30. package/.output/{public/assets/index-BIK4bPTv.js → ui/assets/index-atoQrlb8.js} +1 -1
  31. package/.output/ui/assets/index-nY3E1vxV.js +73 -0
  32. package/.output/{public/assets/index-D2Qw6Ri2.js → ui/assets/index-nl9-dpZn.js} +1 -1
  33. package/.output/ui/assets/json-viewer-B9kIzqeX.js +1 -0
  34. package/.output/{public/assets/jszip.min-B_rfAUCe.js → ui/assets/jszip.min-B7tfyE-I.js} +1 -1
  35. package/.output/ui/index.html +229 -0
  36. package/.output/ui/runtime-config.js +2 -0
  37. package/.output/workers/logFinalizer.worker.js +979 -414
  38. package/.output/workers/sessionWorkerEntry.js +979 -414
  39. package/README.md +182 -43
  40. package/docs/instance-control.openapi.yaml +59 -4
  41. package/package.json +40 -6
  42. package/scripts/generate-theme-scales.mjs +3 -3
  43. package/src/{router.tsx → backend/router.tsx} +3 -15
  44. package/src/backend/routes/$.ts +26 -0
  45. package/src/backend/routes/__root.ts +4 -0
  46. package/src/backend/routes/api/-instances.ts +7 -0
  47. package/src/{routes → backend/routes}/api/alerts.summary.ts +3 -3
  48. package/src/{routes → backend/routes}/api/alerts.ts +4 -4
  49. package/src/{routes → backend/routes}/api/config.paths.ts +1 -1
  50. package/src/{routes → backend/routes}/api/config.ts +11 -2
  51. package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.help.ts +1 -1
  52. package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.install.ts +1 -1
  53. package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.runner-presets.ts +1 -1
  54. package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.upgrade.ts +1 -1
  55. package/src/{routes → backend/routes}/api/ecosystem.packages.ts +5 -1
  56. package/src/{routes → backend/routes}/api/ecosystem.recipes.$recipeId.run.ts +1 -1
  57. package/src/{routes → backend/routes}/api/ecosystem.tasks.$taskId.ts +1 -1
  58. package/src/{routes → backend/routes}/api/ecosystem.tasks.ts +1 -1
  59. package/src/{routes → backend/routes}/api/groups.$groupId.evidence.ts +2 -2
  60. package/src/{routes → backend/routes}/api/groups.$groupId.sessions.ts +2 -2
  61. package/src/{routes → backend/routes}/api/groups.$groupId.ts +2 -2
  62. package/src/{routes → backend/routes}/api/groups.ts +2 -2
  63. package/src/{routes → backend/routes}/api/health.ts +3 -3
  64. package/src/{routes → backend/routes}/api/instances.$name.connection.ts +1 -1
  65. package/src/{routes → backend/routes}/api/instances.$name.restart.ts +2 -2
  66. package/src/{routes → backend/routes}/api/instances.$name.start.ts +2 -2
  67. package/src/{routes → backend/routes}/api/instances.$name.stop.ts +2 -2
  68. package/src/{routes → backend/routes}/api/instances.$name.ts +1 -1
  69. package/src/{routes → backend/routes}/api/instances.ts +1 -1
  70. package/src/{routes → backend/routes}/api/knowledge.candidates.$candidateId.promote.ts +2 -2
  71. package/src/{routes → backend/routes}/api/knowledge.candidates.$candidateId.ts +2 -2
  72. package/src/{routes → backend/routes}/api/knowledge.candidates.ts +1 -1
  73. package/src/{routes → backend/routes}/api/knowledge.project-context.ts +2 -2
  74. package/src/{routes → backend/routes}/api/knowledge.search.ts +2 -2
  75. package/src/{routes → backend/routes}/api/knowledge.sessions.$sessionId.candidates.ts +3 -3
  76. package/src/{routes → backend/routes}/api/logs.$id.body.ts +6 -6
  77. package/src/{routes → backend/routes}/api/logs.$id.chunks.ts +5 -4
  78. package/src/{routes → backend/routes}/api/logs.$id.replay.ts +12 -11
  79. package/src/{routes → backend/routes}/api/logs.$id.ts +4 -3
  80. package/src/{routes → backend/routes}/api/logs.import.ts +3 -3
  81. package/src/{routes → backend/routes}/api/logs.stream.ts +11 -7
  82. package/src/{routes → backend/routes}/api/logs.ts +17 -9
  83. package/src/{routes → backend/routes}/api/mcp.ts +1 -1
  84. package/src/{routes → backend/routes}/api/models.ts +1 -1
  85. package/src/{routes → backend/routes}/api/pi-agent.ts +2 -2
  86. package/src/{routes → backend/routes}/api/providers.$providerId.model-metadata.ts +5 -5
  87. package/src/{routes → backend/routes}/api/providers.$providerId.test.log.ts +7 -7
  88. package/src/{routes → backend/routes}/api/providers.$providerId.ts +4 -4
  89. package/src/{routes → backend/routes}/api/providers.export.ts +1 -1
  90. package/src/{routes → backend/routes}/api/providers.import.ts +3 -3
  91. package/src/{routes → backend/routes}/api/providers.scan.ts +2 -2
  92. package/src/{routes → backend/routes}/api/providers.ts +9 -4
  93. package/src/{routes → backend/routes}/api/runs.$runId.evidence.ts +2 -2
  94. package/src/{routes → backend/routes}/api/runs.$runId.ts +2 -2
  95. package/src/{routes → backend/routes}/api/runs.ts +4 -4
  96. package/src/backend/routes/api/runtime.ts +46 -0
  97. package/src/{routes → backend/routes}/api/sessions.ts +3 -3
  98. package/src/{routes → backend/routes}/proxy/$.ts +1 -1
  99. package/src/{routes → backend/routes}/readyz.ts +1 -1
  100. package/src/{start.ts → backend/start.ts} +1 -1
  101. package/src/cli/alias.ts +2 -11
  102. package/src/cli/doctor.ts +32 -9
  103. package/src/cli/instance.ts +36 -13
  104. package/src/cli/instanceApi.ts +213 -0
  105. package/src/cli/instanceArgs.ts +46 -11
  106. package/src/cli/instanceControl.ts +10 -2
  107. package/src/cli/instanceModel.ts +18 -17
  108. package/src/cli/instanceRegistry.ts +0 -9
  109. package/src/cli/networkHints.ts +27 -14
  110. package/src/cli/onboard.ts +69 -2
  111. package/src/cli/onboardTarget.ts +89 -40
  112. package/src/cli/rustBackendPackage.ts +450 -0
  113. package/src/cli/templates/codex-skill-onboard.ts +44 -14
  114. package/src/cli/templates/skill-onboard.ts +64 -28
  115. package/src/cli.ts +341 -75
  116. package/src/components/ProxyViewer.tsx +11 -9
  117. package/src/components/ProxyViewerContainer.tsx +12 -11
  118. package/src/components/pi-agent/PiAgentPanel.tsx +2 -2
  119. package/src/components/providers/ProviderCard.tsx +1 -1
  120. package/src/components/providers/ProviderTestResultsView.tsx +1 -1
  121. package/src/components/providers/SettingsDialog.tsx +159 -144
  122. package/src/components/proxy-viewer/ApplicationBar.tsx +2 -1
  123. package/src/components/proxy-viewer/LogEntry.tsx +1 -1
  124. package/src/components/proxy-viewer/log-formats/index.ts +1 -1
  125. package/src/contracts/index.ts +5 -0
  126. package/src/contracts/log.ts +33 -3
  127. package/src/knowledge/types.ts +3 -2
  128. package/src/lib/alertContract.ts +2 -2
  129. package/src/lib/apiClient.ts +30 -7
  130. package/src/lib/apiFormat.ts +29 -0
  131. package/src/lib/backendImplementation.ts +16 -0
  132. package/src/lib/basePath.ts +29 -11
  133. package/src/lib/browserRuntimeContract.ts +124 -0
  134. package/src/lib/browserRuntimeResolver.ts +244 -0
  135. package/src/{proxy → lib}/claudeCodeStrip.ts +6 -7
  136. package/src/lib/codingAgentEndpoints.ts +38 -0
  137. package/src/lib/instanceContract.ts +30 -11
  138. package/src/lib/managedInstance.ts +9 -1
  139. package/src/lib/piAgentContract.ts +3 -2
  140. package/src/lib/publicBasePathContext.ts +40 -10
  141. package/src/lib/resourceLimits.ts +2 -0
  142. package/src/lib/runContract.ts +3 -3
  143. package/src/lib/sessionInfoContract.ts +3 -2
  144. package/src/mcp/instanceHandlers.ts +2 -0
  145. package/src/mcp/server.ts +19 -24
  146. package/src/proxy/config.ts +25 -30
  147. package/src/proxy/dataDir.ts +43 -7
  148. package/src/proxy/ecosystemTasks.ts +161 -70
  149. package/src/proxy/formats/registry.ts +6 -21
  150. package/src/proxy/handler.ts +129 -29
  151. package/src/proxy/identityProxy.ts +567 -39
  152. package/src/proxy/jsonlRecovery.ts +554 -0
  153. package/src/proxy/logFinalizer.ts +25 -10
  154. package/src/proxy/logImporter.ts +2 -1
  155. package/src/proxy/logIndex.ts +191 -95
  156. package/src/proxy/logger.ts +77 -14
  157. package/src/proxy/platformCommands.ts +41 -0
  158. package/src/proxy/privateDataPath.ts +310 -88
  159. package/src/proxy/rawStreamCapture.ts +194 -13
  160. package/src/proxy/runtimeAdmission.ts +5 -2
  161. package/src/proxy/runtimeHealth.ts +14 -1
  162. package/src/proxy/runtimeShutdown.ts +11 -1
  163. package/src/proxy/schemas.ts +7 -1
  164. package/src/proxy/sessionArchive.ts +70 -14
  165. package/src/proxy/sqliteLogIndex.ts +65 -42
  166. package/src/proxy/store.ts +141 -34
  167. package/src/proxy/uiAssetServer.ts +106 -0
  168. package/src/proxy/upstream.ts +29 -2
  169. package/src/ui/bootstrap.ts +167 -0
  170. package/src/ui/index.html +38 -0
  171. package/src/ui/logsStreamClient.ts +20 -0
  172. package/src/ui/main.tsx +13 -0
  173. package/src/ui/public/runtime-config.js +2 -0
  174. package/src/ui/router.tsx +13 -0
  175. package/src/ui/routes/__root.tsx +69 -0
  176. package/src/{routes → ui/routes}/index.tsx +2 -3
  177. package/src/{routes → ui/routes}/session/$sessionId.tsx +5 -11
  178. package/src/ui/runtimeDiscovery.ts +50 -0
  179. package/styles/globals.css +1 -0
  180. package/.output/public/assets/ProxyViewerContainer-BEAhuGOJ.js +0 -126
  181. package/.output/public/assets/ResponseView-DBCjkwye.js +0 -2
  182. package/.output/public/assets/StreamingChunkSequence-CuXhDgMo.js +0 -1
  183. package/.output/public/assets/index-BZo_8koU.js +0 -70
  184. package/.output/public/assets/index-ZWschkCh.css +0 -1
  185. package/.output/public/assets/json-viewer-B-Ao6pwW.js +0 -1
  186. package/.output/server/_libs/@radix-ui/react-accessible-icon+[...].mjs +0 -1
  187. package/.output/server/_libs/@radix-ui/react-dismissable-layer+[...].mjs +0 -344
  188. package/.output/server/_libs/@radix-ui/react-navigation-menu+[...].mjs +0 -2
  189. package/.output/server/_libs/@radix-ui/react-one-time-password-field+[...].mjs +0 -2
  190. package/.output/server/_libs/@radix-ui/react-password-toggle-field+[...].mjs +0 -2
  191. package/.output/server/_libs/@radix-ui/react-use-callback-ref+[...].mjs +0 -11
  192. package/.output/server/_libs/@radix-ui/react-use-controllable-state+[...].mjs +0 -69
  193. package/.output/server/_libs/@radix-ui/react-use-effect-event+[...].mjs +0 -1
  194. package/.output/server/_libs/@radix-ui/react-use-is-hydrated+[...].mjs +0 -28
  195. package/.output/server/_libs/@radix-ui/react-use-layout-effect+[...].mjs +0 -6
  196. package/.output/server/_libs/@radix-ui/react-visually-hidden+[...].mjs +0 -34
  197. package/.output/server/_libs/aria-hidden.mjs +0 -122
  198. package/.output/server/_libs/bail.mjs +0 -8
  199. package/.output/server/_libs/character-entities.mjs +0 -2130
  200. package/.output/server/_libs/class-variance-authority.mjs +0 -44
  201. package/.output/server/_libs/clsx.mjs +0 -16
  202. package/.output/server/_libs/comma-separated-tokens.mjs +0 -10
  203. package/.output/server/_libs/decode-named-character-reference+[...].mjs +0 -8
  204. package/.output/server/_libs/dequal.mjs +0 -27
  205. package/.output/server/_libs/detect-node-es.mjs +0 -1
  206. package/.output/server/_libs/devlop.mjs +0 -8
  207. package/.output/server/_libs/diff.mjs +0 -320
  208. package/.output/server/_libs/estree-util-is-identifier-name.mjs +0 -11
  209. package/.output/server/_libs/floating-ui__core.mjs +0 -725
  210. package/.output/server/_libs/floating-ui__dom.mjs +0 -622
  211. package/.output/server/_libs/floating-ui__react-dom.mjs +0 -292
  212. package/.output/server/_libs/floating-ui__utils.mjs +0 -320
  213. package/.output/server/_libs/get-nonce.mjs +0 -9
  214. package/.output/server/_libs/hast-util-to-jsx-runtime.mjs +0 -388
  215. package/.output/server/_libs/hast-util-whitespace.mjs +0 -10
  216. package/.output/server/_libs/html-url-attributes.mjs +0 -26
  217. package/.output/server/_libs/inline-style-parser.mjs +0 -142
  218. package/.output/server/_libs/is-plain-obj.mjs +0 -10
  219. package/.output/server/_libs/lucide-react.mjs +0 -1027
  220. package/.output/server/_libs/mdast-util-from-markdown.mjs +0 -717
  221. package/.output/server/_libs/mdast-util-to-hast.mjs +0 -710
  222. package/.output/server/_libs/mdast-util-to-string.mjs +0 -38
  223. package/.output/server/_libs/micromark-core-commonmark.mjs +0 -2259
  224. package/.output/server/_libs/micromark-factory-destination.mjs +0 -94
  225. package/.output/server/_libs/micromark-factory-label.mjs +0 -63
  226. package/.output/server/_libs/micromark-factory-space.mjs +0 -24
  227. package/.output/server/_libs/micromark-factory-title.mjs +0 -65
  228. package/.output/server/_libs/micromark-factory-whitespace.mjs +0 -22
  229. package/.output/server/_libs/micromark-util-character.mjs +0 -44
  230. package/.output/server/_libs/micromark-util-chunked.mjs +0 -36
  231. package/.output/server/_libs/micromark-util-classify-character+[...].mjs +0 -12
  232. package/.output/server/_libs/micromark-util-combine-extensions+[...].mjs +0 -41
  233. package/.output/server/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +0 -19
  234. package/.output/server/_libs/micromark-util-decode-string.mjs +0 -21
  235. package/.output/server/_libs/micromark-util-encode.mjs +0 -1
  236. package/.output/server/_libs/micromark-util-html-tag-name.mjs +0 -69
  237. package/.output/server/_libs/micromark-util-normalize-identifier+[...].mjs +0 -6
  238. package/.output/server/_libs/micromark-util-resolve-all.mjs +0 -15
  239. package/.output/server/_libs/micromark-util-sanitize-uri.mjs +0 -41
  240. package/.output/server/_libs/micromark-util-subtokenize.mjs +0 -346
  241. package/.output/server/_libs/micromark.mjs +0 -906
  242. package/.output/server/_libs/property-information.mjs +0 -1209
  243. package/.output/server/_libs/radix-ui.mjs +0 -1
  244. package/.output/server/_libs/radix-ui__number.mjs +0 -6
  245. package/.output/server/_libs/radix-ui__primitive.mjs +0 -11
  246. package/.output/server/_libs/radix-ui__react-accordion.mjs +0 -1
  247. package/.output/server/_libs/radix-ui__react-alert-dialog.mjs +0 -1
  248. package/.output/server/_libs/radix-ui__react-arrow.mjs +0 -23
  249. package/.output/server/_libs/radix-ui__react-aspect-ratio.mjs +0 -1
  250. package/.output/server/_libs/radix-ui__react-avatar.mjs +0 -1
  251. package/.output/server/_libs/radix-ui__react-checkbox.mjs +0 -1
  252. package/.output/server/_libs/radix-ui__react-collapsible.mjs +0 -144
  253. package/.output/server/_libs/radix-ui__react-collection.mjs +0 -69
  254. package/.output/server/_libs/radix-ui__react-compose-refs.mjs +0 -38
  255. package/.output/server/_libs/radix-ui__react-context-menu.mjs +0 -1
  256. package/.output/server/_libs/radix-ui__react-context.mjs +0 -64
  257. package/.output/server/_libs/radix-ui__react-dialog.mjs +0 -280
  258. package/.output/server/_libs/radix-ui__react-direction.mjs +0 -9
  259. package/.output/server/_libs/radix-ui__react-dropdown-menu.mjs +0 -1
  260. package/.output/server/_libs/radix-ui__react-focus-guards.mjs +0 -39
  261. package/.output/server/_libs/radix-ui__react-focus-scope.mjs +0 -210
  262. package/.output/server/_libs/radix-ui__react-form.mjs +0 -1
  263. package/.output/server/_libs/radix-ui__react-hover-card.mjs +0 -1
  264. package/.output/server/_libs/radix-ui__react-id.mjs +0 -14
  265. package/.output/server/_libs/radix-ui__react-label.mjs +0 -1
  266. package/.output/server/_libs/radix-ui__react-menu.mjs +0 -1
  267. package/.output/server/_libs/radix-ui__react-menubar.mjs +0 -1
  268. package/.output/server/_libs/radix-ui__react-popover.mjs +0 -1
  269. package/.output/server/_libs/radix-ui__react-popper.mjs +0 -340
  270. package/.output/server/_libs/radix-ui__react-portal.mjs +0 -16
  271. package/.output/server/_libs/radix-ui__react-presence.mjs +0 -173
  272. package/.output/server/_libs/radix-ui__react-primitive.mjs +0 -42
  273. package/.output/server/_libs/radix-ui__react-progress.mjs +0 -1
  274. package/.output/server/_libs/radix-ui__react-radio-group.mjs +0 -1
  275. package/.output/server/_libs/radix-ui__react-roving-focus.mjs +0 -235
  276. package/.output/server/_libs/radix-ui__react-scroll-area.mjs +0 -731
  277. package/.output/server/_libs/radix-ui__react-select.mjs +0 -1207
  278. package/.output/server/_libs/radix-ui__react-separator.mjs +0 -28
  279. package/.output/server/_libs/radix-ui__react-slider.mjs +0 -1
  280. package/.output/server/_libs/radix-ui__react-slot.mjs +0 -132
  281. package/.output/server/_libs/radix-ui__react-switch.mjs +0 -1
  282. package/.output/server/_libs/radix-ui__react-tabs.mjs +0 -194
  283. package/.output/server/_libs/radix-ui__react-toast.mjs +0 -2
  284. package/.output/server/_libs/radix-ui__react-toggle-group.mjs +0 -1
  285. package/.output/server/_libs/radix-ui__react-toggle.mjs +0 -1
  286. package/.output/server/_libs/radix-ui__react-toolbar.mjs +0 -1
  287. package/.output/server/_libs/radix-ui__react-tooltip.mjs +0 -498
  288. package/.output/server/_libs/radix-ui__react-use-previous.mjs +0 -14
  289. package/.output/server/_libs/radix-ui__react-use-size.mjs +0 -39
  290. package/.output/server/_libs/react-markdown.mjs +0 -235
  291. package/.output/server/_libs/react-remove-scroll-bar.mjs +0 -82
  292. package/.output/server/_libs/react-remove-scroll.mjs +0 -328
  293. package/.output/server/_libs/react-style-singleton.mjs +0 -69
  294. package/.output/server/_libs/remark-parse.mjs +0 -19
  295. package/.output/server/_libs/remark-rehype.mjs +0 -21
  296. package/.output/server/_libs/space-separated-tokens.mjs +0 -6
  297. package/.output/server/_libs/style-to-js.mjs +0 -72
  298. package/.output/server/_libs/style-to-object.mjs +0 -38
  299. package/.output/server/_libs/swr.mjs +0 -947
  300. package/.output/server/_libs/tailwind-merge.mjs +0 -3255
  301. package/.output/server/_libs/tanstack__react-virtual.mjs +0 -130
  302. package/.output/server/_libs/tanstack__virtual-core.mjs +0 -1319
  303. package/.output/server/_libs/three.mjs +0 -26016
  304. package/.output/server/_libs/trim-lines.mjs +0 -41
  305. package/.output/server/_libs/trough.mjs +0 -85
  306. package/.output/server/_libs/tslib.mjs +0 -1
  307. package/.output/server/_libs/ungap__structured-clone.mjs +0 -212
  308. package/.output/server/_libs/unified.mjs +0 -661
  309. package/.output/server/_libs/unist-util-is.mjs +0 -100
  310. package/.output/server/_libs/unist-util-position.mjs +0 -27
  311. package/.output/server/_libs/unist-util-stringify-position.mjs +0 -27
  312. package/.output/server/_libs/unist-util-visit-parents.mjs +0 -82
  313. package/.output/server/_libs/unist-util-visit.mjs +0 -24
  314. package/.output/server/_libs/use-callback-ref.mjs +0 -66
  315. package/.output/server/_libs/use-sidecar.mjs +0 -106
  316. package/.output/server/_libs/vfile-message.mjs +0 -138
  317. package/.output/server/_libs/vfile.mjs +0 -467
  318. package/.output/server/_sessionId-CJ99gZFV.mjs +0 -84
  319. package/.output/server/_sessionId-DEjScBpK.mjs +0 -146
  320. package/.output/server/_ssr/CompareDrawer-DtOIMeQB.mjs +0 -1060
  321. package/.output/server/_ssr/InspectorPet-CXc4oCBQ.mjs +0 -938
  322. package/.output/server/_ssr/ProxyViewerContainer-DVPlwfkt.mjs +0 -17632
  323. package/.output/server/_ssr/ReplayDialog-BQEA95qC.mjs +0 -725
  324. package/.output/server/_ssr/RequestAnatomy-BMyd8B7Q.mjs +0 -837
  325. package/.output/server/_ssr/ResponseView-qrTaEIM8.mjs +0 -757
  326. package/.output/server/_ssr/StreamingChunkSequence-BFTL8mIy.mjs +0 -274
  327. package/.output/server/_ssr/index-Bcj1Hcy4.mjs +0 -135
  328. package/.output/server/_ssr/index-DW-M7XUG.mjs +0 -84
  329. package/.output/server/_ssr/json-viewer-DiI0Yjsn.mjs +0 -483
  330. package/.output/server/_tanstack-start-manifest_v-C6pXXX9R.mjs +0 -4
  331. package/.output/server/node_modules/tslib/modules/index.js +0 -70
  332. package/.output/server/node_modules/tslib/modules/package.json +0 -3
  333. package/.output/server/node_modules/tslib/package.json +0 -47
  334. package/.output/server/node_modules/tslib/tslib.js +0 -484
  335. package/.output/server/package.json +0 -9
  336. package/src/routes/__root.tsx +0 -170
  337. package/src/routes/api/-instances.ts +0 -109
  338. /package/.output/{public → ui}/assets/agent-inspector-58K1_MsC.ico +0 -0
  339. /package/.output/{public → ui}/assets/alibaba-TTwafVwX.svg +0 -0
  340. /package/.output/{public → ui}/assets/minimax-BPMzvuL-.jpeg +0 -0
  341. /package/.output/{public → ui}/assets/qwen-mMn3f5ul.webp +0 -0
  342. /package/.output/{public → ui}/assets/zhipuai-BPNAnxo-.svg +0 -0
  343. /package/src/{routes → backend/routes}/livez.ts +0 -0
@@ -5,9 +5,9 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // src/proxy/logFinalizer.ts
8
- import { Buffer as Buffer3 } from "node:buffer";
9
- import { existsSync as existsSync5, readFileSync as readFileSync2, rmSync as rmSync2, statSync as statSync2 } from "node:fs";
10
- import { join as join5 } from "node:path";
8
+ import { Buffer as Buffer4 } from "node:buffer";
9
+ import { existsSync as existsSync5, readFileSync as readFileSync2, rmSync as rmSync2, statSync } from "node:fs";
10
+ import { join as join6 } from "node:path";
11
11
  import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
12
12
 
13
13
  // src/proxy/chunkStorage.ts
@@ -16,29 +16,38 @@ import {
16
16
  readFileSync,
17
17
  unlinkSync,
18
18
  existsSync as existsSync3,
19
- renameSync,
19
+ renameSync as renameSync2,
20
20
  copyFileSync
21
21
  } from "node:fs";
22
- import { join as join3, isAbsolute as isAbsolute2 } from "node:path";
22
+ import { join as join4, isAbsolute as isAbsolute2 } from "node:path";
23
23
 
24
24
  // src/proxy/logger.ts
25
- import { Buffer as Buffer2 } from "node:buffer";
26
- import { appendFileSync } from "node:fs";
27
- import { appendFile, readdir, rename, stat, unlink } from "node:fs/promises";
25
+ import { Buffer as Buffer3 } from "node:buffer";
26
+ import { closeSync as closeSync2, constants as constants3, fsyncSync, openSync as openSync2, writeSync } from "node:fs";
27
+ import { appendFile, readdir as readdir2, rename, stat as stat2, unlink as unlink2 } from "node:fs/promises";
28
28
  import path from "node:path";
29
29
 
30
30
  // src/proxy/dataDir.ts
31
- import { cpSync, existsSync as existsSync2, rmSync } from "node:fs";
31
+ import { cpSync, existsSync, readdirSync as readdirSync2, renameSync, rmSync } from "node:fs";
32
32
  import { isAbsolute, join as join2 } from "node:path";
33
33
 
34
34
  // src/proxy/privateDataPath.ts
35
35
  import { spawnSync } from "node:child_process";
36
- import { chmodSync, existsSync, lstatSync, mkdirSync, readdirSync, statSync } from "node:fs";
37
- import { dirname, join } from "node:path";
36
+ import {
37
+ closeSync,
38
+ constants,
39
+ fchmodSync,
40
+ fstatSync,
41
+ lstatSync,
42
+ mkdirSync,
43
+ openSync,
44
+ readdirSync,
45
+ realpathSync
46
+ } from "node:fs";
47
+ import { join, parse, resolve, sep } from "node:path";
38
48
  var PRIVATE_DIRECTORY_MODE = 448;
39
49
  var PRIVATE_FILE_MODE = 384;
40
- var securedPaths = /* @__PURE__ */ new Set();
41
- var securedFileIdentities = /* @__PURE__ */ new Map();
50
+ var securedPathFingerprints = /* @__PURE__ */ new Map();
42
51
  var cachedWindowsSid = null;
43
52
  function windowsSystemPath(executable) {
44
53
  const systemRoot = process.env["SystemRoot"] ?? "C:\\Windows";
@@ -68,9 +77,7 @@ function resolveWindowsUserSid(run) {
68
77
  function windowsBroadGroupRemovalArgs() {
69
78
  return ["/remove:g", "*S-1-1-0", "*S-1-5-11", "*S-1-5-32-545"];
70
79
  }
71
- function applyWindowsUserOnlyAcl(path2, kind, run = runWindowsCommand) {
72
- const sid = resolveWindowsUserSid(run);
73
- if (sid === null) return false;
80
+ function applyWindowsAclWithSid(path2, kind, sid, run) {
74
81
  const access = kind === "directory" ? `(OI)(CI)F` : "F";
75
82
  const result = run("icacls.exe", [
76
83
  path2,
@@ -82,93 +89,226 @@ function applyWindowsUserOnlyAcl(path2, kind, run = runWindowsCommand) {
82
89
  ]);
83
90
  return result.status === 0;
84
91
  }
85
- function applyWindowsUserOnlyTreeAcl(root, run = runWindowsCommand) {
92
+ function applyWindowsUserOnlyAcl(path2, kind, run = runWindowsCommand) {
86
93
  const sid = resolveWindowsUserSid(run);
87
- if (sid === null) return false;
88
- const result = run("icacls.exe", [
89
- root,
90
- "/inheritance:r",
91
- "/grant:r",
92
- `*${sid}:(OI)(CI)F`,
93
- `*${sid}:F`,
94
- ...windowsBroadGroupRemovalArgs(),
95
- "/T",
96
- "/C",
97
- "/Q"
98
- ]);
99
- return result.status === 0;
94
+ return sid !== null && applyWindowsAclWithSid(path2, kind, sid, run);
100
95
  }
101
- function applyPrivatePermissionsSync(path2, kind) {
96
+ function comparablePath(path2) {
97
+ let normalized = path2;
102
98
  if (process.platform === "win32") {
103
- return applyWindowsUserOnlyAcl(path2, kind);
99
+ if (normalized.startsWith("\\\\?\\UNC\\")) {
100
+ normalized = `\\\\${normalized.slice(8)}`;
101
+ } else if (normalized.startsWith("\\\\?\\")) {
102
+ normalized = normalized.slice(4);
103
+ }
104
104
  }
105
+ const absolute = resolve(normalized);
106
+ return process.platform === "win32" ? absolute.toLowerCase() : absolute;
107
+ }
108
+ function pathIdentity(stats) {
109
+ return `${String(stats.dev)}:${String(stats.ino)}:${String(stats.birthtimeMs)}`;
110
+ }
111
+ function readPathEntry(path2) {
112
+ let stats;
105
113
  try {
106
- chmodSync(path2, kind === "directory" ? PRIVATE_DIRECTORY_MODE : PRIVATE_FILE_MODE);
107
- return true;
114
+ const observed = lstatSync(path2);
115
+ if (observed === void 0) return { status: "missing" };
116
+ stats = observed;
108
117
  } catch {
109
- return false;
118
+ return { status: "missing" };
110
119
  }
111
- }
112
- function secureOnce(path2, kind) {
113
- const cacheKey = `${kind}:${path2}`;
114
- if (securedPaths.has(cacheKey)) return true;
115
- if (!applyPrivatePermissionsSync(path2, kind)) return false;
116
- securedPaths.add(cacheKey);
117
- return true;
118
- }
119
- function ensurePrivateDirectorySync(path2) {
120
+ if (stats.isSymbolicLink()) return { status: "unsafe" };
121
+ const kind = stats.isDirectory() ? "directory" : stats.isFile() ? "file" : null;
122
+ if (kind === null) return { status: "unsafe" };
123
+ let canonical;
120
124
  try {
121
- mkdirSync(path2, { recursive: true, mode: PRIVATE_DIRECTORY_MODE });
125
+ canonical = realpathSync.native(path2);
122
126
  } catch {
123
- return false;
127
+ return { status: "unsafe" };
124
128
  }
125
- return secureOnce(path2, "directory");
129
+ if (comparablePath(canonical) !== comparablePath(path2)) return { status: "unsafe" };
130
+ return {
131
+ status: "ok",
132
+ entry: {
133
+ path: path2,
134
+ kind,
135
+ identity: pathIdentity(stats),
136
+ mode: stats.mode & 511
137
+ }
138
+ };
139
+ }
140
+ function snapshotPathChain(path2) {
141
+ const absolutePath = resolve(path2);
142
+ const root = parse(absolutePath).root;
143
+ const suffix = absolutePath.slice(root.length);
144
+ const parts = suffix === "" ? [] : suffix.split(sep).filter((part) => part !== "");
145
+ const entries = [];
146
+ let current = root;
147
+ const rootRead = readPathEntry(root);
148
+ if (rootRead.status !== "ok" || rootRead.entry.kind !== "directory") return null;
149
+ entries.push(rootRead.entry);
150
+ for (let index = 0; index < parts.length; index += 1) {
151
+ const part = parts[index];
152
+ if (part === void 0) return null;
153
+ current = join(current, part);
154
+ const read = readPathEntry(current);
155
+ if (read.status === "unsafe") return null;
156
+ if (read.status === "missing") {
157
+ return {
158
+ absolutePath,
159
+ complete: false,
160
+ entries,
161
+ missingParts: parts.slice(index)
162
+ };
163
+ }
164
+ if (index < parts.length - 1 && read.entry.kind !== "directory") return null;
165
+ entries.push(read.entry);
166
+ }
167
+ return { absolutePath, complete: true, entries, missingParts: [] };
126
168
  }
127
- function securePrivateFileSync(path2, forceAcl = false) {
128
- let identity;
169
+ function chainFingerprint(snapshot) {
170
+ return snapshot.entries.map((entry) => `${entry.path}:${entry.identity}`).join("|");
171
+ }
172
+ function snapshotsRetainPrefix(before, after) {
173
+ if (after.entries.length < before.entries.length) return false;
174
+ return before.entries.every((entry, index) => {
175
+ const next = after.entries[index];
176
+ return next !== void 0 && next.path === entry.path && next.identity === entry.identity;
177
+ });
178
+ }
179
+ function completeSnapshotForKind(path2, kind) {
180
+ const snapshot = snapshotPathChain(path2);
181
+ if (snapshot === null || !snapshot.complete) return null;
182
+ const leaf = snapshot.entries.at(-1);
183
+ return leaf !== void 0 && leaf.kind === kind ? snapshot : null;
184
+ }
185
+ function applyPosixPermissions(path2, kind, expectedIdentity) {
186
+ let descriptor = null;
129
187
  try {
130
- const stats = statSync(path2);
131
- identity = `${String(stats.dev)}:${String(stats.ino)}:${String(stats.birthtimeMs)}`;
188
+ const directoryFlag = kind === "directory" ? constants.O_DIRECTORY : 0;
189
+ descriptor = openSync(path2, constants.O_RDONLY | constants.O_NOFOLLOW | directoryFlag);
190
+ const before = fstatSync(descriptor);
191
+ if (pathIdentity(before) !== expectedIdentity) return false;
192
+ fchmodSync(descriptor, kind === "directory" ? PRIVATE_DIRECTORY_MODE : PRIVATE_FILE_MODE);
193
+ const after = fstatSync(descriptor);
194
+ return pathIdentity(after) === expectedIdentity && (after.mode & 511) === (kind === "directory" ? PRIVATE_DIRECTORY_MODE : PRIVATE_FILE_MODE);
132
195
  } catch {
133
196
  return false;
197
+ } finally {
198
+ if (descriptor !== null) {
199
+ try {
200
+ closeSync(descriptor);
201
+ } catch {
202
+ }
203
+ }
134
204
  }
135
- if (securedFileIdentities.get(path2) === identity) return true;
136
- if (process.platform === "win32" && !forceAcl && securedPaths.has(`directory:${dirname(path2)}`)) {
137
- securedFileIdentities.set(path2, identity);
138
- return true;
205
+ }
206
+ function permissionsArePrivate(entry) {
207
+ if (process.platform === "win32") return true;
208
+ return entry.mode === (entry.kind === "directory" ? PRIVATE_DIRECTORY_MODE : PRIVATE_FILE_MODE);
209
+ }
210
+ function secureExistingPath(path2, kind, forcePermissions = false) {
211
+ const before = completeSnapshotForKind(path2, kind);
212
+ if (before === null) return false;
213
+ const leaf = before.entries.at(-1);
214
+ if (leaf === void 0) return false;
215
+ const cacheKey = `${kind}:${before.absolutePath}`;
216
+ const beforeFingerprint = chainFingerprint(before);
217
+ if (!forcePermissions && securedPathFingerprints.get(cacheKey) === beforeFingerprint && permissionsArePrivate(leaf)) {
218
+ const cachedCheck = completeSnapshotForKind(path2, kind);
219
+ return cachedCheck !== null && chainFingerprint(cachedCheck) === beforeFingerprint;
139
220
  }
140
- if (!applyPrivatePermissionsSync(path2, "file")) return false;
141
- securedFileIdentities.set(path2, identity);
221
+ const applied = process.platform === "win32" ? applyWindowsUserOnlyAcl(path2, kind) : applyPosixPermissions(path2, kind, leaf.identity);
222
+ if (!applied) return false;
223
+ const after = completeSnapshotForKind(path2, kind);
224
+ if (after === null || !snapshotsRetainPrefix(before, after)) return false;
225
+ const afterLeaf = after.entries.at(-1);
226
+ if (afterLeaf === void 0 || afterLeaf.identity !== leaf.identity) return false;
227
+ if (!permissionsArePrivate(afterLeaf)) return false;
228
+ securedPathFingerprints.set(cacheKey, chainFingerprint(after));
142
229
  return true;
143
230
  }
144
- function securePrivateTreeSync(root) {
145
- if (!existsSync(root)) return false;
146
- let stats;
147
- try {
148
- stats = lstatSync(root);
149
- } catch {
150
- return false;
231
+ function ensurePrivateDirectorySync(path2) {
232
+ const before = snapshotPathChain(path2);
233
+ if (before === null) return false;
234
+ let current = before.entries.at(-1)?.path;
235
+ if (current === void 0) return false;
236
+ for (const part of before.missingParts) {
237
+ const next = join(current, part);
238
+ try {
239
+ mkdirSync(next, { mode: PRIVATE_DIRECTORY_MODE });
240
+ } catch {
241
+ const raced = readPathEntry(next);
242
+ if (raced.status !== "ok" || raced.entry.kind !== "directory") return false;
243
+ }
244
+ if (!secureExistingPath(next, "directory", true)) return false;
245
+ current = next;
151
246
  }
152
- if (stats.isSymbolicLink()) return true;
153
- if (!stats.isDirectory()) return securePrivateFileSync(root, true);
154
- if (process.platform === "win32") {
155
- if (!applyWindowsUserOnlyTreeAcl(root)) return false;
156
- securedPaths.add(`directory:${root}`);
247
+ const complete = completeSnapshotForKind(path2, "directory");
248
+ if (complete === null || !snapshotsRetainPrefix(before, complete)) return false;
249
+ return secureExistingPath(path2, "directory");
250
+ }
251
+ function securePrivateFileSync(path2, forceAcl = false) {
252
+ return secureExistingPath(path2, "file", forceAcl);
253
+ }
254
+ function collectSafeTree(root) {
255
+ const collected = [];
256
+ const visit = (path2) => {
257
+ const snapshot = snapshotPathChain(path2);
258
+ if (snapshot === null || !snapshot.complete) return false;
259
+ const leaf = snapshot.entries.at(-1);
260
+ if (leaf === void 0) return false;
261
+ const fingerprint = chainFingerprint(snapshot);
262
+ collected.push({ path: snapshot.absolutePath, kind: leaf.kind, fingerprint });
263
+ if (leaf.kind === "file") return true;
264
+ let entries;
265
+ try {
266
+ entries = readdirSync(path2);
267
+ } catch {
268
+ return false;
269
+ }
270
+ const afterRead = completeSnapshotForKind(path2, "directory");
271
+ if (afterRead === null || chainFingerprint(afterRead) !== fingerprint) return false;
272
+ for (const entry of entries) {
273
+ if (!visit(join(path2, entry))) return false;
274
+ }
157
275
  return true;
276
+ };
277
+ return visit(root) ? collected : null;
278
+ }
279
+ function treeFingerprintsMatch(expected, observed) {
280
+ if (observed === null || observed.length !== expected.length) return false;
281
+ return expected.every((entry, index) => {
282
+ const next = observed[index];
283
+ return next !== void 0 && next.path === entry.path && next.kind === entry.kind && next.fingerprint === entry.fingerprint;
284
+ });
285
+ }
286
+ function isPathTreeFreeOfIndirectionSync(root) {
287
+ return collectSafeTree(root) !== null;
288
+ }
289
+ function applyWindowsUserOnlyTreeAcl(root, run = runWindowsCommand) {
290
+ const entries = collectSafeTree(root);
291
+ if (entries === null) return false;
292
+ const sid = resolveWindowsUserSid(run);
293
+ if (sid === null) return false;
294
+ for (const entry of entries) {
295
+ const before = completeSnapshotForKind(entry.path, entry.kind);
296
+ if (before === null || chainFingerprint(before) !== entry.fingerprint) return false;
297
+ if (!applyWindowsAclWithSid(entry.path, entry.kind, sid, run)) return false;
298
+ const after = completeSnapshotForKind(entry.path, entry.kind);
299
+ if (after === null || chainFingerprint(after) !== entry.fingerprint) return false;
300
+ securedPathFingerprints.set(`${entry.kind}:${entry.path}`, entry.fingerprint);
158
301
  }
159
- if (!ensurePrivateDirectorySync(root)) return false;
160
- let entries;
161
- try {
162
- entries = readdirSync(root);
163
- } catch {
164
- return false;
165
- }
166
- let secured = true;
302
+ return treeFingerprintsMatch(entries, collectSafeTree(root));
303
+ }
304
+ function securePrivateTreeSync(root) {
305
+ const entries = collectSafeTree(root);
306
+ if (entries === null) return false;
307
+ if (process.platform === "win32") return applyWindowsUserOnlyTreeAcl(root);
167
308
  for (const entry of entries) {
168
- const childPath = join(root, entry);
169
- if (!securePrivateTreeSync(childPath)) secured = false;
309
+ if (!secureExistingPath(entry.path, entry.kind, true)) return false;
170
310
  }
171
- return secured;
311
+ return treeFingerprintsMatch(entries, collectSafeTree(root));
172
312
  }
173
313
 
174
314
  // src/proxy/dataDir.ts
@@ -176,7 +316,7 @@ var CURRENT_DATA_DIR_NAME = ".agent-inspector";
176
316
  var LEGACY_DATA_DIR_NAMES = [".llm-inspector", ".llm-agent"];
177
317
  function getDataDir() {
178
318
  migrateLegacyDataDirs();
179
- return resolveDataDir(existsSync2);
319
+ return resolveDataDir(existsSync);
180
320
  }
181
321
  function hasDataDirState(pathExists, dir) {
182
322
  return pathExists(join2(dir, "providers.json")) || pathExists(join2(dir, "config.json")) || pathExists(join2(dir, "logs")) || pathExists(join2(dir, "chunks"));
@@ -203,293 +343,52 @@ function migrateLegacyDataDirs() {
203
343
  if (hasExplicitDataDir()) return;
204
344
  const base = defaultBaseDir();
205
345
  const currentDir = join2(base, CURRENT_DATA_DIR_NAME);
206
- if (hasDataDirState(existsSync2, currentDir)) return;
346
+ if (hasDataDirState(existsSync, currentDir)) return;
207
347
  for (const legacyName of LEGACY_DATA_DIR_NAMES) {
208
348
  const legacyDir = join2(base, legacyName);
209
- if (!existsSync2(legacyDir)) continue;
349
+ if (!existsSync(legacyDir)) continue;
350
+ const stagingDir = join2(
351
+ base,
352
+ `${CURRENT_DATA_DIR_NAME}.migration-${String(process.pid)}-${String(Date.now())}`
353
+ );
210
354
  try {
211
- if (!ensurePrivateDirectorySync(currentDir)) return;
212
- cpSync(legacyDir, currentDir, { recursive: true, force: true });
213
- if (!securePrivateTreeSync(currentDir)) return;
355
+ if (!isPathTreeFreeOfIndirectionSync(legacyDir)) return;
356
+ if (existsSync(currentDir)) {
357
+ if (readdirSync2(currentDir).length > 0) return;
358
+ rmSync(currentDir, { recursive: true, force: false });
359
+ }
360
+ if (!ensurePrivateDirectorySync(stagingDir)) return;
361
+ for (const entry of readdirSync2(legacyDir)) {
362
+ cpSync(join2(legacyDir, entry), join2(stagingDir, entry), {
363
+ recursive: true,
364
+ force: false,
365
+ errorOnExist: true
366
+ });
367
+ }
368
+ if (!isPathTreeFreeOfIndirectionSync(legacyDir)) {
369
+ rmSync(stagingDir, { recursive: true, force: true });
370
+ return;
371
+ }
372
+ if (!securePrivateTreeSync(stagingDir)) {
373
+ rmSync(stagingDir, { recursive: true, force: true });
374
+ return;
375
+ }
376
+ renameSync(stagingDir, currentDir);
214
377
  rmSync(legacyDir, { recursive: true, force: true });
378
+ return;
215
379
  } catch {
380
+ if (existsSync(stagingDir)) rmSync(stagingDir, { recursive: true, force: true });
381
+ return;
216
382
  }
217
383
  }
218
384
  }
219
385
 
220
- // src/proxy/logger.ts
221
- var DAY_MS = 24 * 60 * 60 * 1e3;
222
- var DEFAULT_RETENTION_DAYS = 7;
223
- var DEFAULT_APP_LOG_MAX_BYTES = 10 * 1024 * 1024;
224
- var DEFAULT_APP_LOG_MAX_FILES = 5;
225
- function writeStderrFallback(message, error51) {
226
- process.stderr.write(`${message} ${String(error51)}
227
- `);
228
- }
229
- function resolveLogDir() {
230
- const logDirEnv = process.env["LOG_DIR"];
231
- if (logDirEnv !== void 0 && logDirEnv !== "") {
232
- return path.isAbsolute(logDirEnv) ? logDirEnv : path.join(getDataDir(), logDirEnv);
233
- }
234
- return path.join(getDataDir(), "logs");
235
- }
236
- function getLogFilePath() {
237
- const date5 = /* @__PURE__ */ new Date();
238
- const yyyy = date5.getUTCFullYear();
239
- const mm = String(date5.getUTCMonth() + 1).padStart(2, "0");
240
- const dd = String(date5.getUTCDate()).padStart(2, "0");
241
- return path.join(resolveLogDir(), `${yyyy}-${mm}-${dd}.jsonl`);
242
- }
243
- function getInspectorLogPath() {
244
- const logFileEnv = process.env["AGENT_INSPECTOR_LOG_FILE"];
245
- if (logFileEnv !== void 0 && logFileEnv !== "") {
246
- return logFileEnv;
247
- }
248
- return path.join(getDataDir(), "logs", "inspector.log");
249
- }
250
- function readBoundedInteger(name, fallback, minimum, maximum) {
251
- const raw = process.env[name];
252
- if (raw === void 0 || raw === "") return fallback;
253
- const parsed = Number(raw);
254
- if (!Number.isInteger(parsed) || parsed < minimum || parsed > maximum) return fallback;
255
- return parsed;
256
- }
257
- function getApplicationLogPolicy() {
258
- const retentionDays = readBoundedInteger("LOG_RETENTION_DAYS", DEFAULT_RETENTION_DAYS, 1, 3650);
259
- return {
260
- maxBytes: readBoundedInteger(
261
- "AGENT_INSPECTOR_APP_LOG_MAX_BYTES",
262
- DEFAULT_APP_LOG_MAX_BYTES,
263
- 1,
264
- 1024 * 1024 * 1024
265
- ),
266
- maxFiles: readBoundedInteger(
267
- "AGENT_INSPECTOR_APP_LOG_MAX_FILES",
268
- DEFAULT_APP_LOG_MAX_FILES,
269
- 1,
270
- 100
271
- ),
272
- retentionMs: retentionDays * DAY_MS
273
- };
274
- }
275
- function getRotatedGeneration(entry, baseName) {
276
- const prefix = `${baseName}.`;
277
- if (!entry.startsWith(prefix)) return null;
278
- const suffix = entry.slice(prefix.length);
279
- if (!/^\d+$/.test(suffix)) return null;
280
- const generation = Number(suffix);
281
- if (!Number.isSafeInteger(generation) || generation < 1) return null;
282
- return generation;
283
- }
284
- async function listApplicationLogFiles(logPath) {
285
- const directory = path.dirname(logPath);
286
- const baseName = path.basename(logPath);
287
- const entries = await readdir(directory);
288
- const files = [];
289
- for (const entry of entries) {
290
- const generation = entry === baseName ? 0 : getRotatedGeneration(entry, baseName);
291
- if (generation === null) continue;
292
- const filePath = path.join(directory, entry);
293
- try {
294
- const fileStat = await stat(filePath);
295
- if (!fileStat.isFile()) continue;
296
- files.push({ generation, modifiedAt: fileStat.mtimeMs, path: filePath });
297
- } catch {
298
- }
299
- }
300
- return files;
301
- }
302
- async function removeApplicationLog(filePath) {
303
- try {
304
- await stat(filePath);
305
- } catch {
306
- return true;
307
- }
308
- try {
309
- await unlink(filePath);
310
- return true;
311
- } catch {
312
- return false;
313
- }
314
- }
315
- async function maintainApplicationLogs(logPath, policy) {
316
- const directory = path.dirname(logPath);
317
- if (!ensurePrivateDirectorySync(directory)) return false;
318
- let files;
319
- try {
320
- files = await listApplicationLogFiles(logPath);
321
- } catch {
322
- return false;
323
- }
324
- for (const file2 of files) {
325
- if (!securePrivateFileSync(file2.path)) return false;
326
- }
327
- const cutoff = Date.now() - policy.retentionMs;
328
- const retained = files.filter((file2) => file2.modifiedAt >= cutoff);
329
- let maintained = true;
330
- for (const file2 of files) {
331
- if (file2.modifiedAt < cutoff && !await removeApplicationLog(file2.path)) maintained = false;
332
- }
333
- const rotated = retained.filter((file2) => file2.generation > 0).sort((left, right) => right.modifiedAt - left.modifiedAt);
334
- const retainedRotatedCount = Math.max(0, policy.maxFiles - 1);
335
- for (const file2 of rotated.slice(retainedRotatedCount)) {
336
- if (!await removeApplicationLog(file2.path)) maintained = false;
337
- }
338
- return maintained;
339
- }
340
- async function moveApplicationLog(source, destination) {
341
- try {
342
- await stat(source);
343
- } catch {
344
- return true;
345
- }
346
- try {
347
- await rename(source, destination);
348
- if (!securePrivateFileSync(destination)) {
349
- writeStderrFallback("[logger] Failed to secure rotated application log:", destination);
350
- return false;
351
- }
352
- return true;
353
- } catch (error51) {
354
- writeStderrFallback("[logger] Failed to rotate application log:", error51);
355
- return false;
356
- }
357
- }
358
- async function rotateApplicationLog(logPath, maxFiles) {
359
- if (maxFiles === 1) {
360
- return await removeApplicationLog(logPath);
361
- }
362
- if (!await removeApplicationLog(`${logPath}.${String(maxFiles - 1)}`)) return false;
363
- for (let generation = maxFiles - 2; generation >= 1; generation -= 1) {
364
- if (!await moveApplicationLog(
365
- `${logPath}.${String(generation)}`,
366
- `${logPath}.${String(generation + 1)}`
367
- )) {
368
- return false;
369
- }
370
- }
371
- return await moveApplicationLog(logPath, `${logPath}.1`);
372
- }
373
- async function rotateApplicationLogIfNeeded(logPath, incomingBytes, policy) {
374
- try {
375
- const fileStat = await stat(logPath);
376
- if (fileStat.size > 0 && fileStat.size + incomingBytes > policy.maxBytes) {
377
- return await rotateApplicationLog(logPath, policy.maxFiles);
378
- }
379
- return true;
380
- } catch {
381
- return true;
382
- }
383
- }
384
- async function initLogger() {
385
- const dir = resolveLogDir();
386
- const policy = getApplicationLogPolicy();
387
- const cutoff = Date.now() - policy.retentionMs;
388
- try {
389
- if (!ensurePrivateDirectorySync(dir)) {
390
- writeStderrFallback("[logger] Failed to secure log directory:", dir);
391
- } else if (!securePrivateTreeSync(dir)) {
392
- writeStderrFallback("[logger] Failed to secure existing log files:", dir);
393
- } else {
394
- const entries = await readdir(dir);
395
- for (const entry of entries) {
396
- if (!entry.endsWith(".jsonl")) continue;
397
- const fullPath = path.join(dir, entry);
398
- try {
399
- const s = await stat(fullPath);
400
- if (s.mtimeMs < cutoff) {
401
- await unlink(fullPath);
402
- }
403
- } catch {
404
- }
405
- }
406
- }
407
- } catch (err) {
408
- writeStderrFallback("[logger] Failed to initialize log directory:", err);
409
- }
410
- const applicationLogPath = getInspectorLogPath();
411
- if (!await maintainApplicationLogs(applicationLogPath, policy)) {
412
- writeStderrFallback(
413
- "[logger] Failed to initialize application log lifecycle:",
414
- applicationLogPath
415
- );
416
- }
417
- }
418
- var loggerInitialization = null;
419
- var applicationLogWriteQueue = Promise.resolve();
420
- function ensureLoggerInitialized() {
421
- if (loggerInitialization === null) loggerInitialization = initLogger();
422
- return loggerInitialization;
423
- }
424
- async function appendApplicationLogLine(logPath, line, policy) {
425
- const logDirPath = path.dirname(logPath);
426
- if (!ensurePrivateDirectorySync(logDirPath)) {
427
- return { ok: false, reason: "application log directory is not private" };
428
- }
429
- try {
430
- if (!await rotateApplicationLogIfNeeded(logPath, Buffer2.byteLength(line, "utf-8"), policy)) {
431
- return { ok: false, reason: "application log rotation failed" };
432
- }
433
- await appendFile(logPath, line, { encoding: "utf-8", mode: PRIVATE_FILE_MODE });
434
- if (!securePrivateFileSync(logPath)) {
435
- return { ok: false, reason: "application log permissions could not be secured" };
436
- }
437
- return { ok: true };
438
- } catch (error51) {
439
- return { ok: false, reason: error51 };
440
- }
441
- }
442
- async function writeAppLog(message) {
443
- const logPath = getInspectorLogPath();
444
- const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
445
- `;
446
- const initialization = ensureLoggerInitialized();
447
- const write = async () => {
448
- await initialization;
449
- const result = await appendApplicationLogLine(logPath, line, getApplicationLogPolicy());
450
- if (!result.ok) writeStderrFallback(`[logger] Failed to write to ${logPath}:`, result.reason);
451
- };
452
- applicationLogWriteQueue = applicationLogWriteQueue.then(write, write);
453
- await applicationLogWriteQueue;
454
- }
455
- var logger = {
456
- debug(message, ...args) {
457
- const msg = args.length > 0 ? `${message} ${args.map(String).join(" ")}` : message;
458
- void writeAppLog(`[DEBUG] ${msg}`);
459
- },
460
- info(message, ...args) {
461
- const msg = args.length > 0 ? `${message} ${args.map(String).join(" ")}` : message;
462
- void writeAppLog(`[INFO] ${msg}`);
463
- },
464
- warn(message, ...args) {
465
- const msg = args.length > 0 ? `${message} ${args.map(String).join(" ")}` : message;
466
- void writeAppLog(`[WARN] ${msg}`);
467
- },
468
- error(message, ...args) {
469
- const msg = args.length > 0 ? `${message} ${args.map(String).join(" ")}` : message;
470
- void writeAppLog(`[ERROR] ${msg}`);
471
- }
472
- };
473
- var writeBuffer = [];
474
- var writeQueue = Promise.resolve();
475
- var logWriteLock = Promise.resolve();
476
- function drainBuffer() {
477
- const toWrite = writeBuffer.join("");
478
- writeBuffer = [];
479
- return toWrite;
480
- }
481
- process.on("exit", () => {
482
- if (writeBuffer.length > 0) {
483
- const toWrite = drainBuffer();
484
- try {
485
- const filePath = getLogFilePath();
486
- if (!ensurePrivateDirectorySync(path.dirname(filePath))) return;
487
- appendFileSync(filePath, toWrite, { encoding: "utf-8", mode: PRIVATE_FILE_MODE });
488
- void securePrivateFileSync(filePath);
489
- } catch {
490
- }
491
- }
492
- });
386
+ // src/proxy/jsonlRecovery.ts
387
+ import { createHash, randomUUID } from "node:crypto";
388
+ import { Buffer as Buffer2 } from "node:buffer";
389
+ import { constants as constants2, existsSync as existsSync2, lstatSync as lstatSync2 } from "node:fs";
390
+ import { link, lstat, open, readFile, readdir, stat, unlink } from "node:fs/promises";
391
+ import { basename, join as join3, resolve as resolve2 } from "node:path";
493
392
 
494
393
  // node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
495
394
  var external_exports = {};
@@ -674,7 +573,7 @@ __export(external_exports, {
674
573
  object: () => object,
675
574
  optional: () => optional,
676
575
  overwrite: () => _overwrite,
677
- parse: () => parse2,
576
+ parse: () => parse3,
678
577
  parseAsync: () => parseAsync2,
679
578
  partialRecord: () => partialRecord,
680
579
  pipe: () => pipe,
@@ -994,7 +893,7 @@ __export(core_exports2, {
994
893
  isValidJWT: () => isValidJWT,
995
894
  locales: () => locales_exports,
996
895
  meta: () => meta,
997
- parse: () => parse,
896
+ parse: () => parse2,
998
897
  parseAsync: () => parseAsync,
999
898
  prettifyError: () => prettifyError,
1000
899
  process: () => process2,
@@ -1939,7 +1838,7 @@ var _parse = (_Err) => (schema, value, _ctx, _params) => {
1939
1838
  }
1940
1839
  return result.value;
1941
1840
  };
1942
- var parse = /* @__PURE__ */ _parse($ZodRealError);
1841
+ var parse2 = /* @__PURE__ */ _parse($ZodRealError);
1943
1842
  var _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
1944
1843
  const ctx = _ctx ? { ..._ctx, async: true } : { async: true };
1945
1844
  let result = schema._zod.run({ value, issues: [] }, ctx);
@@ -4731,10 +4630,10 @@ var $ZodFunction = /* @__PURE__ */ $constructor("$ZodFunction", (inst, def) => {
4731
4630
  throw new Error("implement() must be called with a function");
4732
4631
  }
4733
4632
  return function(...args) {
4734
- const parsedArgs = inst._def.input ? parse(inst._def.input, args) : args;
4633
+ const parsedArgs = inst._def.input ? parse2(inst._def.input, args) : args;
4735
4634
  const result = Reflect.apply(func, this, parsedArgs);
4736
4635
  if (inst._def.output) {
4737
- return parse(inst._def.output, result);
4636
+ return parse2(inst._def.output, result);
4738
4637
  }
4739
4638
  return result;
4740
4639
  };
@@ -13168,7 +13067,7 @@ var ZodRealError = /* @__PURE__ */ $constructor("ZodError", initializer2, {
13168
13067
  });
13169
13068
 
13170
13069
  // node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/parse.js
13171
- var parse2 = /* @__PURE__ */ _parse(ZodRealError);
13070
+ var parse3 = /* @__PURE__ */ _parse(ZodRealError);
13172
13071
  var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
13173
13072
  var safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
13174
13073
  var safeParseAsync2 = /* @__PURE__ */ _safeParseAsync(ZodRealError);
@@ -13231,7 +13130,7 @@ var ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
13231
13130
  inst.def = def;
13232
13131
  inst.type = def.type;
13233
13132
  Object.defineProperty(inst, "_def", { value: def });
13234
- inst.parse = (data, params) => parse2(inst, data, params, { callee: inst.parse });
13133
+ inst.parse = (data, params) => parse3(inst, data, params, { callee: inst.parse });
13235
13134
  inst.safeParse = (data, params) => safeParse2(inst, data, params);
13236
13135
  inst.parseAsync = async (data, params) => parseAsync2(inst, data, params, { callee: inst.parseAsync });
13237
13136
  inst.safeParseAsync = async (data, params) => safeParseAsync2(inst, data, params);
@@ -15024,6 +14923,15 @@ function trustAsJsonValue(value) {
15024
14923
  }
15025
14924
 
15026
14925
  // src/contracts/log.ts
14926
+ var LogIdSchema = external_exports.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
14927
+ var CaptureIncompleteReasonSchema = external_exports.enum([
14928
+ "capacity-exceeded",
14929
+ "pipeline-closed",
14930
+ "write-failed",
14931
+ "finalize-failed",
14932
+ "upstream-stream-error",
14933
+ "shutdown"
14934
+ ]);
15027
14935
  var StreamingChunkSchema = external_exports.object({
15028
14936
  index: external_exports.number(),
15029
14937
  timestamp: external_exports.number(),
@@ -15036,7 +14944,7 @@ var StreamingChunksArraySchema = external_exports.object({
15036
14944
  });
15037
14945
  var LogBodyPartSchema = external_exports.enum(["request", "response"]);
15038
14946
  var LogBodyChunkSchema = external_exports.object({
15039
- logId: external_exports.number().int().positive(),
14947
+ logId: LogIdSchema,
15040
14948
  part: LogBodyPartSchema,
15041
14949
  text: external_exports.string(),
15042
14950
  offset: external_exports.number().int().nonnegative(),
@@ -15048,7 +14956,7 @@ var LogBodyChunkSchema = external_exports.object({
15048
14956
  contentMode: external_exports.enum(["empty", "partial", "full"])
15049
14957
  });
15050
14958
  var CapturedLogSchema = external_exports.object({
15051
- id: external_exports.number(),
14959
+ id: LogIdSchema,
15052
14960
  timestamp: external_exports.string(),
15053
14961
  method: external_exports.string(),
15054
14962
  path: external_exports.string(),
@@ -15073,7 +14981,7 @@ var CapturedLogSchema = external_exports.object({
15073
14981
  headers: external_exports.record(external_exports.string(), external_exports.string()).optional(),
15074
14982
  apiFormat: external_exports.enum(["anthropic", "openai", "unknown"]).default("unknown"),
15075
14983
  isTest: external_exports.boolean().optional().default(false),
15076
- replayOfLogId: external_exports.number().nullable().optional(),
14984
+ replayOfLogId: LogIdSchema.nullable().optional(),
15077
14985
  providerName: external_exports.string().nullable().optional(),
15078
14986
  clientPort: external_exports.number().nullable().optional(),
15079
14987
  clientPid: external_exports.number().nullable().optional(),
@@ -15084,6 +14992,10 @@ var CapturedLogSchema = external_exports.object({
15084
14992
  rawRequestBodyBytes: external_exports.number().int().nonnegative().nullable().optional(),
15085
14993
  responseTextBytes: external_exports.number().int().nonnegative().nullable().optional(),
15086
14994
  bodyContentMode: external_exports.enum(["full", "compact", "truncated"]).optional(),
14995
+ captureIncomplete: external_exports.boolean().optional(),
14996
+ droppedChunks: external_exports.number().int().nonnegative().optional(),
14997
+ droppedBytes: external_exports.number().int().nonnegative().optional(),
14998
+ captureIncompleteReason: CaptureIncompleteReasonSchema.nullable().optional(),
15087
14999
  warnings: external_exports.array(external_exports.string()).optional(),
15088
15000
  /** Error message from streaming response (e.g., SSE error event) */
15089
15001
  error: external_exports.string().nullable().optional()
@@ -15456,32 +15368,681 @@ var OpenAIResponsesSSEventSchema = external_exports.object({
15456
15368
  }).passthrough();
15457
15369
  function parseOpenAIResponse(rawBody) {
15458
15370
  try {
15459
- const json2 = JSON.parse(rawBody);
15460
- const result = OpenAIResponseSchema.safeParse(json2);
15461
- if (result.success) return result.data;
15462
- return null;
15371
+ const json2 = JSON.parse(rawBody);
15372
+ const result = OpenAIResponseSchema.safeParse(json2);
15373
+ if (result.success) return result.data;
15374
+ return null;
15375
+ } catch {
15376
+ return null;
15377
+ }
15378
+ }
15379
+ function parseOpenAIResponsesResponse(rawBody) {
15380
+ try {
15381
+ const json2 = JSON.parse(rawBody);
15382
+ const result = OpenAIResponsesResponseSchema.safeParse(json2);
15383
+ if (result.success) return result.data;
15384
+ return null;
15385
+ } catch {
15386
+ return null;
15387
+ }
15388
+ }
15389
+
15390
+ // src/proxy/schemas.ts
15391
+ var RequestModelSchema = external_exports.object({
15392
+ model: external_exports.string()
15393
+ });
15394
+ var LooseRequestSchema = external_exports.object({
15395
+ model: external_exports.string().optional(),
15396
+ metadata: external_exports.object({ user_id: external_exports.string().optional() }).passthrough().optional()
15397
+ });
15398
+
15399
+ // src/proxy/jsonlRecovery.ts
15400
+ var READ_CHUNK_BYTES = 64 * 1024;
15401
+ var QUARANTINE_DIRECTORY = "quarantine";
15402
+ var activeContext = null;
15403
+ function emptyHealth() {
15404
+ return {
15405
+ level: "ok",
15406
+ diagnostic: null,
15407
+ repairedFiles: 0,
15408
+ delimiterRepairs: 0,
15409
+ quarantinedTails: 0
15410
+ };
15411
+ }
15412
+ function contextFor(logDir) {
15413
+ const root = resolve2(logDir);
15414
+ if (activeContext === null || activeContext.root !== root) {
15415
+ activeContext = {
15416
+ root,
15417
+ health: emptyHealth(),
15418
+ startup: null,
15419
+ startupComplete: false,
15420
+ safeFiles: /* @__PURE__ */ new Map()
15421
+ };
15422
+ }
15423
+ return activeContext;
15424
+ }
15425
+ function copyHealth(health) {
15426
+ return { ...health };
15427
+ }
15428
+ function hashBytes(value) {
15429
+ return createHash("sha256").update(value).digest("hex");
15430
+ }
15431
+ function signatureFromStats(stats) {
15432
+ return {
15433
+ size: stats.size,
15434
+ modifiedAt: stats.mtimeMs,
15435
+ changedAt: stats.ctimeMs,
15436
+ device: stats.dev,
15437
+ inode: stats.ino
15438
+ };
15439
+ }
15440
+ function signaturesMatch(left, right) {
15441
+ return left.size === right.size && left.modifiedAt === right.modifiedAt && left.changedAt === right.changedAt && left.device === right.device && left.inode === right.inode;
15442
+ }
15443
+ function validateRecord(bytes) {
15444
+ const withoutCarriageReturn = bytes.length > 0 && bytes[bytes.length - 1] === 13 ? bytes.subarray(0, -1) : bytes;
15445
+ const text = withoutCarriageReturn.toString("utf-8");
15446
+ if (text.trim() === "") return { valid: true };
15447
+ let parsed;
15448
+ try {
15449
+ parsed = JSON.parse(text);
15450
+ } catch {
15451
+ return { valid: false, reason: "invalid-json" };
15452
+ }
15453
+ return CapturedLogSchema.safeParse(parsed).success ? { valid: true } : { valid: false, reason: "invalid-log-schema" };
15454
+ }
15455
+ async function scanFile(handle, size) {
15456
+ const readBuffer = Buffer2.alloc(READ_CHUNK_BYTES);
15457
+ let position = 0;
15458
+ let pending = Buffer2.alloc(0);
15459
+ let pendingOffset = 0;
15460
+ let line = 1;
15461
+ while (position < size) {
15462
+ const length = Math.min(READ_CHUNK_BYTES, size - position);
15463
+ let bytesRead;
15464
+ try {
15465
+ const result = await handle.read(readBuffer, 0, length, position);
15466
+ bytesRead = result.bytesRead;
15467
+ } catch (error51) {
15468
+ return { status: "failed", reason: `read failed: ${String(error51)}` };
15469
+ }
15470
+ if (bytesRead === 0) {
15471
+ return { status: "failed", reason: "captured-log file changed while being scanned" };
15472
+ }
15473
+ const chunk = readBuffer.subarray(0, bytesRead);
15474
+ const combined = pending.length === 0 ? Buffer2.from(chunk) : Buffer2.concat([pending, chunk]);
15475
+ let consumed = 0;
15476
+ let newline = combined.indexOf(10, consumed);
15477
+ while (newline !== -1) {
15478
+ const record2 = combined.subarray(consumed, newline);
15479
+ const validation = validateRecord(record2);
15480
+ if (!validation.valid) {
15481
+ return {
15482
+ status: "interior-corruption",
15483
+ line,
15484
+ byteOffset: pendingOffset + consumed,
15485
+ recordHash: hashBytes(record2),
15486
+ reason: validation.reason
15487
+ };
15488
+ }
15489
+ consumed = newline + 1;
15490
+ line += 1;
15491
+ newline = combined.indexOf(10, consumed);
15492
+ }
15493
+ pending = Buffer2.from(combined.subarray(consumed));
15494
+ pendingOffset += consumed;
15495
+ position += bytesRead;
15496
+ }
15497
+ return { status: "complete", pending, pendingOffset, nextLine: line };
15498
+ }
15499
+ async function syncDirectory(directory) {
15500
+ let handle = null;
15501
+ try {
15502
+ handle = await open(directory, "r");
15503
+ await handle.sync();
15504
+ } catch {
15505
+ } finally {
15506
+ await handle?.close().catch(() => void 0);
15507
+ }
15508
+ }
15509
+ async function removeTemporaryFile(filePath) {
15510
+ await unlink(filePath).catch(() => void 0);
15511
+ }
15512
+ function readOwnProperty(value, name) {
15513
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
15514
+ return Object.getOwnPropertyDescriptor(value, name)?.value;
15515
+ }
15516
+ async function inspectExistingQuarantine(filePath, expected) {
15517
+ if (!existsSync2(filePath)) return "missing";
15518
+ try {
15519
+ const parsed = JSON.parse(await readFile(filePath, "utf-8"));
15520
+ return readOwnProperty(parsed, "schemaVersion") === expected.schemaVersion && readOwnProperty(parsed, "reason") === expected.reason && readOwnProperty(parsed, "sourceFile") === expected.sourceFile && readOwnProperty(parsed, "sourcePathHash") === expected.sourcePathHash && readOwnProperty(parsed, "tailOffset") === expected.tailOffset && readOwnProperty(parsed, "tailBytes") === expected.tailBytes && readOwnProperty(parsed, "tailSha256") === expected.tailSha256 && readOwnProperty(parsed, "tailBase64") === expected.tailBase64 ? "matching" : "conflicting";
15521
+ } catch {
15522
+ return "conflicting";
15523
+ }
15524
+ }
15525
+ async function quarantineTail(context, sourceFile, tail, tailOffset) {
15526
+ const quarantineDirectory = join3(context.root, QUARANTINE_DIRECTORY);
15527
+ if (!ensurePrivateDirectorySync(quarantineDirectory)) return null;
15528
+ const tailSha256 = hashBytes(tail);
15529
+ const sourceFileName = basename(sourceFile);
15530
+ const destination = join3(quarantineDirectory, `${sourceFileName}.tail-${tailSha256}.json`);
15531
+ const temporary = join3(
15532
+ quarantineDirectory,
15533
+ `.${sourceFileName}.${String(process.pid)}.${randomUUID()}.tmp`
15534
+ );
15535
+ const record2 = {
15536
+ schemaVersion: 1,
15537
+ reason: "invalid-final-jsonl-record",
15538
+ sourceFile: sourceFileName,
15539
+ sourcePathHash: hashBytes(Buffer2.from(resolve2(sourceFile), "utf-8")),
15540
+ recoveredAt: (/* @__PURE__ */ new Date()).toISOString(),
15541
+ tailOffset,
15542
+ tailBytes: tail.length,
15543
+ tailSha256,
15544
+ tailBase64: tail.toString("base64")
15545
+ };
15546
+ const existing = await inspectExistingQuarantine(destination, record2);
15547
+ if (existing === "matching") {
15548
+ return securePrivateFileSync(destination) ? destination : null;
15549
+ }
15550
+ if (existing === "conflicting") return null;
15551
+ let handle = null;
15552
+ try {
15553
+ handle = await open(temporary, "wx", PRIVATE_FILE_MODE);
15554
+ await handle.writeFile(`${JSON.stringify(record2)}
15555
+ `, "utf-8");
15556
+ await handle.sync();
15557
+ await handle.close();
15558
+ handle = null;
15559
+ if (!securePrivateFileSync(temporary)) {
15560
+ await removeTemporaryFile(temporary);
15561
+ return null;
15562
+ }
15563
+ await link(temporary, destination);
15564
+ await unlink(temporary);
15565
+ if (!securePrivateFileSync(destination)) return null;
15566
+ await syncDirectory(quarantineDirectory);
15567
+ return destination;
15568
+ } catch {
15569
+ await handle?.close().catch(() => void 0);
15570
+ await removeTemporaryFile(temporary);
15571
+ const racedExisting = await inspectExistingQuarantine(destination, record2);
15572
+ return racedExisting === "matching" && securePrivateFileSync(destination) ? destination : null;
15573
+ }
15574
+ }
15575
+ async function recoverFile(context, filePath) {
15576
+ if (!existsSync2(filePath)) {
15577
+ context.safeFiles.delete(filePath);
15578
+ return {
15579
+ status: "clean",
15580
+ signature: { size: 0, modifiedAt: 0, changedAt: 0, device: 0, inode: 0 }
15581
+ };
15582
+ }
15583
+ let fileStats;
15584
+ try {
15585
+ fileStats = await lstat(filePath);
15586
+ } catch (error51) {
15587
+ return { status: "failed", reason: `stat failed: ${String(error51)}` };
15588
+ }
15589
+ if (fileStats.isSymbolicLink() || !fileStats.isFile()) {
15590
+ return { status: "failed", reason: "captured-log path is not a regular private file" };
15591
+ }
15592
+ const initialSignature = signatureFromStats(fileStats);
15593
+ const safeSignature = context.safeFiles.get(filePath);
15594
+ if (safeSignature !== void 0 && signaturesMatch(safeSignature, initialSignature)) {
15595
+ return { status: "clean", signature: initialSignature };
15596
+ }
15597
+ let handle = null;
15598
+ try {
15599
+ handle = await open(filePath, constants2.O_RDWR | constants2.O_NOFOLLOW);
15600
+ const openedStats = await handle.stat();
15601
+ if (!openedStats.isFile()) {
15602
+ return { status: "failed", reason: "captured-log handle is not a regular file" };
15603
+ }
15604
+ const openedSignature = signatureFromStats(openedStats);
15605
+ if (!signaturesMatch(initialSignature, openedSignature)) {
15606
+ return {
15607
+ status: "failed",
15608
+ reason: "captured-log path changed between metadata validation and open"
15609
+ };
15610
+ }
15611
+ const scan = await scanFile(handle, openedStats.size);
15612
+ const scannedSignature = signatureFromStats(await handle.stat());
15613
+ if (!signaturesMatch(openedSignature, scannedSignature)) {
15614
+ return {
15615
+ status: "failed",
15616
+ reason: "captured-log file changed while recovery was scanning it"
15617
+ };
15618
+ }
15619
+ switch (scan.status) {
15620
+ case "failed":
15621
+ return scan;
15622
+ case "interior-corruption":
15623
+ return scan;
15624
+ case "complete": {
15625
+ if (scan.pending.length === 0) {
15626
+ return { status: "clean", signature: signatureFromStats(await handle.stat()) };
15627
+ }
15628
+ const validation = validateRecord(scan.pending);
15629
+ if (validation.valid) {
15630
+ const write = await handle.write(Buffer2.from("\n", "utf-8"), 0, 1, openedStats.size);
15631
+ if (write.bytesWritten !== 1) {
15632
+ return { status: "failed", reason: "captured-log delimiter append was incomplete" };
15633
+ }
15634
+ await handle.sync();
15635
+ return {
15636
+ status: "delimiter-appended",
15637
+ signature: signatureFromStats(await handle.stat())
15638
+ };
15639
+ }
15640
+ const quarantinePath = await quarantineTail(
15641
+ context,
15642
+ filePath,
15643
+ scan.pending,
15644
+ scan.pendingOffset
15645
+ );
15646
+ if (quarantinePath === null) {
15647
+ return { status: "failed", reason: "invalid tail could not be privately quarantined" };
15648
+ }
15649
+ const beforeTruncate = signatureFromStats(await handle.stat());
15650
+ if (!signaturesMatch(openedSignature, beforeTruncate)) {
15651
+ return {
15652
+ status: "failed",
15653
+ reason: "captured-log file changed before invalid-tail truncation"
15654
+ };
15655
+ }
15656
+ await handle.truncate(scan.pendingOffset);
15657
+ await handle.sync();
15658
+ return {
15659
+ status: "tail-quarantined",
15660
+ signature: signatureFromStats(await handle.stat())
15661
+ };
15662
+ }
15663
+ }
15664
+ return { status: "failed", reason: "unsupported captured-log scan state" };
15665
+ } catch (error51) {
15666
+ return { status: "failed", reason: String(error51) };
15667
+ } finally {
15668
+ await handle?.close().catch(() => void 0);
15669
+ }
15670
+ }
15671
+ function applyFileResult(context, filePath, result) {
15672
+ const file2 = basename(filePath);
15673
+ switch (result.status) {
15674
+ case "clean":
15675
+ context.safeFiles.set(filePath, result.signature);
15676
+ return;
15677
+ case "delimiter-appended":
15678
+ context.safeFiles.set(filePath, result.signature);
15679
+ context.health.delimiterRepairs += 1;
15680
+ context.health.repairedFiles += 1;
15681
+ return;
15682
+ case "tail-quarantined":
15683
+ context.safeFiles.set(filePath, result.signature);
15684
+ context.health.quarantinedTails += 1;
15685
+ context.health.repairedFiles += 1;
15686
+ if (context.health.level !== "unavailable") {
15687
+ context.health.level = "degraded";
15688
+ context.health.diagnostic = `Recovered and quarantined an invalid JSONL tail in ${file2}`;
15689
+ }
15690
+ return;
15691
+ case "interior-corruption":
15692
+ context.safeFiles.delete(filePath);
15693
+ context.health.level = "unavailable";
15694
+ context.health.diagnostic = `JSONL corruption in ${file2} at line ${String(result.line)} (offset ${String(result.byteOffset)}, ${result.reason}, sha256 ${result.recordHash})`;
15695
+ return;
15696
+ case "failed":
15697
+ context.safeFiles.delete(filePath);
15698
+ context.health.level = "unavailable";
15699
+ context.health.diagnostic = `JSONL recovery failed for ${file2}: ${result.reason}`;
15700
+ }
15701
+ }
15702
+ async function runStartupRecovery(context) {
15703
+ if (!ensurePrivateDirectorySync(context.root)) {
15704
+ context.health.level = "unavailable";
15705
+ context.health.diagnostic = "Captured-log directory could not be made private";
15706
+ return copyHealth(context.health);
15707
+ }
15708
+ let entries;
15709
+ try {
15710
+ entries = await readdir(context.root);
15711
+ } catch (error51) {
15712
+ context.health.level = "unavailable";
15713
+ context.health.diagnostic = `Captured-log directory could not be listed: ${String(error51)}`;
15714
+ return copyHealth(context.health);
15715
+ }
15716
+ const files = entries.filter((entry) => entry.endsWith(".jsonl")).sort();
15717
+ for (const file2 of files) {
15718
+ const filePath = join3(context.root, file2);
15719
+ const result = await recoverFile(context, filePath);
15720
+ applyFileResult(context, filePath, result);
15721
+ if (context.health.level === "unavailable") break;
15722
+ }
15723
+ return copyHealth(context.health);
15724
+ }
15725
+ async function recoverCapturedLogStorage(logDir) {
15726
+ const context = contextFor(logDir);
15727
+ if (context.startup === null) {
15728
+ context.startup = runStartupRecovery(context).then((health) => {
15729
+ context.startupComplete = true;
15730
+ return health;
15731
+ });
15732
+ }
15733
+ return await context.startup;
15734
+ }
15735
+ function canAppendCapturedLogFileOnExit(logDir, filePath) {
15736
+ const context = contextFor(logDir);
15737
+ if (!context.startupComplete || context.health.level === "unavailable") return false;
15738
+ const trusted = context.safeFiles.get(filePath);
15739
+ if (trusted === void 0) return false;
15740
+ try {
15741
+ const observed = lstatSync2(filePath);
15742
+ if (observed === void 0 || observed.isSymbolicLink() || !observed.isFile()) return false;
15743
+ return signaturesMatch(trusted, signatureFromStats(observed));
15744
+ } catch {
15745
+ return false;
15746
+ }
15747
+ }
15748
+
15749
+ // src/proxy/logger.ts
15750
+ var DAY_MS = 24 * 60 * 60 * 1e3;
15751
+ var DEFAULT_RETENTION_DAYS = 7;
15752
+ var DEFAULT_APP_LOG_MAX_BYTES = 10 * 1024 * 1024;
15753
+ var DEFAULT_APP_LOG_MAX_FILES = 5;
15754
+ function writeStderrFallback(message, error51) {
15755
+ process.stderr.write(`${message} ${String(error51)}
15756
+ `);
15757
+ }
15758
+ function resolveLogDir() {
15759
+ const logDirEnv = process.env["LOG_DIR"];
15760
+ if (logDirEnv !== void 0 && logDirEnv !== "") {
15761
+ return path.isAbsolute(logDirEnv) ? logDirEnv : path.join(getDataDir(), logDirEnv);
15762
+ }
15763
+ return path.join(getDataDir(), "logs");
15764
+ }
15765
+ function getLogFilePath() {
15766
+ const date5 = /* @__PURE__ */ new Date();
15767
+ const yyyy = date5.getUTCFullYear();
15768
+ const mm = String(date5.getUTCMonth() + 1).padStart(2, "0");
15769
+ const dd = String(date5.getUTCDate()).padStart(2, "0");
15770
+ return path.join(resolveLogDir(), `${yyyy}-${mm}-${dd}.jsonl`);
15771
+ }
15772
+ function getInspectorLogPath() {
15773
+ const logFileEnv = process.env["AGENT_INSPECTOR_LOG_FILE"];
15774
+ if (logFileEnv !== void 0 && logFileEnv !== "") {
15775
+ return logFileEnv;
15776
+ }
15777
+ return path.join(getDataDir(), "logs", "inspector.log");
15778
+ }
15779
+ function readBoundedInteger(name, fallback, minimum, maximum) {
15780
+ const raw = process.env[name];
15781
+ if (raw === void 0 || raw === "") return fallback;
15782
+ const parsed = Number(raw);
15783
+ if (!Number.isInteger(parsed) || parsed < minimum || parsed > maximum) return fallback;
15784
+ return parsed;
15785
+ }
15786
+ function getApplicationLogPolicy() {
15787
+ const retentionDays = readBoundedInteger("LOG_RETENTION_DAYS", DEFAULT_RETENTION_DAYS, 1, 3650);
15788
+ return {
15789
+ maxBytes: readBoundedInteger(
15790
+ "AGENT_INSPECTOR_APP_LOG_MAX_BYTES",
15791
+ DEFAULT_APP_LOG_MAX_BYTES,
15792
+ 1,
15793
+ 1024 * 1024 * 1024
15794
+ ),
15795
+ maxFiles: readBoundedInteger(
15796
+ "AGENT_INSPECTOR_APP_LOG_MAX_FILES",
15797
+ DEFAULT_APP_LOG_MAX_FILES,
15798
+ 1,
15799
+ 100
15800
+ ),
15801
+ retentionMs: retentionDays * DAY_MS
15802
+ };
15803
+ }
15804
+ function getRotatedGeneration(entry, baseName) {
15805
+ const prefix = `${baseName}.`;
15806
+ if (!entry.startsWith(prefix)) return null;
15807
+ const suffix = entry.slice(prefix.length);
15808
+ if (!/^\d+$/.test(suffix)) return null;
15809
+ const generation = Number(suffix);
15810
+ if (!Number.isSafeInteger(generation) || generation < 1) return null;
15811
+ return generation;
15812
+ }
15813
+ async function listApplicationLogFiles(logPath) {
15814
+ const directory = path.dirname(logPath);
15815
+ const baseName = path.basename(logPath);
15816
+ const entries = await readdir2(directory);
15817
+ const files = [];
15818
+ for (const entry of entries) {
15819
+ const generation = entry === baseName ? 0 : getRotatedGeneration(entry, baseName);
15820
+ if (generation === null) continue;
15821
+ const filePath = path.join(directory, entry);
15822
+ try {
15823
+ const fileStat = await stat2(filePath);
15824
+ if (!fileStat.isFile()) continue;
15825
+ files.push({ generation, modifiedAt: fileStat.mtimeMs, path: filePath });
15826
+ } catch {
15827
+ }
15828
+ }
15829
+ return files;
15830
+ }
15831
+ async function removeApplicationLog(filePath) {
15832
+ try {
15833
+ await stat2(filePath);
15463
15834
  } catch {
15464
- return null;
15835
+ return true;
15836
+ }
15837
+ try {
15838
+ await unlink2(filePath);
15839
+ return true;
15840
+ } catch {
15841
+ return false;
15465
15842
  }
15466
15843
  }
15467
- function parseOpenAIResponsesResponse(rawBody) {
15844
+ async function maintainApplicationLogs(logPath, policy) {
15845
+ const directory = path.dirname(logPath);
15846
+ if (!ensurePrivateDirectorySync(directory)) return false;
15847
+ let files;
15468
15848
  try {
15469
- const json2 = JSON.parse(rawBody);
15470
- const result = OpenAIResponsesResponseSchema.safeParse(json2);
15471
- if (result.success) return result.data;
15472
- return null;
15849
+ files = await listApplicationLogFiles(logPath);
15473
15850
  } catch {
15474
- return null;
15851
+ return false;
15852
+ }
15853
+ for (const file2 of files) {
15854
+ if (!securePrivateFileSync(file2.path)) return false;
15855
+ }
15856
+ const cutoff = Date.now() - policy.retentionMs;
15857
+ const retained = files.filter((file2) => file2.modifiedAt >= cutoff);
15858
+ let maintained = true;
15859
+ for (const file2 of files) {
15860
+ if (file2.modifiedAt < cutoff && !await removeApplicationLog(file2.path)) maintained = false;
15861
+ }
15862
+ const rotated = retained.filter((file2) => file2.generation > 0).sort((left, right) => right.modifiedAt - left.modifiedAt);
15863
+ const retainedRotatedCount = Math.max(0, policy.maxFiles - 1);
15864
+ for (const file2 of rotated.slice(retainedRotatedCount)) {
15865
+ if (!await removeApplicationLog(file2.path)) maintained = false;
15475
15866
  }
15867
+ return maintained;
15476
15868
  }
15477
-
15478
- // src/proxy/schemas.ts
15479
- var RequestModelSchema = external_exports.object({
15480
- model: external_exports.string()
15481
- });
15482
- var LooseRequestSchema = external_exports.object({
15483
- model: external_exports.string().optional(),
15484
- metadata: external_exports.object({ user_id: external_exports.string().optional() }).passthrough().optional()
15869
+ async function moveApplicationLog(source, destination) {
15870
+ try {
15871
+ await stat2(source);
15872
+ } catch {
15873
+ return true;
15874
+ }
15875
+ try {
15876
+ await rename(source, destination);
15877
+ if (!securePrivateFileSync(destination)) {
15878
+ writeStderrFallback("[logger] Failed to secure rotated application log:", destination);
15879
+ return false;
15880
+ }
15881
+ return true;
15882
+ } catch (error51) {
15883
+ writeStderrFallback("[logger] Failed to rotate application log:", error51);
15884
+ return false;
15885
+ }
15886
+ }
15887
+ async function rotateApplicationLog(logPath, maxFiles) {
15888
+ if (maxFiles === 1) {
15889
+ return await removeApplicationLog(logPath);
15890
+ }
15891
+ if (!await removeApplicationLog(`${logPath}.${String(maxFiles - 1)}`)) return false;
15892
+ for (let generation = maxFiles - 2; generation >= 1; generation -= 1) {
15893
+ if (!await moveApplicationLog(
15894
+ `${logPath}.${String(generation)}`,
15895
+ `${logPath}.${String(generation + 1)}`
15896
+ )) {
15897
+ return false;
15898
+ }
15899
+ }
15900
+ return await moveApplicationLog(logPath, `${logPath}.1`);
15901
+ }
15902
+ async function rotateApplicationLogIfNeeded(logPath, incomingBytes, policy) {
15903
+ try {
15904
+ const fileStat = await stat2(logPath);
15905
+ if (fileStat.size > 0 && fileStat.size + incomingBytes > policy.maxBytes) {
15906
+ return await rotateApplicationLog(logPath, policy.maxFiles);
15907
+ }
15908
+ return true;
15909
+ } catch {
15910
+ return true;
15911
+ }
15912
+ }
15913
+ async function initLogger() {
15914
+ const dir = resolveLogDir();
15915
+ const policy = getApplicationLogPolicy();
15916
+ const cutoff = Date.now() - policy.retentionMs;
15917
+ try {
15918
+ if (!ensurePrivateDirectorySync(dir)) {
15919
+ writeStderrFallback("[logger] Failed to secure log directory:", dir);
15920
+ } else if (!securePrivateTreeSync(dir)) {
15921
+ writeStderrFallback("[logger] Failed to secure existing log files:", dir);
15922
+ } else {
15923
+ const recovery = await recoverCapturedLogStorage(dir);
15924
+ if (recovery.level === "unavailable") {
15925
+ writeStderrFallback(
15926
+ "[logger] Captured-log recovery blocked readiness:",
15927
+ recovery.diagnostic ?? "unknown recovery failure"
15928
+ );
15929
+ } else {
15930
+ const entries = await readdir2(dir);
15931
+ for (const entry of entries) {
15932
+ if (!entry.endsWith(".jsonl")) continue;
15933
+ const fullPath = path.join(dir, entry);
15934
+ try {
15935
+ const s = await stat2(fullPath);
15936
+ if (s.mtimeMs < cutoff) {
15937
+ await unlink2(fullPath);
15938
+ }
15939
+ } catch {
15940
+ }
15941
+ }
15942
+ }
15943
+ }
15944
+ } catch (err) {
15945
+ writeStderrFallback("[logger] Failed to initialize log directory:", err);
15946
+ }
15947
+ const applicationLogPath = getInspectorLogPath();
15948
+ if (!await maintainApplicationLogs(applicationLogPath, policy)) {
15949
+ writeStderrFallback(
15950
+ "[logger] Failed to initialize application log lifecycle:",
15951
+ applicationLogPath
15952
+ );
15953
+ }
15954
+ }
15955
+ var loggerInitialization = null;
15956
+ var applicationLogWriteQueue = Promise.resolve();
15957
+ function ensureLoggerInitialized() {
15958
+ if (loggerInitialization === null) loggerInitialization = initLogger();
15959
+ return loggerInitialization;
15960
+ }
15961
+ async function appendApplicationLogLine(logPath, line, policy) {
15962
+ const logDirPath = path.dirname(logPath);
15963
+ if (!ensurePrivateDirectorySync(logDirPath)) {
15964
+ return { ok: false, reason: "application log directory is not private" };
15965
+ }
15966
+ try {
15967
+ if (!await rotateApplicationLogIfNeeded(logPath, Buffer3.byteLength(line, "utf-8"), policy)) {
15968
+ return { ok: false, reason: "application log rotation failed" };
15969
+ }
15970
+ await appendFile(logPath, line, { encoding: "utf-8", mode: PRIVATE_FILE_MODE });
15971
+ if (!securePrivateFileSync(logPath)) {
15972
+ return { ok: false, reason: "application log permissions could not be secured" };
15973
+ }
15974
+ return { ok: true };
15975
+ } catch (error51) {
15976
+ return { ok: false, reason: error51 };
15977
+ }
15978
+ }
15979
+ async function writeAppLog(message) {
15980
+ const logPath = getInspectorLogPath();
15981
+ const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
15982
+ `;
15983
+ const initialization = ensureLoggerInitialized();
15984
+ const write = async () => {
15985
+ await initialization;
15986
+ const result = await appendApplicationLogLine(logPath, line, getApplicationLogPolicy());
15987
+ if (!result.ok) writeStderrFallback(`[logger] Failed to write to ${logPath}:`, result.reason);
15988
+ };
15989
+ applicationLogWriteQueue = applicationLogWriteQueue.then(write, write);
15990
+ await applicationLogWriteQueue;
15991
+ }
15992
+ var logger = {
15993
+ debug(message, ...args) {
15994
+ const msg = args.length > 0 ? `${message} ${args.map(String).join(" ")}` : message;
15995
+ void writeAppLog(`[DEBUG] ${msg}`);
15996
+ },
15997
+ info(message, ...args) {
15998
+ const msg = args.length > 0 ? `${message} ${args.map(String).join(" ")}` : message;
15999
+ void writeAppLog(`[INFO] ${msg}`);
16000
+ },
16001
+ warn(message, ...args) {
16002
+ const msg = args.length > 0 ? `${message} ${args.map(String).join(" ")}` : message;
16003
+ void writeAppLog(`[WARN] ${msg}`);
16004
+ },
16005
+ error(message, ...args) {
16006
+ const msg = args.length > 0 ? `${message} ${args.map(String).join(" ")}` : message;
16007
+ void writeAppLog(`[ERROR] ${msg}`);
16008
+ }
16009
+ };
16010
+ var writeBuffer = [];
16011
+ var writeQueue = Promise.resolve();
16012
+ var logWriteLock = Promise.resolve();
16013
+ function drainBuffer() {
16014
+ const toWrite = writeBuffer.join("");
16015
+ writeBuffer = [];
16016
+ return toWrite;
16017
+ }
16018
+ process.on("exit", () => {
16019
+ if (writeBuffer.length > 0) {
16020
+ const toWrite = drainBuffer();
16021
+ try {
16022
+ const filePath = getLogFilePath();
16023
+ if (!ensurePrivateDirectorySync(path.dirname(filePath))) return;
16024
+ if (!canAppendCapturedLogFileOnExit(resolveLogDir(), filePath)) return;
16025
+ const descriptor = openSync2(
16026
+ filePath,
16027
+ constants3.O_WRONLY | constants3.O_APPEND | constants3.O_NOFOLLOW,
16028
+ PRIVATE_FILE_MODE
16029
+ );
16030
+ try {
16031
+ const payload = Buffer3.from(toWrite, "utf-8");
16032
+ let written = 0;
16033
+ while (written < payload.length) {
16034
+ const writeCount = writeSync(descriptor, payload, written, payload.length - written);
16035
+ if (writeCount === 0) return;
16036
+ written += writeCount;
16037
+ }
16038
+ fsyncSync(descriptor);
16039
+ } finally {
16040
+ closeSync2(descriptor);
16041
+ }
16042
+ void securePrivateFileSync(filePath);
16043
+ } catch {
16044
+ }
16045
+ }
15485
16046
  });
15486
16047
 
15487
16048
  // src/proxy/chunkStorage.ts
@@ -15498,15 +16059,15 @@ var StreamingChunksDataSchema = external_exports.object({
15498
16059
  function getChunksDir() {
15499
16060
  const chunksDirEnv = process.env["CHUNKS_DIR"];
15500
16061
  if (chunksDirEnv !== void 0 && chunksDirEnv !== "") {
15501
- return isAbsolute2(chunksDirEnv) ? chunksDirEnv : join3(getDataDir(), chunksDirEnv);
16062
+ return isAbsolute2(chunksDirEnv) ? chunksDirEnv : join4(getDataDir(), chunksDirEnv);
15502
16063
  }
15503
- return join3(getDataDir(), "chunks");
16064
+ return join4(getDataDir(), "chunks");
15504
16065
  }
15505
16066
  function getChunkFilePath(logId) {
15506
- return join3(getChunksDir(), `${logId}.json`);
16067
+ return join4(getChunksDir(), `${logId}.json`);
15507
16068
  }
15508
16069
  function getTempFilePath(logId) {
15509
- return join3(getChunksDir(), `.${logId}.tmp`);
16070
+ return join4(getChunksDir(), `.${logId}.tmp`);
15510
16071
  }
15511
16072
  function writeChunks(logId, chunks, truncated) {
15512
16073
  const dir = getChunksDir();
@@ -15532,7 +16093,7 @@ function writeChunks(logId, chunks, truncated) {
15532
16093
  return targetPath;
15533
16094
  }
15534
16095
  try {
15535
- renameSync(tempPath, targetPath);
16096
+ renameSync2(tempPath, targetPath);
15536
16097
  } catch (err) {
15537
16098
  logger.warn("[chunkStorage] Rename failed, falling back to copy+delete:", String(err));
15538
16099
  try {
@@ -15548,14 +16109,14 @@ function writeChunks(logId, chunks, truncated) {
15548
16109
  return targetPath;
15549
16110
  }
15550
16111
 
15551
- // src/proxy/constants.ts
15552
- var PROXY_IDENTITY = process.env["PROXY_IDENTITY"] ?? "inspector9527@Tony";
15553
- var PATH_V1_CHAT_COMPLETIONS = "/v1/chat/completions";
15554
- var PATH_CHAT_COMPLETIONS = "/chat/completions";
15555
- var PATH_V1_RESPONSES = "/v1/responses";
15556
- var PATH_RESPONSES = "/responses";
15557
- var PATH_V1_MESSAGES = "/v1/messages";
15558
- var MAX_REQUEST_BODY_BYTES = 50 * 1024 * 1024;
16112
+ // src/lib/apiFormat.ts
16113
+ var API_FORMAT_PATH_ENTRIES = [
16114
+ ["/v1/messages", "anthropic"],
16115
+ ["/v1/chat/completions", "openai"],
16116
+ ["/chat/completions", "openai"],
16117
+ ["/v1/responses", "openai"],
16118
+ ["/responses", "openai"]
16119
+ ];
15559
16120
 
15560
16121
  // src/proxy/formats/registry.ts
15561
16122
  var FormatRegistryImpl = class {
@@ -15595,11 +16156,9 @@ var formatRegistry = new FormatRegistryImpl();
15595
16156
  function formatForPath(path2) {
15596
16157
  return formatRegistry.getByPath(path2) ?? null;
15597
16158
  }
15598
- formatRegistry.registerPath(PATH_V1_MESSAGES, "anthropic");
15599
- formatRegistry.registerPath(PATH_V1_CHAT_COMPLETIONS, "openai");
15600
- formatRegistry.registerPath(PATH_CHAT_COMPLETIONS, "openai");
15601
- formatRegistry.registerPath(PATH_V1_RESPONSES, "openai");
15602
- formatRegistry.registerPath(PATH_RESPONSES, "openai");
16159
+ for (const [path2, format] of API_FORMAT_PATH_ENTRIES) {
16160
+ formatRegistry.registerPath(path2, format);
16161
+ }
15603
16162
 
15604
16163
  // src/proxy/formats/anthropic/stream.ts
15605
16164
  function parseInputJson(json2) {
@@ -16555,12 +17114,12 @@ registry2.register(alibabaProvider);
16555
17114
  // src/proxy/sessionProcess.ts
16556
17115
  import { existsSync as existsSync4 } from "node:fs";
16557
17116
  import { fileURLToPath } from "node:url";
16558
- import { join as join4 } from "node:path";
17117
+ import { join as join5 } from "node:path";
16559
17118
  var IDLE_TIMEOUT_MS = Number(process.env["SESSION_PROCESS_IDLE_MS"]) || 5 * 60 * 1e3;
16560
17119
  function resolveSessionWorkerPath() {
16561
17120
  const workerDir = process.env["AGENT_INSPECTOR_WORKER_DIR"];
16562
17121
  if (workerDir !== void 0 && workerDir.trim().length > 0) {
16563
- const builtWorkerPath = join4(workerDir, "sessionWorkerEntry.js");
17122
+ const builtWorkerPath = join5(workerDir, "sessionWorkerEntry.js");
16564
17123
  if (existsSync4(builtWorkerPath)) return builtWorkerPath;
16565
17124
  }
16566
17125
  return fileURLToPath(new URL("./sessionWorkerEntry.ts", import.meta.url));
@@ -16570,6 +17129,7 @@ function isSessionProcessAvailable() {
16570
17129
  }
16571
17130
 
16572
17131
  // src/proxy/logIndex.ts
17132
+ var INDEX_READ_CHUNK_BYTES = 64 * 1024;
16573
17133
  var idGenerationChain = Promise.resolve();
16574
17134
 
16575
17135
  // src/lib/publicBasePathContext.ts
@@ -16690,14 +17250,14 @@ function cleanupPathForRawStream(rawStream) {
16690
17250
  }
16691
17251
  function rawStreamByteLength(rawStream) {
16692
17252
  if (typeof rawStream === "string") {
16693
- return Buffer3.byteLength(rawStream, "utf8");
17253
+ return Buffer4.byteLength(rawStream, "utf8");
16694
17254
  }
16695
17255
  switch (rawStream.type) {
16696
17256
  case "memory":
16697
- return Buffer3.byteLength(rawStream.rawStream, "utf8");
17257
+ return Buffer4.byteLength(rawStream.rawStream, "utf8");
16698
17258
  case "file":
16699
17259
  try {
16700
- return statSync2(rawStream.path).size;
17260
+ return statSync(rawStream.path).size;
16701
17261
  } catch {
16702
17262
  return null;
16703
17263
  }
@@ -16856,8 +17416,13 @@ function buildFinalizeLogResult(job) {
16856
17416
  switch (job.type) {
16857
17417
  case "non-streaming":
16858
17418
  return finalizeNonStreaming(job, log);
16859
- case "streaming":
16860
- return finalizeStreaming(job, log);
17419
+ case "streaming": {
17420
+ const result = finalizeStreaming(job, log);
17421
+ if (job.terminalError !== void 0 && job.terminalError !== null) {
17422
+ result.log.error = job.terminalError;
17423
+ }
17424
+ return result;
17425
+ }
16861
17426
  case "stream-abort":
16862
17427
  return finalizeStreamAbort(job, log);
16863
17428
  default: {
@@ -16885,7 +17450,7 @@ var WORKER_COUNT = Math.max(1, Number(process.env["FINALIZER_WORKER_COUNT"]) ||
16885
17450
  function resolveLogFinalizerWorkerUrl() {
16886
17451
  const workerDir = process.env["AGENT_INSPECTOR_WORKER_DIR"];
16887
17452
  if (workerDir !== void 0 && workerDir.trim().length > 0) {
16888
- const builtWorkerPath = join5(workerDir, "logFinalizer.worker.js");
17453
+ const builtWorkerPath = join6(workerDir, "logFinalizer.worker.js");
16889
17454
  if (existsSync5(builtWorkerPath)) return pathToFileURL(builtWorkerPath);
16890
17455
  }
16891
17456
  return new URL("./logFinalizer.worker.ts", import.meta.url);