@tonyclaw/agent-inspector 3.0.45 → 3.0.46

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