@humain/terminal 0.0.4-beta.1 → 0.0.5

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 (675) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +1 -0
  3. package/dist/bun/cli.d.ts.map +1 -1
  4. package/dist/bun/cli.js.map +1 -1
  5. package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
  6. package/dist/bun/restore-sandbox-env.js.map +1 -1
  7. package/dist/cli/args.d.ts +1 -0
  8. package/dist/cli/args.d.ts.map +1 -1
  9. package/dist/cli/args.js +11 -0
  10. package/dist/cli/args.js.map +1 -1
  11. package/dist/cli/auth-check.d.ts.map +1 -1
  12. package/dist/cli/auth-check.js.map +1 -1
  13. package/dist/cli/auth-command.d.ts.map +1 -1
  14. package/dist/cli/auth-command.js.map +1 -1
  15. package/dist/cli/config-selector.d.ts.map +1 -1
  16. package/dist/cli/config-selector.js.map +1 -1
  17. package/dist/cli/credential-print.d.ts.map +1 -1
  18. package/dist/cli/credential-print.js.map +1 -1
  19. package/dist/cli/experimental/auth.d.ts.map +1 -1
  20. package/dist/cli/experimental/auth.js.map +1 -1
  21. package/dist/cli/experimental/cli.d.ts.map +1 -1
  22. package/dist/cli/experimental/command-options.d.ts.map +1 -1
  23. package/dist/cli/experimental/command-options.js.map +1 -1
  24. package/dist/cli/experimental/command.d.ts.map +1 -1
  25. package/dist/cli/experimental/command.js +2 -5
  26. package/dist/cli/experimental/command.js.map +1 -1
  27. package/dist/cli/experimental/commands/client.d.ts.map +1 -1
  28. package/dist/cli/experimental/commands/client.js.map +1 -1
  29. package/dist/cli/experimental/commands/pi.d.ts.map +1 -1
  30. package/dist/cli/experimental/commands/pi.js.map +1 -1
  31. package/dist/cli/experimental/commands/server.d.ts.map +1 -1
  32. package/dist/cli/experimental/commands/server.js.map +1 -1
  33. package/dist/cli/experimental/transport-address.d.ts.map +1 -1
  34. package/dist/cli/experimental/transport-address.js.map +1 -1
  35. package/dist/cli/file-processor.d.ts.map +1 -1
  36. package/dist/cli/file-processor.js.map +1 -1
  37. package/dist/cli/initial-message.d.ts +1 -1
  38. package/dist/cli/initial-message.d.ts.map +1 -1
  39. package/dist/cli/initial-message.js.map +1 -1
  40. package/dist/cli/list-models.d.ts.map +1 -1
  41. package/dist/cli/list-models.js.map +1 -1
  42. package/dist/cli/project-trust.d.ts.map +1 -1
  43. package/dist/cli/project-trust.js.map +1 -1
  44. package/dist/cli/session-picker.d.ts.map +1 -1
  45. package/dist/cli/session-picker.js.map +1 -1
  46. package/dist/cli/startup-ui.d.ts.map +1 -1
  47. package/dist/cli/startup-ui.js.map +1 -1
  48. package/dist/cli.d.ts.map +1 -1
  49. package/dist/cli.js.map +1 -1
  50. package/dist/client/index.d.ts.map +1 -1
  51. package/dist/client/remote-session.d.ts.map +1 -1
  52. package/dist/client/remote-session.js.map +1 -1
  53. package/dist/client/transcript.d.ts.map +1 -1
  54. package/dist/client/transcript.js +1 -1
  55. package/dist/client/transcript.js.map +1 -1
  56. package/dist/config.d.ts.map +1 -1
  57. package/dist/config.js.map +1 -1
  58. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  59. package/dist/core/agent-session-runtime.js +0 -8
  60. package/dist/core/agent-session-runtime.js.map +1 -1
  61. package/dist/core/agent-session-services.d.ts.map +1 -1
  62. package/dist/core/agent-session-services.js.map +1 -1
  63. package/dist/core/agent-session.d.ts +36 -2
  64. package/dist/core/agent-session.d.ts.map +1 -1
  65. package/dist/core/agent-session.js +100 -128
  66. package/dist/core/agent-session.js.map +1 -1
  67. package/dist/core/auth-guidance.d.ts.map +1 -1
  68. package/dist/core/auth-guidance.js.map +1 -1
  69. package/dist/core/auth-storage.d.ts.map +1 -1
  70. package/dist/core/auth-storage.js +3 -8
  71. package/dist/core/auth-storage.js.map +1 -1
  72. package/dist/core/bash-executor.d.ts.map +1 -1
  73. package/dist/core/bash-executor.js.map +1 -1
  74. package/dist/core/cache-stats.d.ts.map +1 -1
  75. package/dist/core/cache-stats.js.map +1 -1
  76. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  77. package/dist/core/compaction/branch-summarization.js.map +1 -1
  78. package/dist/core/compaction/compaction.d.ts.map +1 -1
  79. package/dist/core/compaction/compaction.js.map +1 -1
  80. package/dist/core/compaction/index.d.ts.map +1 -1
  81. package/dist/core/compaction/utils.d.ts.map +1 -1
  82. package/dist/core/compaction/utils.js.map +1 -1
  83. package/dist/core/defaults.d.ts.map +1 -1
  84. package/dist/core/diagnostics.d.ts.map +1 -1
  85. package/dist/core/event-bus.d.ts.map +1 -1
  86. package/dist/core/event-bus.js.map +1 -1
  87. package/dist/core/exec.d.ts.map +1 -1
  88. package/dist/core/exec.js.map +1 -1
  89. package/dist/core/experimental.d.ts +4 -0
  90. package/dist/core/experimental.d.ts.map +1 -1
  91. package/dist/core/experimental.js +4 -0
  92. package/dist/core/experimental.js.map +1 -1
  93. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  94. package/dist/core/export-html/ansi-to-html.js.map +1 -1
  95. package/dist/core/export-html/index.d.ts.map +1 -1
  96. package/dist/core/export-html/index.js.map +1 -1
  97. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  98. package/dist/core/export-html/tool-renderer.js.map +1 -1
  99. package/dist/core/extensions/index.d.ts.map +1 -1
  100. package/dist/core/extensions/loader.d.ts.map +1 -1
  101. package/dist/core/extensions/loader.js.map +1 -1
  102. package/dist/core/extensions/runner.d.ts.map +1 -1
  103. package/dist/core/extensions/runner.js +22 -30
  104. package/dist/core/extensions/runner.js.map +1 -1
  105. package/dist/core/extensions/types.d.ts +4 -0
  106. package/dist/core/extensions/types.d.ts.map +1 -1
  107. package/dist/core/extensions/types.js.map +1 -1
  108. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  109. package/dist/core/extensions/wrapper.js.map +1 -1
  110. package/dist/core/footer-data-provider.d.ts.map +1 -1
  111. package/dist/core/footer-data-provider.js +17 -18
  112. package/dist/core/footer-data-provider.js.map +1 -1
  113. package/dist/core/http-dispatcher.d.ts.map +1 -1
  114. package/dist/core/http-dispatcher.js.map +1 -1
  115. package/dist/core/index.d.ts.map +1 -1
  116. package/dist/core/keybindings.d.ts +24 -0
  117. package/dist/core/keybindings.d.ts.map +1 -1
  118. package/dist/core/keybindings.js +0 -1
  119. package/dist/core/keybindings.js.map +1 -1
  120. package/dist/core/messages.d.ts.map +1 -1
  121. package/dist/core/messages.js.map +1 -1
  122. package/dist/core/model-config.d.ts +5 -0
  123. package/dist/core/model-config.d.ts.map +1 -1
  124. package/dist/core/model-config.js +1 -2
  125. package/dist/core/model-config.js.map +1 -1
  126. package/dist/core/model-registry.d.ts.map +1 -1
  127. package/dist/core/model-registry.js +0 -1
  128. package/dist/core/model-registry.js.map +1 -1
  129. package/dist/core/model-resolver.d.ts.map +1 -1
  130. package/dist/core/model-resolver.js.map +1 -1
  131. package/dist/core/model-runtime.d.ts.map +1 -1
  132. package/dist/core/model-runtime.js +15 -25
  133. package/dist/core/model-runtime.js.map +1 -1
  134. package/dist/core/models-store.d.ts.map +1 -1
  135. package/dist/core/models-store.js +3 -4
  136. package/dist/core/models-store.js.map +1 -1
  137. package/dist/core/output-guard.d.ts.map +1 -1
  138. package/dist/core/output-guard.js.map +1 -1
  139. package/dist/core/package-manager.d.ts.map +1 -1
  140. package/dist/core/package-manager.js +0 -7
  141. package/dist/core/package-manager.js.map +1 -1
  142. package/dist/core/pi-manifest.d.ts.map +1 -1
  143. package/dist/core/pi-manifest.js.map +1 -1
  144. package/dist/core/project-trust.d.ts.map +1 -1
  145. package/dist/core/project-trust.js.map +1 -1
  146. package/dist/core/prompt-templates.d.ts.map +1 -1
  147. package/dist/core/prompt-templates.js.map +1 -1
  148. package/dist/core/provider-attribution.d.ts.map +1 -1
  149. package/dist/core/provider-attribution.js.map +1 -1
  150. package/dist/core/provider-composer.d.ts.map +1 -1
  151. package/dist/core/provider-composer.js.map +1 -1
  152. package/dist/core/radius.d.ts.map +1 -1
  153. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  154. package/dist/core/remote-catalog-provider.js.map +1 -1
  155. package/dist/core/resolve-config-value.d.ts.map +1 -1
  156. package/dist/core/resolve-config-value.js.map +1 -1
  157. package/dist/core/resource-loader.d.ts.map +1 -1
  158. package/dist/core/resource-loader.js +0 -44
  159. package/dist/core/resource-loader.js.map +1 -1
  160. package/dist/core/runtime-credentials.d.ts.map +1 -1
  161. package/dist/core/runtime-credentials.js +1 -2
  162. package/dist/core/runtime-credentials.js.map +1 -1
  163. package/dist/core/sdk.d.ts +5 -3
  164. package/dist/core/sdk.d.ts.map +1 -1
  165. package/dist/core/sdk.js +2 -1
  166. package/dist/core/sdk.js.map +1 -1
  167. package/dist/core/session-cwd.d.ts.map +1 -1
  168. package/dist/core/session-cwd.js +0 -1
  169. package/dist/core/session-cwd.js.map +1 -1
  170. package/dist/core/session-manager.d.ts.map +1 -1
  171. package/dist/core/session-manager.js +9 -13
  172. package/dist/core/session-manager.js.map +1 -1
  173. package/dist/core/settings-manager.d.ts +6 -0
  174. package/dist/core/settings-manager.d.ts.map +1 -1
  175. package/dist/core/settings-manager.js +19 -17
  176. package/dist/core/settings-manager.js.map +1 -1
  177. package/dist/core/skills.d.ts.map +1 -1
  178. package/dist/core/skills.js.map +1 -1
  179. package/dist/core/slash-commands.d.ts.map +1 -1
  180. package/dist/core/source-info.d.ts.map +1 -1
  181. package/dist/core/source-info.js.map +1 -1
  182. package/dist/core/system-prompt.d.ts.map +1 -1
  183. package/dist/core/system-prompt.js +1 -1
  184. package/dist/core/system-prompt.js.map +1 -1
  185. package/dist/core/telemetry.d.ts.map +1 -1
  186. package/dist/core/telemetry.js.map +1 -1
  187. package/dist/core/timings.d.ts.map +1 -1
  188. package/dist/core/timings.js.map +1 -1
  189. package/dist/core/tools/bash.d.ts.map +1 -1
  190. package/dist/core/tools/bash.js +10 -5
  191. package/dist/core/tools/bash.js.map +1 -1
  192. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  193. package/dist/core/tools/edit-diff.js.map +1 -1
  194. package/dist/core/tools/edit.d.ts.map +1 -1
  195. package/dist/core/tools/edit.js +2 -0
  196. package/dist/core/tools/edit.js.map +1 -1
  197. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  198. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  199. package/dist/core/tools/find.d.ts +1 -1
  200. package/dist/core/tools/find.d.ts.map +1 -1
  201. package/dist/core/tools/find.js +1 -1
  202. package/dist/core/tools/find.js.map +1 -1
  203. package/dist/core/tools/grep.d.ts.map +1 -1
  204. package/dist/core/tools/grep.js +1 -1
  205. package/dist/core/tools/grep.js.map +1 -1
  206. package/dist/core/tools/index.d.ts.map +1 -1
  207. package/dist/core/tools/index.js.map +1 -1
  208. package/dist/core/tools/ls.d.ts.map +1 -1
  209. package/dist/core/tools/ls.js.map +1 -1
  210. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  211. package/dist/core/tools/output-accumulator.js +12 -18
  212. package/dist/core/tools/output-accumulator.js.map +1 -1
  213. package/dist/core/tools/path-utils.d.ts.map +1 -1
  214. package/dist/core/tools/path-utils.js.map +1 -1
  215. package/dist/core/tools/read.d.ts.map +1 -1
  216. package/dist/core/tools/read.js +2 -0
  217. package/dist/core/tools/read.js.map +1 -1
  218. package/dist/core/tools/render-utils.d.ts.map +1 -1
  219. package/dist/core/tools/render-utils.js.map +1 -1
  220. package/dist/core/tools/subagent.d.ts +3 -0
  221. package/dist/core/tools/subagent.d.ts.map +1 -1
  222. package/dist/core/tools/subagent.js +30 -9
  223. package/dist/core/tools/subagent.js.map +1 -1
  224. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  225. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  226. package/dist/core/tools/truncate.d.ts.map +1 -1
  227. package/dist/core/tools/truncate.js.map +1 -1
  228. package/dist/core/tools/write.d.ts.map +1 -1
  229. package/dist/core/tools/write.js +2 -1
  230. package/dist/core/tools/write.js.map +1 -1
  231. package/dist/core/trust-manager.d.ts.map +1 -1
  232. package/dist/core/trust-manager.js +0 -1
  233. package/dist/core/trust-manager.js.map +1 -1
  234. package/dist/core/usage-totals.d.ts.map +1 -1
  235. package/dist/core/usage-totals.js.map +1 -1
  236. package/dist/extensions/index.d.ts.map +1 -1
  237. package/dist/extensions/llama/client.d.ts.map +1 -1
  238. package/dist/extensions/llama/client.js +0 -2
  239. package/dist/extensions/llama/client.js.map +1 -1
  240. package/dist/extensions/llama/huggingface.d.ts.map +1 -1
  241. package/dist/extensions/llama/huggingface.js +0 -2
  242. package/dist/extensions/llama/huggingface.js.map +1 -1
  243. package/dist/extensions/llama/index.d.ts.map +1 -1
  244. package/dist/extensions/llama/index.js.map +1 -1
  245. package/dist/extensions/llama/provider.d.ts.map +1 -1
  246. package/dist/extensions/llama/provider.js.map +1 -1
  247. package/dist/extensions/llama/ui.d.ts.map +1 -1
  248. package/dist/extensions/llama/ui.js +12 -28
  249. package/dist/extensions/llama/ui.js.map +1 -1
  250. package/dist/humain/agent-execution-protocol.d.ts.map +1 -1
  251. package/dist/humain/agent-execution-protocol.js.map +1 -1
  252. package/dist/humain/agent-execution-runtime.d.ts.map +1 -1
  253. package/dist/humain/agent-execution-runtime.js.map +1 -1
  254. package/dist/humain/bedrock-provider/vendor/index.bundle.mjs +127 -7
  255. package/dist/humain/brand-logo.d.ts.map +1 -1
  256. package/dist/humain/index.d.ts.map +1 -1
  257. package/dist/humain/index.js.map +1 -1
  258. package/dist/humain/legacy-workflow-tiers.d.ts.map +1 -1
  259. package/dist/humain/legacy-workflow-tiers.js.map +1 -1
  260. package/dist/humain/mcp-adapter/vendor/package.json +3 -3
  261. package/dist/humain/mcp-adapter.d.ts.map +1 -1
  262. package/dist/humain/mcp-adapter.js.map +1 -1
  263. package/dist/humain/pi-agent-execution-host.d.ts.map +1 -1
  264. package/dist/humain/pi-agent-execution-host.js.map +1 -1
  265. package/dist/humain/web-access/host.d.ts.map +1 -1
  266. package/dist/humain/web-access/index.d.ts.map +1 -1
  267. package/dist/humain/web-access/index.js.map +1 -1
  268. package/dist/humain/web-access/vendor/activity.d.ts.map +1 -1
  269. package/dist/humain/web-access/vendor/activity.js +7 -5
  270. package/dist/humain/web-access/vendor/activity.js.map +1 -1
  271. package/dist/humain/web-access/vendor/anysearch.d.ts.map +1 -1
  272. package/dist/humain/web-access/vendor/anysearch.js.map +1 -1
  273. package/dist/humain/web-access/vendor/auth-fetch.d.ts.map +1 -1
  274. package/dist/humain/web-access/vendor/auth-fetch.js.map +1 -1
  275. package/dist/humain/web-access/vendor/bocha.d.ts.map +1 -1
  276. package/dist/humain/web-access/vendor/bocha.js.map +1 -1
  277. package/dist/humain/web-access/vendor/brave.d.ts.map +1 -1
  278. package/dist/humain/web-access/vendor/brave.js.map +1 -1
  279. package/dist/humain/web-access/vendor/brightdata-unlocker.d.ts.map +1 -1
  280. package/dist/humain/web-access/vendor/brightdata-unlocker.js.map +1 -1
  281. package/dist/humain/web-access/vendor/brightdata.d.ts.map +1 -1
  282. package/dist/humain/web-access/vendor/brightdata.js.map +1 -1
  283. package/dist/humain/web-access/vendor/chrome-cookies.d.ts.map +1 -1
  284. package/dist/humain/web-access/vendor/chrome-cookies.js +101 -19
  285. package/dist/humain/web-access/vendor/chrome-cookies.js.map +1 -1
  286. package/dist/humain/web-access/vendor/content-find.d.ts.map +1 -1
  287. package/dist/humain/web-access/vendor/content-find.js.map +1 -1
  288. package/dist/humain/web-access/vendor/credential-source.d.ts.map +1 -1
  289. package/dist/humain/web-access/vendor/credential-source.js +0 -2
  290. package/dist/humain/web-access/vendor/credential-source.js.map +1 -1
  291. package/dist/humain/web-access/vendor/curator-page.d.ts.map +1 -1
  292. package/dist/humain/web-access/vendor/curator-page.js.map +1 -1
  293. package/dist/humain/web-access/vendor/curator-server.d.ts.map +1 -1
  294. package/dist/humain/web-access/vendor/curator-server.js.map +1 -1
  295. package/dist/humain/web-access/vendor/data-uri-sanitize.d.ts +21 -0
  296. package/dist/humain/web-access/vendor/data-uri-sanitize.d.ts.map +1 -0
  297. package/dist/humain/web-access/vendor/data-uri-sanitize.js +373 -0
  298. package/dist/humain/web-access/vendor/data-uri-sanitize.js.map +1 -0
  299. package/dist/humain/web-access/vendor/datalab-pdf-extract.d.ts.map +1 -1
  300. package/dist/humain/web-access/vendor/datalab-pdf-extract.js.map +1 -1
  301. package/dist/humain/web-access/vendor/declared-web-links.d.ts.map +1 -1
  302. package/dist/humain/web-access/vendor/declared-web-links.js.map +1 -1
  303. package/dist/humain/web-access/vendor/duckduckgo.d.ts.map +1 -1
  304. package/dist/humain/web-access/vendor/duckduckgo.js.map +1 -1
  305. package/dist/humain/web-access/vendor/exa.d.ts.map +1 -1
  306. package/dist/humain/web-access/vendor/exa.js.map +1 -1
  307. package/dist/humain/web-access/vendor/extract.d.ts.map +1 -1
  308. package/dist/humain/web-access/vendor/extract.js +14 -2
  309. package/dist/humain/web-access/vendor/extract.js.map +1 -1
  310. package/dist/humain/web-access/vendor/feature-config.d.ts.map +1 -1
  311. package/dist/humain/web-access/vendor/feature-config.js.map +1 -1
  312. package/dist/humain/web-access/vendor/fetch-params.d.ts.map +1 -1
  313. package/dist/humain/web-access/vendor/fetch-params.js.map +1 -1
  314. package/dist/humain/web-access/vendor/firecrawl.d.ts.map +1 -1
  315. package/dist/humain/web-access/vendor/firecrawl.js +15 -2
  316. package/dist/humain/web-access/vendor/firecrawl.js.map +1 -1
  317. package/dist/humain/web-access/vendor/gemini-api.d.ts.map +1 -1
  318. package/dist/humain/web-access/vendor/gemini-api.js.map +1 -1
  319. package/dist/humain/web-access/vendor/gemini-pdf-extract.d.ts.map +1 -1
  320. package/dist/humain/web-access/vendor/gemini-pdf-extract.js.map +1 -1
  321. package/dist/humain/web-access/vendor/gemini-search.d.ts.map +1 -1
  322. package/dist/humain/web-access/vendor/gemini-search.js +30 -16
  323. package/dist/humain/web-access/vendor/gemini-search.js.map +1 -1
  324. package/dist/humain/web-access/vendor/gemini-url-context.d.ts.map +1 -1
  325. package/dist/humain/web-access/vendor/gemini-url-context.js.map +1 -1
  326. package/dist/humain/web-access/vendor/gemini-web-config.d.ts.map +1 -1
  327. package/dist/humain/web-access/vendor/gemini-web-config.js.map +1 -1
  328. package/dist/humain/web-access/vendor/gemini-web.d.ts.map +1 -1
  329. package/dist/humain/web-access/vendor/gemini-web.js.map +1 -1
  330. package/dist/humain/web-access/vendor/github-api.d.ts.map +1 -1
  331. package/dist/humain/web-access/vendor/github-api.js.map +1 -1
  332. package/dist/humain/web-access/vendor/github-extract.d.ts.map +1 -1
  333. package/dist/humain/web-access/vendor/github-extract.js +69 -35
  334. package/dist/humain/web-access/vendor/github-extract.js.map +1 -1
  335. package/dist/humain/web-access/vendor/index.d.ts +74 -1
  336. package/dist/humain/web-access/vendor/index.d.ts.map +1 -1
  337. package/dist/humain/web-access/vendor/index.js +38 -15
  338. package/dist/humain/web-access/vendor/index.js.map +1 -1
  339. package/dist/humain/web-access/vendor/jina-search.d.ts.map +1 -1
  340. package/dist/humain/web-access/vendor/jina-search.js.map +1 -1
  341. package/dist/humain/web-access/vendor/kagi.d.ts.map +1 -1
  342. package/dist/humain/web-access/vendor/kagi.js.map +1 -1
  343. package/dist/humain/web-access/vendor/ollama.d.ts.map +1 -1
  344. package/dist/humain/web-access/vendor/ollama.js.map +1 -1
  345. package/dist/humain/web-access/vendor/openai-search.d.ts +1 -1
  346. package/dist/humain/web-access/vendor/openai-search.d.ts.map +1 -1
  347. package/dist/humain/web-access/vendor/openai-search.js +15 -5
  348. package/dist/humain/web-access/vendor/openai-search.js.map +1 -1
  349. package/dist/humain/web-access/vendor/page-query.d.ts.map +1 -1
  350. package/dist/humain/web-access/vendor/page-query.js.map +1 -1
  351. package/dist/humain/web-access/vendor/parallel-mcp.d.ts.map +1 -1
  352. package/dist/humain/web-access/vendor/parallel-mcp.js.map +1 -1
  353. package/dist/humain/web-access/vendor/parallel.d.ts.map +1 -1
  354. package/dist/humain/web-access/vendor/parallel.js.map +1 -1
  355. package/dist/humain/web-access/vendor/pdf-extract.d.ts +1 -0
  356. package/dist/humain/web-access/vendor/pdf-extract.d.ts.map +1 -1
  357. package/dist/humain/web-access/vendor/pdf-extract.js +15 -5
  358. package/dist/humain/web-access/vendor/pdf-extract.js.map +1 -1
  359. package/dist/humain/web-access/vendor/perplexity.d.ts.map +1 -1
  360. package/dist/humain/web-access/vendor/perplexity.js.map +1 -1
  361. package/dist/humain/web-access/vendor/querit.d.ts.map +1 -1
  362. package/dist/humain/web-access/vendor/querit.js.map +1 -1
  363. package/dist/humain/web-access/vendor/query-rewrite.d.ts.map +1 -1
  364. package/dist/humain/web-access/vendor/query-rewrite.js.map +1 -1
  365. package/dist/humain/web-access/vendor/render-search-error.d.ts.map +1 -1
  366. package/dist/humain/web-access/vendor/render-search-error.js.map +1 -1
  367. package/dist/humain/web-access/vendor/rsc-extract.d.ts.map +1 -1
  368. package/dist/humain/web-access/vendor/rsc-extract.js.map +1 -1
  369. package/dist/humain/web-access/vendor/search1api.d.ts.map +1 -1
  370. package/dist/humain/web-access/vendor/search1api.js.map +1 -1
  371. package/dist/humain/web-access/vendor/searchinfinity.d.ts.map +1 -1
  372. package/dist/humain/web-access/vendor/searchinfinity.js.map +1 -1
  373. package/dist/humain/web-access/vendor/searxng.d.ts.map +1 -1
  374. package/dist/humain/web-access/vendor/searxng.js.map +1 -1
  375. package/dist/humain/web-access/vendor/serpbase.d.ts.map +1 -1
  376. package/dist/humain/web-access/vendor/serpbase.js.map +1 -1
  377. package/dist/humain/web-access/vendor/serpdive.d.ts.map +1 -1
  378. package/dist/humain/web-access/vendor/serpdive.js.map +1 -1
  379. package/dist/humain/web-access/vendor/serper.d.ts.map +1 -1
  380. package/dist/humain/web-access/vendor/serper.js.map +1 -1
  381. package/dist/humain/web-access/vendor/source-check.d.ts.map +1 -1
  382. package/dist/humain/web-access/vendor/source-check.js.map +1 -1
  383. package/dist/humain/web-access/vendor/ssrf-protection.d.ts +2 -0
  384. package/dist/humain/web-access/vendor/ssrf-protection.d.ts.map +1 -1
  385. package/dist/humain/web-access/vendor/ssrf-protection.js +11 -2
  386. package/dist/humain/web-access/vendor/ssrf-protection.js.map +1 -1
  387. package/dist/humain/web-access/vendor/storage.d.ts.map +1 -1
  388. package/dist/humain/web-access/vendor/storage.js.map +1 -1
  389. package/dist/humain/web-access/vendor/summary-model-scope.d.ts.map +1 -1
  390. package/dist/humain/web-access/vendor/summary-model-scope.js.map +1 -1
  391. package/dist/humain/web-access/vendor/summary-review.d.ts.map +1 -1
  392. package/dist/humain/web-access/vendor/summary-review.js.map +1 -1
  393. package/dist/humain/web-access/vendor/tavily.d.ts.map +1 -1
  394. package/dist/humain/web-access/vendor/tavily.js.map +1 -1
  395. package/dist/humain/web-access/vendor/tinyfish.d.ts.map +1 -1
  396. package/dist/humain/web-access/vendor/tinyfish.js.map +1 -1
  397. package/dist/humain/web-access/vendor/utils.d.ts.map +1 -1
  398. package/dist/humain/web-access/vendor/utils.js.map +1 -1
  399. package/dist/humain/web-access/vendor/valyu.d.ts.map +1 -1
  400. package/dist/humain/web-access/vendor/valyu.js.map +1 -1
  401. package/dist/humain/web-access/vendor/video-extract.d.ts.map +1 -1
  402. package/dist/humain/web-access/vendor/video-extract.js.map +1 -1
  403. package/dist/humain/web-access/vendor/xai-search.d.ts.map +1 -1
  404. package/dist/humain/web-access/vendor/xai-search.js.map +1 -1
  405. package/dist/humain/web-access/vendor/youtube-extract.d.ts.map +1 -1
  406. package/dist/humain/web-access/vendor/youtube-extract.js.map +1 -1
  407. package/dist/index.d.ts +1 -1
  408. package/dist/index.d.ts.map +1 -1
  409. package/dist/index.js.map +1 -1
  410. package/dist/main.d.ts.map +1 -1
  411. package/dist/main.js +4 -0
  412. package/dist/main.js.map +1 -1
  413. package/dist/migrations.d.ts.map +1 -1
  414. package/dist/migrations.js.map +1 -1
  415. package/dist/modes/agent-exec-mode.d.ts.map +1 -1
  416. package/dist/modes/agent-exec-mode.js.map +1 -1
  417. package/dist/modes/index.d.ts.map +1 -1
  418. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  419. package/dist/modes/interactive/components/armin.js +6 -10
  420. package/dist/modes/interactive/components/armin.js.map +1 -1
  421. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  422. package/dist/modes/interactive/components/assistant-message.js +2 -9
  423. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  424. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  425. package/dist/modes/interactive/components/bash-execution.js +4 -9
  426. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  427. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  428. package/dist/modes/interactive/components/bordered-loader.js +0 -3
  429. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  430. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  431. package/dist/modes/interactive/components/branch-summary-message.js +1 -3
  432. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  433. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  434. package/dist/modes/interactive/components/compaction-summary-message.js +1 -3
  435. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  436. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  437. package/dist/modes/interactive/components/config-selector.js +5 -22
  438. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  439. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  440. package/dist/modes/interactive/components/countdown-timer.js +0 -5
  441. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  442. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  443. package/dist/modes/interactive/components/custom-editor.js +1 -8
  444. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  445. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  446. package/dist/modes/interactive/components/custom-entry.js +1 -4
  447. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  448. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  449. package/dist/modes/interactive/components/custom-message.js +1 -7
  450. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  451. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  452. package/dist/modes/interactive/components/daxnuts.js +6 -8
  453. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  454. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  455. package/dist/modes/interactive/components/diff.js +2 -2
  456. package/dist/modes/interactive/components/diff.js.map +1 -1
  457. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  458. package/dist/modes/interactive/components/dynamic-border.js +0 -1
  459. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  460. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
  461. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
  462. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  463. package/dist/modes/interactive/components/extension-editor.js +1 -7
  464. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  465. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  466. package/dist/modes/interactive/components/extension-input.js +2 -8
  467. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  468. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  469. package/dist/modes/interactive/components/extension-selector.js +1 -9
  470. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  471. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  472. package/dist/modes/interactive/components/first-time-setup.js +2 -4
  473. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  474. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  475. package/dist/modes/interactive/components/footer.js +1 -3
  476. package/dist/modes/interactive/components/footer.js.map +1 -1
  477. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  478. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  479. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  480. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  481. package/dist/modes/interactive/components/login-dialog.js +3 -9
  482. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  483. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
  484. package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
  485. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
  486. package/dist/modes/interactive/components/mermaid.js.map +1 -1
  487. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  488. package/dist/modes/interactive/components/model-selector.js +14 -26
  489. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  490. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  491. package/dist/modes/interactive/components/oauth-selector.js +3 -11
  492. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  493. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  494. package/dist/modes/interactive/components/scoped-models-selector.js +9 -14
  495. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  496. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  497. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  498. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  499. package/dist/modes/interactive/components/session-selector.js +33 -57
  500. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  501. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  502. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  503. package/dist/modes/interactive/components/settings-selector.js +10 -14
  504. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  505. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  506. package/dist/modes/interactive/components/show-images-selector.js +0 -1
  507. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  508. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  509. package/dist/modes/interactive/components/skill-invocation-message.js +1 -3
  510. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  511. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  512. package/dist/modes/interactive/components/status-indicator.js +0 -2
  513. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  514. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  515. package/dist/modes/interactive/components/theme-selector.js +0 -2
  516. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  517. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  518. package/dist/modes/interactive/components/thinking-selector.js +0 -1
  519. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  520. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  521. package/dist/modes/interactive/components/tool-execution.js +19 -25
  522. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  523. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  524. package/dist/modes/interactive/components/tree-selector.js +18 -34
  525. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  526. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
  527. package/dist/modes/interactive/components/trust-selector.js +0 -6
  528. package/dist/modes/interactive/components/trust-selector.js.map +1 -1
  529. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  530. package/dist/modes/interactive/components/user-message-selector.js +3 -6
  531. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  532. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  533. package/dist/modes/interactive/components/user-message.js +0 -4
  534. package/dist/modes/interactive/components/user-message.js.map +1 -1
  535. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  536. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  537. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  538. package/dist/modes/interactive/external-editor.js.map +1 -1
  539. package/dist/modes/interactive/interactive-mode.d.ts +18 -2
  540. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  541. package/dist/modes/interactive/interactive-mode.js +147 -137
  542. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  543. package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
  544. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
  545. package/dist/modes/interactive/model-catalog-refresh.js +36 -0
  546. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
  547. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  548. package/dist/modes/interactive/model-search.js.map +1 -1
  549. package/dist/modes/interactive/theme/dark.json +2 -0
  550. package/dist/modes/interactive/theme/light.json +2 -0
  551. package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
  552. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  553. package/dist/modes/interactive/theme/theme-controller.js +25 -18
  554. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  555. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  556. package/dist/modes/interactive/theme/theme.d.ts +7 -5
  557. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  558. package/dist/modes/interactive/theme/theme.js +12 -8
  559. package/dist/modes/interactive/theme/theme.js.map +1 -1
  560. package/dist/modes/json-event.d.ts +4 -1
  561. package/dist/modes/json-event.d.ts.map +1 -1
  562. package/dist/modes/json-event.js +5 -2
  563. package/dist/modes/json-event.js.map +1 -1
  564. package/dist/modes/print-mode.d.ts.map +1 -1
  565. package/dist/modes/print-mode.js.map +1 -1
  566. package/dist/modes/rpc/jsonl.d.ts.map +1 -1
  567. package/dist/modes/rpc/jsonl.js.map +1 -1
  568. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  569. package/dist/modes/rpc/rpc-client.js +9 -10
  570. package/dist/modes/rpc/rpc-client.js.map +1 -1
  571. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  572. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  573. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  574. package/dist/package-manager-cli.d.ts.map +1 -1
  575. package/dist/package-manager-cli.js.map +1 -1
  576. package/dist/rpc-entry.d.ts.map +1 -1
  577. package/dist/rpc-entry.js.map +1 -1
  578. package/dist/server/create-harness.d.ts.map +1 -1
  579. package/dist/server/create-harness.js +2 -0
  580. package/dist/server/create-harness.js.map +1 -1
  581. package/dist/utils/abort.d.ts.map +1 -1
  582. package/dist/utils/abort.js.map +1 -1
  583. package/dist/utils/ansi.d.ts.map +1 -1
  584. package/dist/utils/ansi.js.map +1 -1
  585. package/dist/utils/changelog.d.ts.map +1 -1
  586. package/dist/utils/changelog.js.map +1 -1
  587. package/dist/utils/child-process.d.ts.map +1 -1
  588. package/dist/utils/child-process.js.map +1 -1
  589. package/dist/utils/clipboard-image.d.ts.map +1 -1
  590. package/dist/utils/clipboard-image.js +1 -1
  591. package/dist/utils/clipboard-image.js.map +1 -1
  592. package/dist/utils/clipboard-native.d.ts.map +1 -1
  593. package/dist/utils/clipboard-native.js.map +1 -1
  594. package/dist/utils/clipboard.d.ts.map +1 -1
  595. package/dist/utils/clipboard.js.map +1 -1
  596. package/dist/utils/deprecation.d.ts.map +1 -1
  597. package/dist/utils/deprecation.js.map +1 -1
  598. package/dist/utils/exif-orientation.d.ts.map +1 -1
  599. package/dist/utils/exif-orientation.js.map +1 -1
  600. package/dist/utils/frontmatter.d.ts.map +1 -1
  601. package/dist/utils/frontmatter.js.map +1 -1
  602. package/dist/utils/fs-watch.d.ts.map +1 -1
  603. package/dist/utils/fs-watch.js.map +1 -1
  604. package/dist/utils/git.d.ts.map +1 -1
  605. package/dist/utils/git.js.map +1 -1
  606. package/dist/utils/html.d.ts.map +1 -1
  607. package/dist/utils/html.js.map +1 -1
  608. package/dist/utils/image-convert.d.ts.map +1 -1
  609. package/dist/utils/image-convert.js.map +1 -1
  610. package/dist/utils/image-process.d.ts.map +1 -1
  611. package/dist/utils/image-process.js.map +1 -1
  612. package/dist/utils/image-resize-core.d.ts.map +1 -1
  613. package/dist/utils/image-resize-core.js.map +1 -1
  614. package/dist/utils/image-resize-worker.d.ts.map +1 -1
  615. package/dist/utils/image-resize-worker.js.map +1 -1
  616. package/dist/utils/image-resize.d.ts.map +1 -1
  617. package/dist/utils/image-resize.js.map +1 -1
  618. package/dist/utils/json.d.ts.map +1 -1
  619. package/dist/utils/json.js.map +1 -1
  620. package/dist/utils/management-http.d.ts.map +1 -1
  621. package/dist/utils/management-http.js.map +1 -1
  622. package/dist/utils/mime.d.ts.map +1 -1
  623. package/dist/utils/mime.js.map +1 -1
  624. package/dist/utils/open-browser.d.ts.map +1 -1
  625. package/dist/utils/open-browser.js.map +1 -1
  626. package/dist/utils/paths.d.ts.map +1 -1
  627. package/dist/utils/paths.js.map +1 -1
  628. package/dist/utils/photon.d.ts.map +1 -1
  629. package/dist/utils/photon.js.map +1 -1
  630. package/dist/utils/pi-user-agent.d.ts.map +1 -1
  631. package/dist/utils/pi-user-agent.js.map +1 -1
  632. package/dist/utils/shell.d.ts.map +1 -1
  633. package/dist/utils/shell.js.map +1 -1
  634. package/dist/utils/sleep.d.ts.map +1 -1
  635. package/dist/utils/sleep.js.map +1 -1
  636. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  637. package/dist/utils/syntax-highlight.js +1 -1
  638. package/dist/utils/syntax-highlight.js.map +1 -1
  639. package/dist/utils/tool-result-images.d.ts.map +1 -1
  640. package/dist/utils/tool-result-images.js.map +1 -1
  641. package/dist/utils/tools-manager.d.ts +10 -1
  642. package/dist/utils/tools-manager.d.ts.map +1 -1
  643. package/dist/utils/tools-manager.js +14 -19
  644. package/dist/utils/tools-manager.js.map +1 -1
  645. package/dist/utils/version-check.d.ts.map +1 -1
  646. package/dist/utils/version-check.js.map +1 -1
  647. package/dist/utils/windows-self-update.d.ts.map +1 -1
  648. package/dist/utils/windows-self-update.js.map +1 -1
  649. package/docs/compaction.md +3 -3
  650. package/docs/custom-provider.md +1 -1
  651. package/docs/environment-variables.md +1 -0
  652. package/docs/extensions.md +4 -0
  653. package/docs/json.md +6 -4
  654. package/docs/keybindings.md +8 -2
  655. package/docs/rpc.md +15 -4
  656. package/docs/sdk.md +9 -0
  657. package/docs/settings.md +31 -0
  658. package/docs/terminal-setup.md +23 -2
  659. package/docs/themes.md +23 -3
  660. package/docs/tui.md +2 -2
  661. package/docs/usage.md +3 -2
  662. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  663. package/examples/extensions/custom-provider-anthropic/package.json +2 -2
  664. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  665. package/examples/extensions/gondolin/package-lock.json +2 -2
  666. package/examples/extensions/gondolin/package.json +1 -1
  667. package/examples/extensions/minimal-mode.ts +6 -6
  668. package/examples/extensions/sandbox/package-lock.json +2 -2
  669. package/examples/extensions/sandbox/package.json +2 -2
  670. package/examples/extensions/with-deps/package-lock.json +2 -2
  671. package/examples/extensions/with-deps/package.json +1 -1
  672. package/npm-shrinkwrap.json +853 -661
  673. package/package.json +33 -33
  674. package/src/humain/web-access/UPSTREAM.md +1 -1
  675. package/src/humain/web-access/upstream.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"gemini-web.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/gemini-web.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport { getLastGoogleCookieDiagnostic, type CookieMap, getGoogleCookies } from \"./chrome-cookies.ts\";\nimport { getChromeProfileFromConfig, isBrowserCookieAccessAllowed, normalizeChromeProfile } from \"./gemini-web-config.ts\";\n\nconst GEMINI_APP_URL = \"https://gemini.google.com/app\";\nconst GEMINI_STREAM_GENERATE_URL =\n\t\"https://gemini.google.com/_/BardChatUi/data/assistant.lamda.BardFrontendService/StreamGenerate\";\nconst GEMINI_UPLOAD_URL = \"https://content-push.googleapis.com/upload\";\nconst GEMINI_UPLOAD_PUSH_ID = \"feeds/mcudyrk2a4khkz\";\nconst GOOGLE_LIST_ACCOUNTS_URL =\n\t\"https://accounts.google.com/ListAccounts?gpsia=1&source=ChromiumBrowser&laf=b64bin&json=standard\";\n\nconst USER_AGENT =\n\t\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\";\n\nconst MODEL_HEADER_NAME = \"x-goog-ext-525001261-jspb\";\nexport const DEFAULT_GEMINI_WEB_MODEL = \"gemini-3.1-pro\";\nconst MODEL_HEADERS: Record<string, string> = {\n\t[DEFAULT_GEMINI_WEB_MODEL]: '[1,null,null,null,\"9d8ca3786ebdfbea\",null,null,0,[4]]',\n\t\"gemini-2.5-pro\": '[1,null,null,null,\"4af6c7f5da75d65d\",null,null,0,[4]]',\n\t\"gemini-2.5-flash\": '[1,null,null,null,\"9ec249fc9ad08861\",null,null,0,[4]]',\n};\n\nconst REQUIRED_COOKIES = [\"__Secure-1PSID\", \"__Secure-1PSIDTS\"];\n\n// Gemini Web talks to Google's frontend inside the host agent (pi), whose\n// global undici dispatcher runs HTTP/1.1 with undici's default 16 KiB\n// maxHeaderSize. Google's gemini.google.com /app response headers routinely\n// exceed that budget over HTTP/1.1, so cookie-bearing requests fail with\n// UND_ERR_HEADERS_OVERFLOW surfaced as \"fetch failed\". Route these requests\n// through a dedicated undici Agent with a larger header budget instead; fall\n// back to the ambient global fetch when undici is not resolvable (e.g.\n// standalone test environments).\nlet geminiFetchImpl: typeof fetch | null = null;\n\n// Test-only hook: lets tests inject a simulated transport instead of patching\n// globalThis.fetch. Gemini Web deliberately bypasses the ambient global fetch\n// (inside the pi host agent it is constrained to undici's 16 KiB\n// maxHeaderSize and cannot serve Google's /app page over HTTP/1.1), so\n// globalThis.fetch patching is no longer a reliable way to intercept these\n// requests.\nexport function setGeminiFetchOverrideForTests(fetchImpl: typeof fetch | null): void {\n\tgeminiFetchOverride = fetchImpl;\n}\n\nlet geminiFetchOverride: typeof fetch | null = null;\n\n// The header budget Gemini Web needs for Google frontend responses.\n// Google's /app page exceeds undici's default 16 KiB maxHeaderSize when\n// served over HTTP/1.1, which is how pi's global dispatcher operates.\nexport const GEMINI_MAX_HEADER_SIZE = 4 * 1024 * 1024;\n\n// Build a fetch that routes through a dedicated undici Agent with a larger\n// header budget than the host agent's global dispatcher allows. Exported for\n// tests so the agent configuration can be asserted without network access.\nexport function createGeminiFetch(undiciImpl: typeof import(\"undici\")): typeof fetch {\n\tconst agent = new undiciImpl.EnvHttpProxyAgent({\n\t\tallowH2: false,\n\t\tconnectTimeout: 30_000,\n\t\tmaxHeaderSize: GEMINI_MAX_HEADER_SIZE,\n\t\tpipelining: 1,\n\t});\n\t// undici 8 types its fetch request/response structurally differently from\n\t// the DOM lib types (duplex/textStream on Request, Symbol.dispose on\n\t// Headers); the shape this module uses (status, ok, headers.get, text) is\n\t// identical, so bridge the two.\n\ttype UndiciFetch = typeof undiciImpl.fetch;\n\treturn (input, init) =>\n\t\tundiciImpl.fetch(\n\t\t\tinput as unknown as Parameters<UndiciFetch>[0],\n\t\t\t{ ...init, dispatcher: agent } as unknown as Parameters<UndiciFetch>[1],\n\t\t) as unknown as Promise<Response>;\n}\n\nexport async function resolveGeminiFetch(): Promise<typeof fetch> {\n\tif (geminiFetchOverride) return geminiFetchOverride;\n\tif (geminiFetchImpl) return geminiFetchImpl;\n\n\tlet undici: typeof import(\"undici\");\n\ttry {\n\t\tundici = await import(\"undici\");\n\t} catch {\n\t\tgeminiFetchImpl = fetch;\n\t\treturn geminiFetchImpl;\n\t}\n\n\tgeminiFetchImpl = createGeminiFetch(undici);\n\treturn geminiFetchImpl;\n}\n\nexport interface GeminiWebOptions {\n\tyoutubeUrl?: string;\n\tmodel?: string;\n\tfiles?: string[];\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n}\n\nexport async function isGeminiWebAvailable(chromeProfile?: string): Promise<CookieMap | null> {\n\tif (!isBrowserCookieAccessAllowed()) return null;\n\n\tconst result = await getGoogleCookies({\n\t\tprofile: normalizeChromeProfile(chromeProfile) ?? getChromeProfileFromConfig(),\n\t\trequiredCookies: REQUIRED_COOKIES,\n\t});\n\tif (!result) return null;\n\treturn result.cookies;\n}\n\nexport function getGeminiWebAvailabilityDiagnostic(): string | null {\n\treturn isBrowserCookieAccessAllowed() ? getLastGoogleCookieDiagnostic() : null;\n}\n\nexport async function getActiveGoogleEmail(cookies: CookieMap): Promise<string | null> {\n\tconst cookieHeader = buildCookieHeader(cookies);\n\tif (!cookieHeader) return null;\n\n\ttry {\n\t\tconst html = await fetchWithCookieRedirects(\n\t\t\tGEMINI_APP_URL,\n\t\t\tcookieHeader,\n\t\t\t10,\n\t\t\tAbortSignal.timeout(10000),\n\t\t);\n\t\tconst email = extractEmailFromGeminiHtml(html);\n\t\tif (email) return email;\n\t} catch {\n\t}\n\n\ttry {\n\t\tconst response = await fetchWithCookieRedirects(\n\t\t\tGOOGLE_LIST_ACCOUNTS_URL,\n\t\t\tcookieHeader,\n\t\t\t10,\n\t\t\tAbortSignal.timeout(10000),\n\t\t);\n\t\treturn extractEmailFromListAccounts(response);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport async function queryWithCookies(\n\tprompt: string,\n\tcookieMap: CookieMap,\n\toptions: GeminiWebOptions = {},\n): Promise<string> {\n\tconst model = options.model ?? DEFAULT_GEMINI_WEB_MODEL;\n\tif (!MODEL_HEADERS[model]) {\n\t\tthrow new Error(`Gemini Web does not support model ${model}; configure Gemini API or choose a supported Gemini Web model.`);\n\t}\n\tconst timeoutMs = options.timeoutMs ?? 120000;\n\n\tlet fullPrompt = prompt;\n\tif (options.youtubeUrl) {\n\t\tfullPrompt = `${fullPrompt}\\n\\nYouTube video: ${options.youtubeUrl}`;\n\t}\n\n\tconst result = await runGeminiWebOnce(fullPrompt, cookieMap, model, options.files, timeoutMs, options.signal);\n\n\tif (result.errorMessage) throw new Error(result.errorMessage);\n\tif (!result.text) throw new Error(\"Gemini Web returned empty response\");\n\treturn result.text;\n}\n\ninterface GeminiWebResult {\n\ttext: string;\n\terrorCode?: number;\n\terrorMessage?: string;\n}\n\nasync function runGeminiWebOnce(\n\tprompt: string,\n\tcookieMap: CookieMap,\n\tmodel: string,\n\tfiles: string[] | undefined,\n\ttimeoutMs: number,\n\tsignal?: AbortSignal,\n): Promise<GeminiWebResult> {\n\tconst effectiveSignal = withTimeout(signal, timeoutMs);\n\tconst cookieHeader = buildCookieHeader(cookieMap);\n\tconst accessToken = await fetchAccessToken(cookieHeader, effectiveSignal);\n\n\tconst uploaded: Array<{ id: string; name: string }> = [];\n\tif (files) {\n\t\tfor (const filePath of files) {\n\t\t\tuploaded.push(await uploadFile(filePath, cookieHeader, effectiveSignal));\n\t\t}\n\t}\n\n\tconst fReq = buildFReqPayload(prompt, uploaded);\n\tconst params = new URLSearchParams();\n\tparams.set(\"at\", accessToken);\n\tparams.set(\"f.req\", fReq);\n\n\tconst res = await (await resolveGeminiFetch())(GEMINI_STREAM_GENERATE_URL, {\n\t\tmethod: \"POST\",\n\t\tredirect: \"error\",\n\t\theaders: {\n\t\t\t\"content-type\": \"application/x-www-form-urlencoded;charset=utf-8\",\n\t\t\thost: \"gemini.google.com\",\n\t\t\torigin: \"https://gemini.google.com\",\n\t\t\treferer: \"https://gemini.google.com/\",\n\t\t\t\"x-same-domain\": \"1\",\n\t\t\t\"user-agent\": USER_AGENT,\n\t\t\tcookie: cookieHeader,\n\t\t\t[MODEL_HEADER_NAME]: MODEL_HEADERS[model],\n\t\t},\n\t\tbody: params.toString(),\n\t\tsignal: effectiveSignal,\n\t});\n\n\tconst rawText = await res.text();\n\n\tif (!res.ok) {\n\t\treturn { text: \"\", errorMessage: `Gemini request failed: ${res.status}` };\n\t}\n\n\ttry {\n\t\treturn parseStreamGenerateResponse(rawText);\n\t} catch (err) {\n\t\tlet errorCode: number | undefined;\n\t\ttry {\n\t\t\tconst json = JSON.parse(trimJsonEnvelope(rawText));\n\t\t\terrorCode = extractErrorCode(json);\n\t\t} catch {\n\t\t}\n\t\treturn {\n\t\t\ttext: \"\",\n\t\t\terrorCode,\n\t\t\terrorMessage: err instanceof Error ? err.message : String(err),\n\t\t};\n\t}\n}\n\nasync function fetchAccessToken(\n\tcookieHeader: string,\n\tsignal: AbortSignal,\n): Promise<string> {\n\tconst html = await fetchWithCookieRedirects(GEMINI_APP_URL, cookieHeader, 10, signal);\n\n\tfor (const key of [\"SNlM0e\", \"thykhd\"]) {\n\t\tconst match = html.match(new RegExp(`\"${key}\":\"(.*?)\"`));\n\t\tif (match?.[1]) return match[1];\n\t}\n\n\tthrow new Error(\"Unable to authenticate with Gemini. Make sure you're signed into gemini.google.com in a supported Chromium-based browser.\");\n}\n\nasync function fetchWithCookieRedirects(\n\turl: string,\n\tcookieHeader: string,\n\tmaxRedirects: number,\n\tsignal: AbortSignal,\n): Promise<string> {\n\tlet current = url;\n\tconst allowedOrigin = new URL(url).origin;\n\tfor (let i = 0; i <= maxRedirects; i++) {\n\t\tconst res = await (await resolveGeminiFetch())(current, {\n\t\t\theaders: { \"user-agent\": USER_AGENT, cookie: cookieHeader },\n\t\t\tredirect: \"manual\",\n\t\t\tsignal,\n\t\t});\n\t\tif (res.status >= 300 && res.status < 400) {\n\t\t\tconst location = res.headers.get(\"location\");\n\t\t\tif (location) {\n\t\t\t\tconst next = new URL(location, current);\n\t\t\t\tif (next.origin !== allowedOrigin) {\n\t\t\t\t\tthrow new Error(`Refusing to send Google cookies across origins: ${allowedOrigin} -> ${next.origin}`);\n\t\t\t\t}\n\t\t\t\tcurrent = next.toString();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\treturn await res.text();\n\t}\n\tthrow new Error(`Too many redirects (>${maxRedirects})`);\n}\n\nfunction extractEmailFromGeminiHtml(html: string): string | null {\n\tconst patterns = [\n\t\t// Gemini bootstraps the active account in oPEP7c. Prefer it over generic\n\t\t// feature/config entries that may contain other signed-in Google accounts.\n\t\t/\"oPEP7c\"\\s*:\\s*\"([^\"]+)\"/,\n\t\t// The Google account menu aria-label is rendered for the active account.\n\t\t/aria-label=\"Google Account:[^\"]*?\\(([^)]+)\\)\"/,\n\t\t/\"displayEmail\"\\s*:\\s*\"([^\"]+)\"/,\n\t\t/\"defaultEmail\"\\s*:\\s*\"([^\"]+)\"/,\n\t\t/\"email\"\\s*:\\s*\"([^\"]+)\"/,\n\t\t/\"identifier\"\\s*:\\s*\"([^\"]+)\"/,\n\t\t/\"gaiaIdentifier\"\\s*:\\s*\"([^\"]+)\"/,\n\t];\n\n\tfor (const pattern of patterns) {\n\t\tconst match = html.match(pattern);\n\t\tconst email = normalizeEmail(match?.[1]);\n\t\tif (email) return email;\n\t}\n\n\treturn findFirstEmail(html);\n}\n\nfunction extractEmailFromListAccounts(text: string): string | null {\n\tconst trimmed = text.replace(/^\\)\\]\\}'\\s*/, \"\");\n\ttry {\n\t\treturn findEmailInValue(JSON.parse(trimmed)) ?? findFirstEmail(trimmed);\n\t} catch {\n\t\treturn findFirstEmail(trimmed);\n\t}\n}\n\nfunction findEmailInValue(value: unknown): string | null {\n\tif (typeof value === \"string\") return normalizeEmail(value);\n\tif (Array.isArray(value)) {\n\t\tfor (const item of value) {\n\t\t\tconst email = findEmailInValue(item);\n\t\t\tif (email) return email;\n\t\t}\n\t\treturn null;\n\t}\n\tif (value && typeof value === \"object\") {\n\t\tfor (const item of Object.values(value as Record<string, unknown>)) {\n\t\t\tconst email = findEmailInValue(item);\n\t\t\tif (email) return email;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction findFirstEmail(text: string): string | null {\n\tconst normalized = decodeEmailEscapes(text);\n\tconst match = normalized.match(/\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\b/i);\n\treturn match?.[0] ?? null;\n}\n\nfunction normalizeEmail(value: string | undefined): string | null {\n\tif (!value) return null;\n\tconst normalized = decodeEmailEscapes(value.trim());\n\treturn /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$/i.test(normalized) ? normalized : null;\n}\n\nfunction decodeEmailEscapes(value: string): string {\n\treturn value\n\t\t.replace(/\\\\u0040/gi, \"@\")\n\t\t.replace(/\\\\x40/gi, \"@\")\n\t\t.replace(/&#64;/gi, \"@\")\n\t\t.replace(/&commat;/gi, \"@\")\n\t\t.replace(/\\\\\"/g, \"\\\"\")\n\t\t.replace(/\\\\\\\\/g, \"\\\\\");\n}\n\nasync function uploadFile(\n\tfilePath: string,\n\tcookieHeader: string,\n\tsignal: AbortSignal,\n): Promise<{ id: string; name: string }> {\n\tconst data = readFileSync(filePath);\n\tconst fileName = basename(filePath);\n\tconst boundary = \"----FormBoundary\" + Math.random().toString(36).slice(2);\n\tconst header = `--${boundary}\\r\\nContent-Disposition: form-data; name=\"file\"; filename=\"${fileName}\"\\r\\nContent-Type: application/octet-stream\\r\\n\\r\\n`;\n\tconst footer = `\\r\\n--${boundary}--\\r\\n`;\n\n\tconst body = Buffer.concat([\n\t\tBuffer.from(header, \"utf-8\"),\n\t\tdata,\n\t\tBuffer.from(footer, \"utf-8\"),\n\t]);\n\n\tconst res = await (await resolveGeminiFetch())(GEMINI_UPLOAD_URL, {\n\t\tmethod: \"POST\",\n\t\tredirect: \"error\",\n\t\theaders: {\n\t\t\t\"content-type\": `multipart/form-data; boundary=${boundary}`,\n\t\t\t\"push-id\": GEMINI_UPLOAD_PUSH_ID,\n\t\t\t\"user-agent\": USER_AGENT,\n\t\t\tcookie: cookieHeader,\n\t\t},\n\t\tbody,\n\t\tsignal,\n\t});\n\n\tif (!res.ok) {\n\t\tconst text = await res.text();\n\t\tthrow new Error(`File upload failed: ${res.status} (${text.slice(0, 200)})`);\n\t}\n\n\treturn { id: await res.text(), name: fileName };\n}\n\nfunction buildFReqPayload(\n\tprompt: string,\n\tuploaded: Array<{ id: string; name: string }>,\n): string {\n\tconst promptPayload =\n\t\tuploaded.length > 0\n\t\t\t? [prompt, 0, null, uploaded.map((file) => [[file.id, 1]])]\n\t\t\t: [prompt];\n\tconst innerList = [promptPayload, null, null];\n\treturn JSON.stringify([null, JSON.stringify(innerList)]);\n}\n\nfunction withTimeout(signal: AbortSignal | undefined, timeoutMs: number): AbortSignal {\n\tconst timeout = AbortSignal.timeout(timeoutMs);\n\treturn signal ? AbortSignal.any([signal, timeout]) : timeout;\n}\n\nfunction buildCookieHeader(cookieMap: CookieMap): string {\n\treturn Object.entries(cookieMap)\n\t\t.filter(([, value]) => typeof value === \"string\" && value.length > 0)\n\t\t.map(([name, value]) => `${name}=${value}`)\n\t\t.join(\"; \");\n}\n\nfunction getNestedValue(value: unknown, pathParts: number[]): unknown {\n\tlet current: unknown = value;\n\tfor (const part of pathParts) {\n\t\tif (current == null) return undefined;\n\t\tif (!Array.isArray(current)) return undefined;\n\t\tcurrent = (current as unknown[])[part];\n\t}\n\treturn current;\n}\n\nfunction trimJsonEnvelope(text: string): string {\n\tconst start = text.indexOf(\"[\");\n\tconst end = text.lastIndexOf(\"]\");\n\tif (start === -1 || end === -1 || end <= start) {\n\t\tthrow new Error(\"Gemini response did not contain a JSON payload.\");\n\t}\n\treturn text.slice(start, end + 1);\n}\n\nfunction extractErrorCode(responseJson: unknown): number | undefined {\n\tconst code = getNestedValue(responseJson, [0, 5, 2, 0, 1, 0]);\n\treturn typeof code === \"number\" && code >= 0 ? code : undefined;\n}\n\nfunction extractCandidateText(candidate: unknown): string {\n\tconst textRaw = getNestedValue(candidate, [1, 0]);\n\tlet text = typeof textRaw === \"string\" ? textRaw : \"\";\n\n\tif (/^http:\\/\\/googleusercontent\\.com\\/card_content\\/\\d+/.test(text)) {\n\t\tconst alt = getNestedValue(candidate, [22, 0]);\n\t\tif (typeof alt === \"string\" && alt.length > 0) text = alt;\n\t}\n\n\treturn text;\n}\n\nfunction parseStreamGenerateResponse(rawText: string): GeminiWebResult {\n\tconst responseJson = JSON.parse(trimJsonEnvelope(rawText));\n\tconst errorCode = extractErrorCode(responseJson);\n\n\tconst parts = Array.isArray(responseJson) ? responseJson : [];\n\tlet firstCandidateSeen: unknown = undefined;\n\tlet latestNonEmptyText = \"\";\n\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst partBody = getNestedValue(parts[i], [2]);\n\t\tif (!partBody || typeof partBody !== \"string\") continue;\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(partBody);\n\t\t\tconst candidateList = getNestedValue(parsed, [4]);\n\t\t\tif (!Array.isArray(candidateList) || candidateList.length === 0) continue;\n\n\t\t\tconst firstCandidate = (candidateList as unknown[])[0];\n\t\t\tif (firstCandidateSeen === undefined) firstCandidateSeen = firstCandidate;\n\n\t\t\tconst text = extractCandidateText(firstCandidate);\n\t\t\tif (text.length > 0) latestNonEmptyText = text;\n\t\t} catch {\n\t\t}\n\t}\n\n\tconst text = latestNonEmptyText.length > 0\n\t\t? latestNonEmptyText\n\t\t: extractCandidateText(firstCandidateSeen);\n\n\treturn { text, errorCode };\n}\n"]}
1
+ {"version":3,"file":"gemini-web.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/gemini-web.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport { getLastGoogleCookieDiagnostic, type CookieMap, getGoogleCookies } from \"./chrome-cookies.ts\";\nimport { getChromeProfileFromConfig, isBrowserCookieAccessAllowed, normalizeChromeProfile } from \"./gemini-web-config.ts\";\n\nconst GEMINI_APP_URL = \"https://gemini.google.com/app\";\nconst GEMINI_STREAM_GENERATE_URL =\n\t\"https://gemini.google.com/_/BardChatUi/data/assistant.lamda.BardFrontendService/StreamGenerate\";\nconst GEMINI_UPLOAD_URL = \"https://content-push.googleapis.com/upload\";\nconst GEMINI_UPLOAD_PUSH_ID = \"feeds/mcudyrk2a4khkz\";\nconst GOOGLE_LIST_ACCOUNTS_URL =\n\t\"https://accounts.google.com/ListAccounts?gpsia=1&source=ChromiumBrowser&laf=b64bin&json=standard\";\n\nconst USER_AGENT =\n\t\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\";\n\nconst MODEL_HEADER_NAME = \"x-goog-ext-525001261-jspb\";\nexport const DEFAULT_GEMINI_WEB_MODEL = \"gemini-3.1-pro\";\nconst MODEL_HEADERS: Record<string, string> = {\n\t[DEFAULT_GEMINI_WEB_MODEL]: '[1,null,null,null,\"9d8ca3786ebdfbea\",null,null,0,[4]]',\n\t\"gemini-2.5-pro\": '[1,null,null,null,\"4af6c7f5da75d65d\",null,null,0,[4]]',\n\t\"gemini-2.5-flash\": '[1,null,null,null,\"9ec249fc9ad08861\",null,null,0,[4]]',\n};\n\nconst REQUIRED_COOKIES = [\"__Secure-1PSID\", \"__Secure-1PSIDTS\"];\n\n// Gemini Web talks to Google's frontend inside the host agent (pi), whose\n// global undici dispatcher runs HTTP/1.1 with undici's default 16 KiB\n// maxHeaderSize. Google's gemini.google.com /app response headers routinely\n// exceed that budget over HTTP/1.1, so cookie-bearing requests fail with\n// UND_ERR_HEADERS_OVERFLOW surfaced as \"fetch failed\". Route these requests\n// through a dedicated undici Agent with a larger header budget instead; fall\n// back to the ambient global fetch when undici is not resolvable (e.g.\n// standalone test environments).\nlet geminiFetchImpl: typeof fetch | null = null;\n\n// Test-only hook: lets tests inject a simulated transport instead of patching\n// globalThis.fetch. Gemini Web deliberately bypasses the ambient global fetch\n// (inside the pi host agent it is constrained to undici's 16 KiB\n// maxHeaderSize and cannot serve Google's /app page over HTTP/1.1), so\n// globalThis.fetch patching is no longer a reliable way to intercept these\n// requests.\nexport function setGeminiFetchOverrideForTests(fetchImpl: typeof fetch | null): void {\n\tgeminiFetchOverride = fetchImpl;\n}\n\nlet geminiFetchOverride: typeof fetch | null = null;\n\n// The header budget Gemini Web needs for Google frontend responses.\n// Google's /app page exceeds undici's default 16 KiB maxHeaderSize when\n// served over HTTP/1.1, which is how pi's global dispatcher operates.\nexport const GEMINI_MAX_HEADER_SIZE = 4 * 1024 * 1024;\n\n// Build a fetch that routes through a dedicated undici Agent with a larger\n// header budget than the host agent's global dispatcher allows. Exported for\n// tests so the agent configuration can be asserted without network access.\nexport function createGeminiFetch(undiciImpl: typeof import(\"undici\")): typeof fetch {\n\tconst agent = new undiciImpl.EnvHttpProxyAgent({\n\t\tallowH2: false,\n\t\tconnectTimeout: 30_000,\n\t\tmaxHeaderSize: GEMINI_MAX_HEADER_SIZE,\n\t\tpipelining: 1,\n\t});\n\t// undici 8 types its fetch request/response structurally differently from\n\t// the DOM lib types (duplex/textStream on Request, Symbol.dispose on\n\t// Headers); the shape this module uses (status, ok, headers.get, text) is\n\t// identical, so bridge the two.\n\ttype UndiciFetch = typeof undiciImpl.fetch;\n\treturn (input, init) =>\n\t\tundiciImpl.fetch(\n\t\t\tinput as unknown as Parameters<UndiciFetch>[0],\n\t\t\t{ ...init, dispatcher: agent } as unknown as Parameters<UndiciFetch>[1],\n\t\t) as unknown as Promise<Response>;\n}\n\nexport async function resolveGeminiFetch(): Promise<typeof fetch> {\n\tif (geminiFetchOverride) return geminiFetchOverride;\n\tif (geminiFetchImpl) return geminiFetchImpl;\n\n\tlet undici: typeof import(\"undici\");\n\ttry {\n\t\tundici = await import(\"undici\");\n\t} catch {\n\t\tgeminiFetchImpl = fetch;\n\t\treturn geminiFetchImpl;\n\t}\n\n\tgeminiFetchImpl = createGeminiFetch(undici);\n\treturn geminiFetchImpl;\n}\n\nexport interface GeminiWebOptions {\n\tyoutubeUrl?: string;\n\tmodel?: string;\n\tfiles?: string[];\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n}\n\nexport async function isGeminiWebAvailable(chromeProfile?: string): Promise<CookieMap | null> {\n\tif (!isBrowserCookieAccessAllowed()) return null;\n\n\tconst result = await getGoogleCookies({\n\t\tprofile: normalizeChromeProfile(chromeProfile) ?? getChromeProfileFromConfig(),\n\t\trequiredCookies: REQUIRED_COOKIES,\n\t});\n\tif (!result) return null;\n\treturn result.cookies;\n}\n\nexport function getGeminiWebAvailabilityDiagnostic(): string | null {\n\treturn isBrowserCookieAccessAllowed() ? getLastGoogleCookieDiagnostic() : null;\n}\n\nexport async function getActiveGoogleEmail(cookies: CookieMap): Promise<string | null> {\n\tconst cookieHeader = buildCookieHeader(cookies);\n\tif (!cookieHeader) return null;\n\n\ttry {\n\t\tconst html = await fetchWithCookieRedirects(\n\t\t\tGEMINI_APP_URL,\n\t\t\tcookieHeader,\n\t\t\t10,\n\t\t\tAbortSignal.timeout(10000),\n\t\t);\n\t\tconst email = extractEmailFromGeminiHtml(html);\n\t\tif (email) return email;\n\t} catch {\n\t}\n\n\ttry {\n\t\tconst response = await fetchWithCookieRedirects(\n\t\t\tGOOGLE_LIST_ACCOUNTS_URL,\n\t\t\tcookieHeader,\n\t\t\t10,\n\t\t\tAbortSignal.timeout(10000),\n\t\t);\n\t\treturn extractEmailFromListAccounts(response);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport async function queryWithCookies(\n\tprompt: string,\n\tcookieMap: CookieMap,\n\toptions: GeminiWebOptions = {},\n): Promise<string> {\n\tconst model = options.model ?? DEFAULT_GEMINI_WEB_MODEL;\n\tif (!MODEL_HEADERS[model]) {\n\t\tthrow new Error(`Gemini Web does not support model ${model}; configure Gemini API or choose a supported Gemini Web model.`);\n\t}\n\tconst timeoutMs = options.timeoutMs ?? 120000;\n\n\tlet fullPrompt = prompt;\n\tif (options.youtubeUrl) {\n\t\tfullPrompt = `${fullPrompt}\\n\\nYouTube video: ${options.youtubeUrl}`;\n\t}\n\n\tconst result = await runGeminiWebOnce(fullPrompt, cookieMap, model, options.files, timeoutMs, options.signal);\n\n\tif (result.errorMessage) throw new Error(result.errorMessage);\n\tif (!result.text) throw new Error(\"Gemini Web returned empty response\");\n\treturn result.text;\n}\n\ninterface GeminiWebResult {\n\ttext: string;\n\terrorCode?: number;\n\terrorMessage?: string;\n}\n\nasync function runGeminiWebOnce(\n\tprompt: string,\n\tcookieMap: CookieMap,\n\tmodel: string,\n\tfiles: string[] | undefined,\n\ttimeoutMs: number,\n\tsignal?: AbortSignal,\n): Promise<GeminiWebResult> {\n\tconst effectiveSignal = withTimeout(signal, timeoutMs);\n\tconst cookieHeader = buildCookieHeader(cookieMap);\n\tconst accessToken = await fetchAccessToken(cookieHeader, effectiveSignal);\n\n\tconst uploaded: Array<{ id: string; name: string }> = [];\n\tif (files) {\n\t\tfor (const filePath of files) {\n\t\t\tuploaded.push(await uploadFile(filePath, cookieHeader, effectiveSignal));\n\t\t}\n\t}\n\n\tconst fReq = buildFReqPayload(prompt, uploaded);\n\tconst params = new URLSearchParams();\n\tparams.set(\"at\", accessToken);\n\tparams.set(\"f.req\", fReq);\n\n\tconst res = await (await resolveGeminiFetch())(GEMINI_STREAM_GENERATE_URL, {\n\t\tmethod: \"POST\",\n\t\tredirect: \"error\",\n\t\theaders: {\n\t\t\t\"content-type\": \"application/x-www-form-urlencoded;charset=utf-8\",\n\t\t\thost: \"gemini.google.com\",\n\t\t\torigin: \"https://gemini.google.com\",\n\t\t\treferer: \"https://gemini.google.com/\",\n\t\t\t\"x-same-domain\": \"1\",\n\t\t\t\"user-agent\": USER_AGENT,\n\t\t\tcookie: cookieHeader,\n\t\t\t[MODEL_HEADER_NAME]: MODEL_HEADERS[model],\n\t\t},\n\t\tbody: params.toString(),\n\t\tsignal: effectiveSignal,\n\t});\n\n\tconst rawText = await res.text();\n\n\tif (!res.ok) {\n\t\treturn { text: \"\", errorMessage: `Gemini request failed: ${res.status}` };\n\t}\n\n\ttry {\n\t\treturn parseStreamGenerateResponse(rawText);\n\t} catch (err) {\n\t\tlet errorCode: number | undefined;\n\t\ttry {\n\t\t\tconst json = JSON.parse(trimJsonEnvelope(rawText));\n\t\t\terrorCode = extractErrorCode(json);\n\t\t} catch {\n\t\t}\n\t\treturn {\n\t\t\ttext: \"\",\n\t\t\terrorCode,\n\t\t\terrorMessage: err instanceof Error ? err.message : String(err),\n\t\t};\n\t}\n}\n\nasync function fetchAccessToken(\n\tcookieHeader: string,\n\tsignal: AbortSignal,\n): Promise<string> {\n\tconst html = await fetchWithCookieRedirects(GEMINI_APP_URL, cookieHeader, 10, signal);\n\n\tfor (const key of [\"SNlM0e\", \"thykhd\"]) {\n\t\tconst match = html.match(new RegExp(`\"${key}\":\"(.*?)\"`));\n\t\tif (match?.[1]) return match[1];\n\t}\n\n\tthrow new Error(\"Unable to authenticate with Gemini. Make sure you're signed into gemini.google.com in a supported Chromium-based browser.\");\n}\n\nasync function fetchWithCookieRedirects(\n\turl: string,\n\tcookieHeader: string,\n\tmaxRedirects: number,\n\tsignal: AbortSignal,\n): Promise<string> {\n\tlet current = url;\n\tconst allowedOrigin = new URL(url).origin;\n\tfor (let i = 0; i <= maxRedirects; i++) {\n\t\tconst res = await (await resolveGeminiFetch())(current, {\n\t\t\theaders: { \"user-agent\": USER_AGENT, cookie: cookieHeader },\n\t\t\tredirect: \"manual\",\n\t\t\tsignal,\n\t\t});\n\t\tif (res.status >= 300 && res.status < 400) {\n\t\t\tconst location = res.headers.get(\"location\");\n\t\t\tif (location) {\n\t\t\t\tconst next = new URL(location, current);\n\t\t\t\tif (next.origin !== allowedOrigin) {\n\t\t\t\t\tthrow new Error(`Refusing to send Google cookies across origins: ${allowedOrigin} -> ${next.origin}`);\n\t\t\t\t}\n\t\t\t\tcurrent = next.toString();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\treturn await res.text();\n\t}\n\tthrow new Error(`Too many redirects (>${maxRedirects})`);\n}\n\nfunction extractEmailFromGeminiHtml(html: string): string | null {\n\tconst patterns = [\n\t\t// Gemini bootstraps the active account in oPEP7c. Prefer it over generic\n\t\t// feature/config entries that may contain other signed-in Google accounts.\n\t\t/\"oPEP7c\"\\s*:\\s*\"([^\"]+)\"/,\n\t\t// The Google account menu aria-label is rendered for the active account.\n\t\t/aria-label=\"Google Account:[^\"]*?\\(([^)]+)\\)\"/,\n\t\t/\"displayEmail\"\\s*:\\s*\"([^\"]+)\"/,\n\t\t/\"defaultEmail\"\\s*:\\s*\"([^\"]+)\"/,\n\t\t/\"email\"\\s*:\\s*\"([^\"]+)\"/,\n\t\t/\"identifier\"\\s*:\\s*\"([^\"]+)\"/,\n\t\t/\"gaiaIdentifier\"\\s*:\\s*\"([^\"]+)\"/,\n\t];\n\n\tfor (const pattern of patterns) {\n\t\tconst match = html.match(pattern);\n\t\tconst email = normalizeEmail(match?.[1]);\n\t\tif (email) return email;\n\t}\n\n\treturn findFirstEmail(html);\n}\n\nfunction extractEmailFromListAccounts(text: string): string | null {\n\tconst trimmed = text.replace(/^\\)\\]\\}'\\s*/, \"\");\n\ttry {\n\t\treturn findEmailInValue(JSON.parse(trimmed)) ?? findFirstEmail(trimmed);\n\t} catch {\n\t\treturn findFirstEmail(trimmed);\n\t}\n}\n\nfunction findEmailInValue(value: unknown): string | null {\n\tif (typeof value === \"string\") return normalizeEmail(value);\n\tif (Array.isArray(value)) {\n\t\tfor (const item of value) {\n\t\t\tconst email = findEmailInValue(item);\n\t\t\tif (email) return email;\n\t\t}\n\t\treturn null;\n\t}\n\tif (value && typeof value === \"object\") {\n\t\tfor (const item of Object.values(value as Record<string, unknown>)) {\n\t\t\tconst email = findEmailInValue(item);\n\t\t\tif (email) return email;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction findFirstEmail(text: string): string | null {\n\tconst normalized = decodeEmailEscapes(text);\n\tconst match = normalized.match(/\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\b/i);\n\treturn match?.[0] ?? null;\n}\n\nfunction normalizeEmail(value: string | undefined): string | null {\n\tif (!value) return null;\n\tconst normalized = decodeEmailEscapes(value.trim());\n\treturn /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$/i.test(normalized) ? normalized : null;\n}\n\nfunction decodeEmailEscapes(value: string): string {\n\treturn value\n\t\t.replace(/\\\\u0040/gi, \"@\")\n\t\t.replace(/\\\\x40/gi, \"@\")\n\t\t.replace(/&#64;/gi, \"@\")\n\t\t.replace(/&commat;/gi, \"@\")\n\t\t.replace(/\\\\\"/g, \"\\\"\")\n\t\t.replace(/\\\\\\\\/g, \"\\\\\");\n}\n\nasync function uploadFile(\n\tfilePath: string,\n\tcookieHeader: string,\n\tsignal: AbortSignal,\n): Promise<{ id: string; name: string }> {\n\tconst data = readFileSync(filePath);\n\tconst fileName = basename(filePath);\n\tconst boundary = \"----FormBoundary\" + Math.random().toString(36).slice(2);\n\tconst header = `--${boundary}\\r\\nContent-Disposition: form-data; name=\"file\"; filename=\"${fileName}\"\\r\\nContent-Type: application/octet-stream\\r\\n\\r\\n`;\n\tconst footer = `\\r\\n--${boundary}--\\r\\n`;\n\n\tconst body = Buffer.concat([\n\t\tBuffer.from(header, \"utf-8\"),\n\t\tdata,\n\t\tBuffer.from(footer, \"utf-8\"),\n\t]);\n\n\tconst res = await (await resolveGeminiFetch())(GEMINI_UPLOAD_URL, {\n\t\tmethod: \"POST\",\n\t\tredirect: \"error\",\n\t\theaders: {\n\t\t\t\"content-type\": `multipart/form-data; boundary=${boundary}`,\n\t\t\t\"push-id\": GEMINI_UPLOAD_PUSH_ID,\n\t\t\t\"user-agent\": USER_AGENT,\n\t\t\tcookie: cookieHeader,\n\t\t},\n\t\tbody,\n\t\tsignal,\n\t});\n\n\tif (!res.ok) {\n\t\tconst text = await res.text();\n\t\tthrow new Error(`File upload failed: ${res.status} (${text.slice(0, 200)})`);\n\t}\n\n\treturn { id: await res.text(), name: fileName };\n}\n\nfunction buildFReqPayload(\n\tprompt: string,\n\tuploaded: Array<{ id: string; name: string }>,\n): string {\n\tconst promptPayload =\n\t\tuploaded.length > 0\n\t\t\t? [prompt, 0, null, uploaded.map((file) => [[file.id, 1]])]\n\t\t\t: [prompt];\n\tconst innerList = [promptPayload, null, null];\n\treturn JSON.stringify([null, JSON.stringify(innerList)]);\n}\n\nfunction withTimeout(signal: AbortSignal | undefined, timeoutMs: number): AbortSignal {\n\tconst timeout = AbortSignal.timeout(timeoutMs);\n\treturn signal ? AbortSignal.any([signal, timeout]) : timeout;\n}\n\nfunction buildCookieHeader(cookieMap: CookieMap): string {\n\treturn Object.entries(cookieMap)\n\t\t.filter(([, value]) => typeof value === \"string\" && value.length > 0)\n\t\t.map(([name, value]) => `${name}=${value}`)\n\t\t.join(\"; \");\n}\n\nfunction getNestedValue(value: unknown, pathParts: number[]): unknown {\n\tlet current: unknown = value;\n\tfor (const part of pathParts) {\n\t\tif (current == null) return undefined;\n\t\tif (!Array.isArray(current)) return undefined;\n\t\tcurrent = (current as unknown[])[part];\n\t}\n\treturn current;\n}\n\nfunction trimJsonEnvelope(text: string): string {\n\tconst start = text.indexOf(\"[\");\n\tconst end = text.lastIndexOf(\"]\");\n\tif (start === -1 || end === -1 || end <= start) {\n\t\tthrow new Error(\"Gemini response did not contain a JSON payload.\");\n\t}\n\treturn text.slice(start, end + 1);\n}\n\nfunction extractErrorCode(responseJson: unknown): number | undefined {\n\tconst code = getNestedValue(responseJson, [0, 5, 2, 0, 1, 0]);\n\treturn typeof code === \"number\" && code >= 0 ? code : undefined;\n}\n\nfunction extractCandidateText(candidate: unknown): string {\n\tconst textRaw = getNestedValue(candidate, [1, 0]);\n\tlet text = typeof textRaw === \"string\" ? textRaw : \"\";\n\n\tif (/^http:\\/\\/googleusercontent\\.com\\/card_content\\/\\d+/.test(text)) {\n\t\tconst alt = getNestedValue(candidate, [22, 0]);\n\t\tif (typeof alt === \"string\" && alt.length > 0) text = alt;\n\t}\n\n\treturn text;\n}\n\nfunction parseStreamGenerateResponse(rawText: string): GeminiWebResult {\n\tconst responseJson = JSON.parse(trimJsonEnvelope(rawText));\n\tconst errorCode = extractErrorCode(responseJson);\n\n\tconst parts = Array.isArray(responseJson) ? responseJson : [];\n\tlet firstCandidateSeen: unknown = undefined;\n\tlet latestNonEmptyText = \"\";\n\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst partBody = getNestedValue(parts[i], [2]);\n\t\tif (!partBody || typeof partBody !== \"string\") continue;\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(partBody);\n\t\t\tconst candidateList = getNestedValue(parsed, [4]);\n\t\t\tif (!Array.isArray(candidateList) || candidateList.length === 0) continue;\n\n\t\t\tconst firstCandidate = (candidateList as unknown[])[0];\n\t\t\tif (firstCandidateSeen === undefined) firstCandidateSeen = firstCandidate;\n\n\t\t\tconst text = extractCandidateText(firstCandidate);\n\t\t\tif (text.length > 0) latestNonEmptyText = text;\n\t\t} catch {\n\t\t}\n\t}\n\n\tconst text = latestNonEmptyText.length > 0\n\t\t? latestNonEmptyText\n\t\t: extractCandidateText(firstCandidateSeen);\n\n\treturn { text, errorCode };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"github-api.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/github-api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQzD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CASzD;AAED,wBAAgB,UAAU,IAAI,IAAI,CAKjC;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAavF;AA0FD,wBAAsB,WAAW,CAChC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,EACnB,QAAQ,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA0DlC","sourcesContent":["import { execFile } from \"node:child_process\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport type { GitHubUrlInfo } from \"./github-extract.ts\";\n\nconst MAX_TREE_ENTRIES = 200;\nconst MAX_INLINE_FILE_CHARS = 100_000;\n\nlet ghAvailable: boolean | null = null;\nlet ghHintShown = false;\n\nexport async function checkGhAvailable(): Promise<boolean> {\n\tif (ghAvailable !== null) return ghAvailable;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\"gh\", [\"--version\"], { timeout: 5000 }, (err) => {\n\t\t\tghAvailable = !err;\n\t\t\tresolve(ghAvailable);\n\t\t});\n\t});\n}\n\nexport function showGhHint(): void {\n\tif (!ghHintShown) {\n\t\tghHintShown = true;\n\t\tconsole.error(\"[pi-web-access] Install `gh` CLI for better GitHub repo access including private repos.\");\n\t}\n}\n\nexport async function checkRepoSize(owner: string, repo: string): Promise<number | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\"gh\", [\"api\", `repos/${owner}/${repo}`, \"--jq\", \".size\"], { timeout: 10000 }, (err, stdout) => {\n\t\t\tif (err) {\n\t\t\t\tresolve(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst kb = parseInt(stdout.trim(), 10);\n\t\t\tresolve(Number.isNaN(kb) ? null : kb);\n\t\t});\n\t});\n}\n\nasync function getDefaultBranch(owner: string, repo: string): Promise<string | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\"gh\", [\"api\", `repos/${owner}/${repo}`, \"--jq\", \".default_branch\"], { timeout: 10000 }, (err, stdout) => {\n\t\t\tif (err) {\n\t\t\t\tresolve(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst branch = stdout.trim();\n\t\t\tresolve(branch || null);\n\t\t});\n\t});\n}\n\nasync function fetchTreeViaApi(owner: string, repo: string, ref: string): Promise<string | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\n\t\t\t\"gh\",\n\t\t\t[\"api\", `repos/${owner}/${repo}/git/trees/${ref}?recursive=1`, \"--jq\", \".tree[].path\"],\n\t\t\t{ timeout: 15000, maxBuffer: 5 * 1024 * 1024 },\n\t\t\t(err, stdout) => {\n\t\t\t\tif (err) {\n\t\t\t\t\tresolve(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst paths = stdout.trim().split(\"\\n\").filter(Boolean);\n\t\t\t\tif (paths.length === 0) {\n\t\t\t\t\tresolve(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst truncated = paths.length > MAX_TREE_ENTRIES;\n\t\t\t\tconst display = paths.slice(0, MAX_TREE_ENTRIES).join(\"\\n\");\n\t\t\t\tresolve(truncated ? display + `\\n... (${paths.length} total entries)` : display);\n\t\t\t},\n\t\t);\n\t});\n}\n\nasync function fetchReadmeViaApi(owner: string, repo: string, ref: string): Promise<string | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\n\t\t\t\"gh\",\n\t\t\t[\"api\", `repos/${owner}/${repo}/readme?ref=${ref}`, \"--jq\", \".content\"],\n\t\t\t{ timeout: 10000 },\n\t\t\t(err, stdout) => {\n\t\t\t\tif (err) {\n\t\t\t\t\tresolve(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst decoded = Buffer.from(stdout.trim(), \"base64\").toString(\"utf-8\");\n\t\t\t\t\tresolve(decoded.length > 8192 ? decoded.slice(0, 8192) + \"\\n\\n[README truncated at 8K chars]\" : decoded);\n\t\t\t\t} catch {\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t});\n}\n\nasync function fetchFileViaApi(owner: string, repo: string, path: string, ref: string): Promise<string | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\n\t\t\t\"gh\",\n\t\t\t[\"api\", `repos/${owner}/${repo}/contents/${path}?ref=${ref}`, \"--jq\", \".content\"],\n\t\t\t{ timeout: 10000, maxBuffer: 2 * 1024 * 1024 },\n\t\t\t(err, stdout) => {\n\t\t\t\tif (err) {\n\t\t\t\t\tresolve(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tresolve(Buffer.from(stdout.trim(), \"base64\").toString(\"utf-8\"));\n\t\t\t\t} catch {\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport async function fetchViaApi(\n\turl: string,\n\towner: string,\n\trepo: string,\n\tinfo: GitHubUrlInfo,\n\tsizeNote?: string,\n): Promise<ExtractedContent | null> {\n\tconst ref = info.ref || (await getDefaultBranch(owner, repo));\n\tif (!ref) return null;\n\n\tconst lines: string[] = [];\n\tif (sizeNote) {\n\t\tlines.push(sizeNote);\n\t\tlines.push(\"\");\n\t}\n\n\tif (info.type === \"blob\" && info.path) {\n\t\tconst content = await fetchFileViaApi(owner, repo, info.path, ref);\n\t\tif (!content) return null;\n\n\t\tlines.push(`## ${info.path}`);\n\t\tif (content.length > MAX_INLINE_FILE_CHARS) {\n\t\t\tlines.push(content.slice(0, MAX_INLINE_FILE_CHARS));\n\t\t\tlines.push(`\\n[File truncated at 100K chars]`);\n\t\t} else {\n\t\t\tlines.push(content);\n\t\t}\n\n\t\treturn {\n\t\t\turl,\n\t\t\ttitle: `${owner}/${repo} - ${info.path}`,\n\t\t\tcontent: lines.join(\"\\n\"),\n\t\t\terror: null,\n\t\t};\n\t}\n\n\tconst [tree, readme] = await Promise.all([\n\t\tfetchTreeViaApi(owner, repo, ref),\n\t\tfetchReadmeViaApi(owner, repo, ref),\n\t]);\n\n\tif (!tree && !readme) return null;\n\n\tif (tree) {\n\t\tlines.push(\"## Structure\");\n\t\tlines.push(tree);\n\t\tlines.push(\"\");\n\t}\n\n\tif (readme) {\n\t\tlines.push(\"## README.md\");\n\t\tlines.push(readme);\n\t\tlines.push(\"\");\n\t}\n\n\tlines.push(\"This is an API-only view. Clone the repo or use `read`/`bash` for deeper exploration.\");\n\n\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\treturn {\n\t\turl,\n\t\ttitle,\n\t\tcontent: lines.join(\"\\n\"),\n\t\terror: null,\n\t};\n}\n"]}
1
+ {"version":3,"file":"github-api.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/github-api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQzD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CASzD;AAED,wBAAgB,UAAU,IAAI,IAAI,CAKjC;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAavF;AA0FD,wBAAsB,WAAW,CAChC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,EACnB,QAAQ,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA0DlC"}
@@ -1 +1 @@
1
- {"version":3,"file":"github-api.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/github-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport type { GitHubUrlInfo } from \"./github-extract.ts\";\n\nconst MAX_TREE_ENTRIES = 200;\nconst MAX_INLINE_FILE_CHARS = 100_000;\n\nlet ghAvailable: boolean | null = null;\nlet ghHintShown = false;\n\nexport async function checkGhAvailable(): Promise<boolean> {\n\tif (ghAvailable !== null) return ghAvailable;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\"gh\", [\"--version\"], { timeout: 5000 }, (err) => {\n\t\t\tghAvailable = !err;\n\t\t\tresolve(ghAvailable);\n\t\t});\n\t});\n}\n\nexport function showGhHint(): void {\n\tif (!ghHintShown) {\n\t\tghHintShown = true;\n\t\tconsole.error(\"[pi-web-access] Install `gh` CLI for better GitHub repo access including private repos.\");\n\t}\n}\n\nexport async function checkRepoSize(owner: string, repo: string): Promise<number | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\"gh\", [\"api\", `repos/${owner}/${repo}`, \"--jq\", \".size\"], { timeout: 10000 }, (err, stdout) => {\n\t\t\tif (err) {\n\t\t\t\tresolve(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst kb = parseInt(stdout.trim(), 10);\n\t\t\tresolve(Number.isNaN(kb) ? null : kb);\n\t\t});\n\t});\n}\n\nasync function getDefaultBranch(owner: string, repo: string): Promise<string | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\"gh\", [\"api\", `repos/${owner}/${repo}`, \"--jq\", \".default_branch\"], { timeout: 10000 }, (err, stdout) => {\n\t\t\tif (err) {\n\t\t\t\tresolve(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst branch = stdout.trim();\n\t\t\tresolve(branch || null);\n\t\t});\n\t});\n}\n\nasync function fetchTreeViaApi(owner: string, repo: string, ref: string): Promise<string | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\n\t\t\t\"gh\",\n\t\t\t[\"api\", `repos/${owner}/${repo}/git/trees/${ref}?recursive=1`, \"--jq\", \".tree[].path\"],\n\t\t\t{ timeout: 15000, maxBuffer: 5 * 1024 * 1024 },\n\t\t\t(err, stdout) => {\n\t\t\t\tif (err) {\n\t\t\t\t\tresolve(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst paths = stdout.trim().split(\"\\n\").filter(Boolean);\n\t\t\t\tif (paths.length === 0) {\n\t\t\t\t\tresolve(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst truncated = paths.length > MAX_TREE_ENTRIES;\n\t\t\t\tconst display = paths.slice(0, MAX_TREE_ENTRIES).join(\"\\n\");\n\t\t\t\tresolve(truncated ? display + `\\n... (${paths.length} total entries)` : display);\n\t\t\t},\n\t\t);\n\t});\n}\n\nasync function fetchReadmeViaApi(owner: string, repo: string, ref: string): Promise<string | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\n\t\t\t\"gh\",\n\t\t\t[\"api\", `repos/${owner}/${repo}/readme?ref=${ref}`, \"--jq\", \".content\"],\n\t\t\t{ timeout: 10000 },\n\t\t\t(err, stdout) => {\n\t\t\t\tif (err) {\n\t\t\t\t\tresolve(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst decoded = Buffer.from(stdout.trim(), \"base64\").toString(\"utf-8\");\n\t\t\t\t\tresolve(decoded.length > 8192 ? decoded.slice(0, 8192) + \"\\n\\n[README truncated at 8K chars]\" : decoded);\n\t\t\t\t} catch {\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t});\n}\n\nasync function fetchFileViaApi(owner: string, repo: string, path: string, ref: string): Promise<string | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\n\t\t\t\"gh\",\n\t\t\t[\"api\", `repos/${owner}/${repo}/contents/${path}?ref=${ref}`, \"--jq\", \".content\"],\n\t\t\t{ timeout: 10000, maxBuffer: 2 * 1024 * 1024 },\n\t\t\t(err, stdout) => {\n\t\t\t\tif (err) {\n\t\t\t\t\tresolve(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tresolve(Buffer.from(stdout.trim(), \"base64\").toString(\"utf-8\"));\n\t\t\t\t} catch {\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport async function fetchViaApi(\n\turl: string,\n\towner: string,\n\trepo: string,\n\tinfo: GitHubUrlInfo,\n\tsizeNote?: string,\n): Promise<ExtractedContent | null> {\n\tconst ref = info.ref || (await getDefaultBranch(owner, repo));\n\tif (!ref) return null;\n\n\tconst lines: string[] = [];\n\tif (sizeNote) {\n\t\tlines.push(sizeNote);\n\t\tlines.push(\"\");\n\t}\n\n\tif (info.type === \"blob\" && info.path) {\n\t\tconst content = await fetchFileViaApi(owner, repo, info.path, ref);\n\t\tif (!content) return null;\n\n\t\tlines.push(`## ${info.path}`);\n\t\tif (content.length > MAX_INLINE_FILE_CHARS) {\n\t\t\tlines.push(content.slice(0, MAX_INLINE_FILE_CHARS));\n\t\t\tlines.push(`\\n[File truncated at 100K chars]`);\n\t\t} else {\n\t\t\tlines.push(content);\n\t\t}\n\n\t\treturn {\n\t\t\turl,\n\t\t\ttitle: `${owner}/${repo} - ${info.path}`,\n\t\t\tcontent: lines.join(\"\\n\"),\n\t\t\terror: null,\n\t\t};\n\t}\n\n\tconst [tree, readme] = await Promise.all([\n\t\tfetchTreeViaApi(owner, repo, ref),\n\t\tfetchReadmeViaApi(owner, repo, ref),\n\t]);\n\n\tif (!tree && !readme) return null;\n\n\tif (tree) {\n\t\tlines.push(\"## Structure\");\n\t\tlines.push(tree);\n\t\tlines.push(\"\");\n\t}\n\n\tif (readme) {\n\t\tlines.push(\"## README.md\");\n\t\tlines.push(readme);\n\t\tlines.push(\"\");\n\t}\n\n\tlines.push(\"This is an API-only view. Clone the repo or use `read`/`bash` for deeper exploration.\");\n\n\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\treturn {\n\t\turl,\n\t\ttitle,\n\t\tcontent: lines.join(\"\\n\"),\n\t\terror: null,\n\t};\n}\n"]}
1
+ {"version":3,"file":"github-api.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/github-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport type { GitHubUrlInfo } from \"./github-extract.ts\";\n\nconst MAX_TREE_ENTRIES = 200;\nconst MAX_INLINE_FILE_CHARS = 100_000;\n\nlet ghAvailable: boolean | null = null;\nlet ghHintShown = false;\n\nexport async function checkGhAvailable(): Promise<boolean> {\n\tif (ghAvailable !== null) return ghAvailable;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\"gh\", [\"--version\"], { timeout: 5000 }, (err) => {\n\t\t\tghAvailable = !err;\n\t\t\tresolve(ghAvailable);\n\t\t});\n\t});\n}\n\nexport function showGhHint(): void {\n\tif (!ghHintShown) {\n\t\tghHintShown = true;\n\t\tconsole.error(\"[pi-web-access] Install `gh` CLI for better GitHub repo access including private repos.\");\n\t}\n}\n\nexport async function checkRepoSize(owner: string, repo: string): Promise<number | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\"gh\", [\"api\", `repos/${owner}/${repo}`, \"--jq\", \".size\"], { timeout: 10000 }, (err, stdout) => {\n\t\t\tif (err) {\n\t\t\t\tresolve(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst kb = parseInt(stdout.trim(), 10);\n\t\t\tresolve(Number.isNaN(kb) ? null : kb);\n\t\t});\n\t});\n}\n\nasync function getDefaultBranch(owner: string, repo: string): Promise<string | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\"gh\", [\"api\", `repos/${owner}/${repo}`, \"--jq\", \".default_branch\"], { timeout: 10000 }, (err, stdout) => {\n\t\t\tif (err) {\n\t\t\t\tresolve(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst branch = stdout.trim();\n\t\t\tresolve(branch || null);\n\t\t});\n\t});\n}\n\nasync function fetchTreeViaApi(owner: string, repo: string, ref: string): Promise<string | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\n\t\t\t\"gh\",\n\t\t\t[\"api\", `repos/${owner}/${repo}/git/trees/${ref}?recursive=1`, \"--jq\", \".tree[].path\"],\n\t\t\t{ timeout: 15000, maxBuffer: 5 * 1024 * 1024 },\n\t\t\t(err, stdout) => {\n\t\t\t\tif (err) {\n\t\t\t\t\tresolve(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst paths = stdout.trim().split(\"\\n\").filter(Boolean);\n\t\t\t\tif (paths.length === 0) {\n\t\t\t\t\tresolve(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst truncated = paths.length > MAX_TREE_ENTRIES;\n\t\t\t\tconst display = paths.slice(0, MAX_TREE_ENTRIES).join(\"\\n\");\n\t\t\t\tresolve(truncated ? display + `\\n... (${paths.length} total entries)` : display);\n\t\t\t},\n\t\t);\n\t});\n}\n\nasync function fetchReadmeViaApi(owner: string, repo: string, ref: string): Promise<string | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\n\t\t\t\"gh\",\n\t\t\t[\"api\", `repos/${owner}/${repo}/readme?ref=${ref}`, \"--jq\", \".content\"],\n\t\t\t{ timeout: 10000 },\n\t\t\t(err, stdout) => {\n\t\t\t\tif (err) {\n\t\t\t\t\tresolve(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst decoded = Buffer.from(stdout.trim(), \"base64\").toString(\"utf-8\");\n\t\t\t\t\tresolve(decoded.length > 8192 ? decoded.slice(0, 8192) + \"\\n\\n[README truncated at 8K chars]\" : decoded);\n\t\t\t\t} catch {\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t});\n}\n\nasync function fetchFileViaApi(owner: string, repo: string, path: string, ref: string): Promise<string | null> {\n\tif (!(await checkGhAvailable())) return null;\n\n\treturn new Promise((resolve) => {\n\t\texecFile(\n\t\t\t\"gh\",\n\t\t\t[\"api\", `repos/${owner}/${repo}/contents/${path}?ref=${ref}`, \"--jq\", \".content\"],\n\t\t\t{ timeout: 10000, maxBuffer: 2 * 1024 * 1024 },\n\t\t\t(err, stdout) => {\n\t\t\t\tif (err) {\n\t\t\t\t\tresolve(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tresolve(Buffer.from(stdout.trim(), \"base64\").toString(\"utf-8\"));\n\t\t\t\t} catch {\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport async function fetchViaApi(\n\turl: string,\n\towner: string,\n\trepo: string,\n\tinfo: GitHubUrlInfo,\n\tsizeNote?: string,\n): Promise<ExtractedContent | null> {\n\tconst ref = info.ref || (await getDefaultBranch(owner, repo));\n\tif (!ref) return null;\n\n\tconst lines: string[] = [];\n\tif (sizeNote) {\n\t\tlines.push(sizeNote);\n\t\tlines.push(\"\");\n\t}\n\n\tif (info.type === \"blob\" && info.path) {\n\t\tconst content = await fetchFileViaApi(owner, repo, info.path, ref);\n\t\tif (!content) return null;\n\n\t\tlines.push(`## ${info.path}`);\n\t\tif (content.length > MAX_INLINE_FILE_CHARS) {\n\t\t\tlines.push(content.slice(0, MAX_INLINE_FILE_CHARS));\n\t\t\tlines.push(`\\n[File truncated at 100K chars]`);\n\t\t} else {\n\t\t\tlines.push(content);\n\t\t}\n\n\t\treturn {\n\t\t\turl,\n\t\t\ttitle: `${owner}/${repo} - ${info.path}`,\n\t\t\tcontent: lines.join(\"\\n\"),\n\t\t\terror: null,\n\t\t};\n\t}\n\n\tconst [tree, readme] = await Promise.all([\n\t\tfetchTreeViaApi(owner, repo, ref),\n\t\tfetchReadmeViaApi(owner, repo, ref),\n\t]);\n\n\tif (!tree && !readme) return null;\n\n\tif (tree) {\n\t\tlines.push(\"## Structure\");\n\t\tlines.push(tree);\n\t\tlines.push(\"\");\n\t}\n\n\tif (readme) {\n\t\tlines.push(\"## README.md\");\n\t\tlines.push(readme);\n\t\tlines.push(\"\");\n\t}\n\n\tlines.push(\"This is an API-only view. Clone the repo or use `read`/`bash` for deeper exploration.\");\n\n\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\treturn {\n\t\turl,\n\t\ttitle,\n\t\tcontent: lines.join(\"\\n\"),\n\t\terror: null,\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"github-extract.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/github-extract.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AA2BrD,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAC/B;AA0FD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAiDhE;AAsaD,wBAAsB,aAAa,CAClC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAsGlC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAStC","sourcesContent":["import { existsSync, readFileSync, rmSync, statSync, readdirSync, openSync, readSync, closeSync, realpathSync } from \"node:fs\";\nimport { execFile, spawn, type ChildProcess } from \"node:child_process\";\nimport { extname, join, resolve as resolvePath, sep as pathSep } from \"node:path\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport { checkGhAvailable, checkRepoSize, fetchViaApi, showGhHint } from \"./github-api.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst CONFIG_PATH = getWebSearchConfigPath();\n\nconst BINARY_EXTENSIONS = new Set([\n\t\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\", \".ico\", \".webp\", \".svg\", \".tiff\", \".tif\",\n\t\".mp3\", \".mp4\", \".avi\", \".mov\", \".mkv\", \".flv\", \".wmv\", \".wav\", \".ogg\", \".webm\", \".flac\", \".aac\",\n\t\".zip\", \".tar\", \".gz\", \".bz2\", \".xz\", \".7z\", \".rar\", \".zst\",\n\t\".exe\", \".dll\", \".so\", \".dylib\", \".bin\", \".o\", \".a\", \".lib\",\n\t\".woff\", \".woff2\", \".ttf\", \".otf\", \".eot\",\n\t\".pdf\", \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\",\n\t\".sqlite\", \".db\", \".sqlite3\",\n\t\".pyc\", \".pyo\", \".class\", \".jar\", \".war\",\n\t\".iso\", \".img\", \".dmg\",\n]);\n\nconst NOISE_DIRS = new Set([\n\t\"node_modules\", \"vendor\", \".next\", \"dist\", \"build\", \"__pycache__\",\n\t\".venv\", \"venv\", \".tox\", \".mypy_cache\", \".pytest_cache\",\n\t\"target\", \".gradle\", \".idea\", \".vscode\",\n]);\n\nconst MAX_INLINE_FILE_CHARS = 100_000;\nconst MAX_TREE_ENTRIES = 200;\n\nexport interface GitHubUrlInfo {\n\towner: string;\n\trepo: string;\n\tref?: string;\n\trefIsFullSha: boolean;\n\tpath?: string;\n\ttype: \"root\" | \"blob\" | \"tree\";\n}\n\ninterface CachedClone {\n\tlocalPath: string;\n\tclonePromise: Promise<string | null>;\n}\n\ninterface GitHubCloneConfig {\n\tenabled: boolean;\n\tmaxRepoSizeMB: number;\n\tcloneTimeoutSeconds: number;\n\tclonePath: string;\n}\n\nconst cloneCache = new Map<string, CachedClone>();\n\nlet cachedConfig: GitHubCloneConfig | null = null;\n\nfunction normalizeEnabled(value: unknown, fallback: boolean): boolean {\n\treturn typeof value === \"boolean\" ? value : fallback;\n}\n\nfunction normalizePositiveNumber(value: unknown, fallback: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n\treturn value > 0 ? value : fallback;\n}\n\nfunction expandPath(value: string): string {\n\tlet expanded = value;\n\t// Expand ~ at the start of the path\n\tif (expanded.startsWith(\"~/\") || expanded === \"~\") {\n\t\texpanded = expanded.replace(/^~/, process.env.HOME || process.env.USERPROFILE || \"\");\n\t}\n\t// Expand environment variables like $HOME, $USER, etc.\n\texpanded = expanded.replace(/\\$([A-Z_][A-Z0-9_]*)/gi, (match, varName) => {\n\t\treturn process.env[varName] ?? match;\n\t});\n\treturn expanded;\n}\n\nfunction normalizeClonePath(value: unknown, fallback: string): string {\n\tif (typeof value !== \"string\") return fallback;\n\tconst normalized = value.trim();\n\tif (normalized.length === 0) return fallback;\n\treturn expandPath(normalized);\n}\n\nfunction loadGitHubConfig(): GitHubCloneConfig {\n\tif (cachedConfig) return cachedConfig;\n\n\tconst defaults: GitHubCloneConfig = {\n\t\tenabled: true,\n\t\tmaxRepoSizeMB: 350,\n\t\tcloneTimeoutSeconds: 30,\n\t\tclonePath: \"/tmp/pi-github-repos\",\n\t};\n\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = defaults;\n\t\treturn cachedConfig;\n\t}\n\n\tconst rawText = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet raw: { githubClone?: { enabled?: unknown; maxRepoSizeMB?: unknown; cloneTimeoutSeconds?: unknown; clonePath?: unknown } };\n\ttry {\n\t\traw = JSON.parse(rawText) as { githubClone?: { enabled?: unknown; maxRepoSizeMB?: unknown; cloneTimeoutSeconds?: unknown; clonePath?: unknown } };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\n\tconst gc = raw.githubClone ?? {};\n\tcachedConfig = {\n\t\tenabled: normalizeEnabled(gc.enabled, defaults.enabled),\n\t\tmaxRepoSizeMB: normalizePositiveNumber(gc.maxRepoSizeMB, defaults.maxRepoSizeMB),\n\t\tcloneTimeoutSeconds: normalizePositiveNumber(gc.cloneTimeoutSeconds, defaults.cloneTimeoutSeconds),\n\t\tclonePath: normalizeClonePath(gc.clonePath, defaults.clonePath),\n\t};\n\treturn cachedConfig;\n}\n\nconst NON_CODE_SEGMENTS = new Set([\n\t\"issues\", \"pull\", \"pulls\", \"discussions\", \"releases\", \"wiki\",\n\t\"actions\", \"settings\", \"security\", \"projects\", \"graphs\",\n\t\"compare\", \"commits\", \"tags\", \"branches\", \"stargazers\",\n\t\"watchers\", \"network\", \"forks\", \"milestone\", \"labels\",\n\t\"packages\", \"codespaces\", \"contribute\", \"community\",\n\t\"sponsors\", \"invitations\", \"notifications\", \"insights\",\n]);\n\nexport function parseGitHubUrl(url: string): GitHubUrlInfo | null {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(url);\n\t} catch {\n\t\treturn null;\n\t}\n\n\tconst host = parsed.hostname.toLowerCase();\n\tif (host !== \"github.com\" && host !== \"www.github.com\") return null;\n\n\tconst segments = parsed.pathname\n\t\t.split(\"/\")\n\t\t.filter(Boolean)\n\t\t.map((segment) => {\n\t\t\ttry {\n\t\t\t\treturn decodeURIComponent(segment);\n\t\t\t} catch {\n\t\t\t\treturn segment;\n\t\t\t}\n\t\t});\n\tif (segments.length < 2) return null;\n\n\tconst owner = segments[0];\n\tconst repo = segments[1].replace(/\\.git$/, \"\");\n\n\tif (NON_CODE_SEGMENTS.has(segments[2]?.toLowerCase())) return null;\n\n\tif (segments.length === 2) {\n\t\treturn { owner, repo, refIsFullSha: false, type: \"root\" };\n\t}\n\n\tconst action = segments[2];\n\tif (action !== \"blob\" && action !== \"tree\") return null;\n\tif (segments.length < 4) return null;\n\n\tconst ref = segments[3];\n\tconst refIsFullSha = /^[0-9a-f]{40}$/.test(ref);\n\tconst pathParts = segments.slice(4);\n\tconst path = pathParts.length > 0 ? pathParts.join(\"/\") : \"\";\n\n\treturn {\n\t\towner,\n\t\trepo,\n\t\tref,\n\t\trefIsFullSha,\n\t\tpath,\n\t\ttype: action as \"blob\" | \"tree\",\n\t};\n}\n\nfunction cacheKey(owner: string, repo: string, ref?: string): string {\n\treturn ref ? `${owner}/${repo}@${ref}` : `${owner}/${repo}`;\n}\n\nfunction cloneDir(config: GitHubCloneConfig, owner: string, repo: string, ref?: string): string {\n\tconst dirName = ref ? `${repo}@${ref}` : repo;\n\treturn join(config.clonePath, owner, dirName);\n}\n\nconst PROCESS_KILL_GRACE_MS = 3000;\n\nfunction terminateProcessTree(child: ChildProcess): void {\n\tconst pid = child.pid;\n\tif (!pid) return;\n\n\tif (process.platform === \"win32\") {\n\t\tconst killer = execFile(\n\t\t\t\"taskkill\",\n\t\t\t[\"/pid\", String(pid), \"/T\", \"/F\"],\n\t\t\t{ windowsHide: true },\n\t\t\t(err) => {\n\t\t\t\tif (err) child.kill();\n\t\t\t},\n\t\t);\n\t\tkiller.unref();\n\t\treturn;\n\t}\n\n\ttry {\n\t\t// Clone commands run in their own process group so git/gh helpers cannot\n\t\t// survive a timeout or cancellation and keep reading from the host TTY.\n\t\tprocess.kill(-pid, \"SIGTERM\");\n\t} catch {\n\t\tchild.kill();\n\t}\n\n\t// A credential helper may handle or ignore SIGTERM. Escalate against the\n\t// entire process group so neither git nor any descendant can block forever.\n\tconst forceKill = setTimeout(() => {\n\t\ttry {\n\t\t\tprocess.kill(-pid, \"SIGKILL\");\n\t\t} catch {\n\t\t\tchild.kill(\"SIGKILL\");\n\t\t}\n\t}, PROCESS_KILL_GRACE_MS);\n\tforceKill.unref();\n}\n\nfunction execClone(args: string[], localPath: string, timeoutMs: number, signal?: AbortSignal): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tlet timeout: ReturnType<typeof setTimeout> | undefined;\n\t\tlet onAbort: (() => void) | undefined;\n\n\t\tconst finish = (success: boolean) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tif (timeout) clearTimeout(timeout);\n\t\t\tif (signal && onAbort) signal.removeEventListener(\"abort\", onAbort);\n\n\t\t\tif (!success) {\n\t\t\t\ttry {\n\t\t\t\t\trmSync(localPath, { recursive: true, force: true });\n\t\t\t\t} catch {\n\t\t\t\t}\n\t\t\t\tresolve(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(localPath);\n\t\t};\n\n\t\tconst child = spawn(args[0], args.slice(1), {\n\t\t\tdetached: process.platform !== \"win32\",\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\tGIT_TERMINAL_PROMPT: \"0\",\n\t\t\t\tGCM_INTERACTIVE: \"Never\",\n\t\t\t\tGH_PROMPT_DISABLED: \"1\",\n\t\t\t},\n\t\t\tstdio: \"ignore\",\n\t\t\twindowsHide: true,\n\t\t});\n\n\t\tchild.once(\"error\", () => finish(false));\n\t\tchild.once(\"close\", (code) => finish(code === 0));\n\n\t\ttimeout = setTimeout(() => terminateProcessTree(child), timeoutMs);\n\t\ttimeout.unref();\n\n\t\tif (signal) {\n\t\t\tonAbort = () => {\n\t\t\t\tif (timeout) clearTimeout(timeout);\n\t\t\t\tterminateProcessTree(child);\n\t\t\t};\n\t\t\tif (signal.aborted) onAbort();\n\t\t\telse signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t}\n\t});\n}\n\nasync function cloneRepo(\n\towner: string,\n\trepo: string,\n\tref: string | undefined,\n\tconfig: GitHubCloneConfig,\n\tsignal?: AbortSignal,\n): Promise<string | null> {\n\tconst localPath = cloneDir(config, owner, repo, ref);\n\n\ttry {\n\t\trmSync(localPath, { recursive: true, force: true });\n\t} catch {\n\t}\n\n\tconst timeoutMs = config.cloneTimeoutSeconds * 1000;\n\tconst hasGh = await checkGhAvailable();\n\n\tif (hasGh) {\n\t\tconst args = [\"gh\", \"repo\", \"clone\", `${owner}/${repo}`, localPath, \"--\", \"--depth\", \"1\", \"--single-branch\"];\n\t\tif (ref) args.push(\"--branch\", ref);\n\t\treturn execClone(args, localPath, timeoutMs, signal);\n\t}\n\n\tshowGhHint();\n\n\tconst gitUrl = `https://github.com/${owner}/${repo}.git`;\n\tconst args = [\"git\", \"clone\", \"--depth\", \"1\", \"--single-branch\"];\n\tif (ref) args.push(\"--branch\", ref);\n\targs.push(gitUrl, localPath);\n\treturn execClone(args, localPath, timeoutMs, signal);\n}\n\nfunction isBinaryFile(filePath: string): boolean {\n\tconst ext = extname(filePath).toLowerCase();\n\tif (BINARY_EXTENSIONS.has(ext)) return true;\n\n\tlet fd: number;\n\ttry {\n\t\tfd = openSync(filePath, \"r\");\n\t} catch {\n\t\treturn false;\n\t}\n\ttry {\n\t\tconst buf = Buffer.alloc(512);\n\t\tconst bytesRead = readSync(fd, buf, 0, 512, 0);\n\t\tfor (let i = 0; i < bytesRead; i++) {\n\t\t\tif (buf[i] === 0) return true;\n\t\t}\n\t} catch {\n\t\treturn false;\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\n\treturn false;\n}\n\nfunction formatFileSize(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction resolveWithinRepo(rootPath: string, relativePath: string): string | null {\n\tconst normalizedRoot = resolvePath(rootPath);\n\tconst candidate = resolvePath(normalizedRoot, relativePath);\n\tif (candidate !== normalizedRoot) {\n\t\tconst rootPrefix = normalizedRoot.endsWith(pathSep) ? normalizedRoot : normalizedRoot + pathSep;\n\t\tif (!candidate.startsWith(rootPrefix)) return null;\n\t}\n\n\tif (!existsSync(candidate)) return candidate;\n\n\ttry {\n\t\tconst realRoot = realpathSync(normalizedRoot);\n\t\tconst realCandidate = realpathSync(candidate);\n\t\tif (realCandidate === realRoot) return candidate;\n\t\tconst realRootPrefix = realRoot.endsWith(pathSep) ? realRoot : realRoot + pathSep;\n\t\treturn realCandidate.startsWith(realRootPrefix) ? candidate : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction readTextFile(path: string): string | null {\n\ttry {\n\t\treturn readFileSync(path, \"utf-8\");\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction buildTree(rootPath: string): string {\n\tconst entries: string[] = [];\n\n\tfunction walk(dir: string, relPath: string): void {\n\t\tif (entries.length >= MAX_TREE_ENTRIES) return;\n\n\t\tlet items: string[];\n\t\ttry {\n\t\t\titems = readdirSync(dir).sort();\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const item of items) {\n\t\t\tif (entries.length >= MAX_TREE_ENTRIES) return;\n\t\t\tif (item === \".git\") continue;\n\n\t\t\tconst rel = relPath ? `${relPath}/${item}` : item;\n\t\t\tconst safePath = resolveWithinRepo(rootPath, rel);\n\t\t\tif (!safePath) {\n\t\t\t\tentries.push(`${rel} [outside repo skipped]`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet stat;\n\t\t\ttry {\n\t\t\t\tstat = statSync(safePath);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (stat.isDirectory()) {\n\t\t\t\tif (NOISE_DIRS.has(item)) {\n\t\t\t\t\tentries.push(`${rel}/ [skipped]`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tentries.push(`${rel}/`);\n\t\t\t\twalk(safePath, rel);\n\t\t\t} else {\n\t\t\t\tentries.push(rel);\n\t\t\t}\n\t\t}\n\t}\n\n\twalk(rootPath, \"\");\n\n\tif (entries.length >= MAX_TREE_ENTRIES) {\n\t\tentries.push(`... (truncated at ${MAX_TREE_ENTRIES} entries)`);\n\t}\n\n\treturn entries.join(\"\\n\");\n}\n\nfunction buildDirListing(rootPath: string, subPath: string): string {\n\tconst targetPath = resolveWithinRepo(rootPath, subPath);\n\tif (!targetPath) return \"(path escapes repository root)\";\n\tconst lines: string[] = [];\n\n\tlet items: string[];\n\ttry {\n\t\titems = readdirSync(targetPath).sort();\n\t} catch {\n\t\treturn \"(directory not readable)\";\n\t}\n\n\tfor (const item of items) {\n\t\tif (item === \".git\") continue;\n\t\tconst rel = subPath ? `${subPath}/${item}` : item;\n\t\tconst safePath = resolveWithinRepo(rootPath, rel);\n\t\tif (!safePath) {\n\t\t\tlines.push(` ${item} (outside repo)`);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst stat = statSync(safePath);\n\t\t\tif (stat.isDirectory()) {\n\t\t\t\tlines.push(` ${item}/`);\n\t\t\t} else {\n\t\t\t\tlines.push(` ${item} (${formatFileSize(stat.size)})`);\n\t\t\t}\n\t\t} catch {\n\t\t\tlines.push(` ${item} (unreadable)`);\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nfunction readReadme(localPath: string): string | null {\n\tconst candidates = [\"README.md\", \"readme.md\", \"README\", \"README.txt\", \"README.rst\"];\n\tfor (const name of candidates) {\n\t\tconst readmePath = join(localPath, name);\n\t\tif (existsSync(readmePath)) {\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(readmePath, \"utf-8\");\n\t\t\t\treturn content.length > 8192 ? content.slice(0, 8192) + \"\\n\\n[README truncated at 8K chars]\" : content;\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction generateContent(localPath: string, info: GitHubUrlInfo): string {\n\tconst lines: string[] = [];\n\tlines.push(`Repository cloned to: ${localPath}`);\n\tlines.push(\"\");\n\n\tif (info.type === \"root\") {\n\t\tlines.push(\"## Structure\");\n\t\tlines.push(buildTree(localPath));\n\t\tlines.push(\"\");\n\n\t\tconst readme = readReadme(localPath);\n\t\tif (readme) {\n\t\t\tlines.push(\"## README.md\");\n\t\t\tlines.push(readme);\n\t\t\tlines.push(\"\");\n\t\t}\n\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tif (info.type === \"tree\") {\n\t\tconst dirPath = info.path || \"\";\n\t\tconst fullDirPath = resolveWithinRepo(localPath, dirPath);\n\n\t\tif (!fullDirPath || !existsSync(fullDirPath)) {\n\t\t\tlines.push(`Path \\`${dirPath}\\` not found in clone. Showing repository root instead.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"## Structure\");\n\t\t\tlines.push(buildTree(localPath));\n\t\t} else {\n\t\t\tlines.push(`## ${dirPath || \"/\"}`);\n\t\t\tlines.push(buildDirListing(localPath, dirPath));\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tif (info.type === \"blob\") {\n\t\tconst filePath = info.path || \"\";\n\t\tconst fullFilePath = resolveWithinRepo(localPath, filePath);\n\n\t\tif (!fullFilePath || !existsSync(fullFilePath)) {\n\t\t\tlines.push(`Path \\`${filePath}\\` not found in clone. Showing repository root instead.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"## Structure\");\n\t\t\tlines.push(buildTree(localPath));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tlet stat: ReturnType<typeof statSync>;\n\t\ttry {\n\t\t\tstat = statSync(fullFilePath);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\tlines.push(`Could not inspect \\`${filePath}\\`: ${message}`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tif (stat.isDirectory()) {\n\t\t\tlines.push(`## ${filePath || \"/\"}`);\n\t\t\tlines.push(buildDirListing(localPath, filePath));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tif (isBinaryFile(fullFilePath)) {\n\t\t\tconst ext = extname(filePath).replace(\".\", \"\");\n\t\t\tlines.push(`## ${filePath}`);\n\t\t\tlines.push(`Binary file (${ext}, ${formatFileSize(stat.size)}). Use \\`read\\` or \\`bash\\` tools at the path above to inspect.`);\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\n\t\tconst content = readTextFile(fullFilePath);\n\t\tif (content === null) {\n\t\t\tlines.push(`Could not read \\`${filePath}\\` as UTF-8 text.`);\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\t\treturn lines.join(\"\\n\");\n\t\t}\n\t\tlines.push(`## ${filePath}`);\n\n\t\tif (content.length > MAX_INLINE_FILE_CHARS) {\n\t\t\tlines.push(content.slice(0, MAX_INLINE_FILE_CHARS));\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(`[File truncated at 100K chars. Full file: ${fullFilePath}]`);\n\t\t} else {\n\t\t\tlines.push(content);\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tlines.push(\"Use `read` and `bash` tools at the path above to explore further.\");\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nasync function awaitCachedClone(\n\tcached: CachedClone,\n\turl: string,\n\towner: string,\n\trepo: string,\n\tinfo: GitHubUrlInfo,\n\tsignal?: AbortSignal,\n): Promise<ExtractedContent | null> {\n\tif (signal?.aborted) return null;\n\tconst result = await cached.clonePromise;\n\tif (signal?.aborted) return null;\n\tif (result) {\n\t\tconst content = generateContent(result, info);\n\t\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\t\treturn { url, title, content, error: null };\n\t}\n\treturn fetchViaApi(url, owner, repo, info);\n}\n\nexport async function extractGitHub(\n\turl: string,\n\tsignal?: AbortSignal,\n\tforceClone?: boolean,\n): Promise<ExtractedContent | null> {\n\tconst info = parseGitHubUrl(url);\n\tif (!info) return null;\n\n\tif (signal?.aborted) return null;\n\n\tconst config = loadGitHubConfig();\n\tif (!config.enabled) return null;\n\n\tconst { owner, repo } = info;\n\tconst key = cacheKey(owner, repo, info.ref);\n\n\tconst cached = cloneCache.get(key);\n\tif (cached) return awaitCachedClone(cached, url, owner, repo, info, signal);\n\n\tif (info.refIsFullSha) {\n\t\tif (signal?.aborted) return null;\n\t\tconst sizeNote = `Note: Commit SHA URLs use the GitHub API instead of cloning.`;\n\t\treturn fetchViaApi(url, owner, repo, info, sizeNote);\n\t}\n\n\tconst activityId = activityMonitor.logStart({ type: \"fetch\", url: `github.com/${owner}/${repo}` });\n\n\tif (!forceClone) {\n\t\tconst sizeKB = await checkRepoSize(owner, repo);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\treturn null;\n\t\t}\n\t\tif (sizeKB !== null) {\n\t\t\tconst sizeMB = sizeKB / 1024;\n\t\t\tif (sizeMB > config.maxRepoSizeMB) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst sizeNote =\n\t\t\t\t\t`Note: Repository is ${Math.round(sizeMB)}MB (threshold: ${config.maxRepoSizeMB}MB). ` +\n\t\t\t\t\t`Showing API-fetched content instead of full clone. Ask the user if they'd like to clone the full repo -- ` +\n\t\t\t\t\t`if yes, call fetch_content again with the same URL and add forceClone: true to the params.`;\n\t\t\t\tconst apiView = await fetchViaApi(url, owner, repo, info, sizeNote);\n\t\t\t\tif (apiView) {\n\t\t\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\t\t\treturn apiView;\n\t\t\t\t}\n\t\t\t\tactivityMonitor.logError(activityId, \"api fallback unavailable for oversized repository\");\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (signal?.aborted) {\n\t\tactivityMonitor.logComplete(activityId, 0);\n\t\treturn null;\n\t}\n\n\t// Re-check: another concurrent caller may have started a clone while we awaited the size check\n\tconst cachedAfterSizeCheck = cloneCache.get(key);\n\tif (cachedAfterSizeCheck) {\n\t\tconst cachedResult = await awaitCachedClone(cachedAfterSizeCheck, url, owner, repo, info, signal);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t} else if (cachedResult) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t} else {\n\t\t\tactivityMonitor.logError(activityId, \"clone failed\");\n\t\t}\n\t\treturn cachedResult;\n\t}\n\n\tconst clonePromise = cloneRepo(owner, repo, info.ref, config, signal);\n\tconst localPath = cloneDir(config, owner, repo, info.ref);\n\tcloneCache.set(key, { localPath, clonePromise });\n\n\tconst result = await clonePromise;\n\tif (signal?.aborted) {\n\t\tif (!result) cloneCache.delete(key);\n\t\tactivityMonitor.logComplete(activityId, 0);\n\t\treturn null;\n\t}\n\n\tif (!result) {\n\t\tcloneCache.delete(key);\n\t\tif (signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst apiFallback = await fetchViaApi(url, owner, repo, info);\n\t\tif (apiFallback) {\n\t\t\tactivityMonitor.logComplete(activityId, 200);\n\t\t\treturn apiFallback;\n\t\t}\n\n\t\tactivityMonitor.logError(activityId, \"clone and API fallback failed\");\n\t\treturn null;\n\t}\n\n\tactivityMonitor.logComplete(activityId, 200);\n\tconst content = generateContent(result, info);\n\tconst title = info.path ? `${owner}/${repo} - ${info.path}` : `${owner}/${repo}`;\n\treturn { url, title, content, error: null };\n}\n\nexport function clearCloneCache(): void {\n\tfor (const entry of cloneCache.values()) {\n\t\ttry {\n\t\t\trmSync(entry.localPath, { recursive: true, force: true });\n\t\t} catch {\n\t\t}\n\t}\n\tcloneCache.clear();\n\tcachedConfig = null;\n}\n"]}
1
+ {"version":3,"file":"github-extract.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/github-extract.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AA2BrD,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAC/B;AA+FD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAmDhE;AAwbD,wBAAsB,aAAa,CAClC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA4GlC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAMtC"}
@@ -1,6 +1,7 @@
1
- import { existsSync, readFileSync, rmSync, statSync, readdirSync, openSync, readSync, closeSync, realpathSync } from "node:fs";
1
+ import { closeSync, existsSync, lstatSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, realpathSync, rmSync, statSync, unlinkSync } from "node:fs";
2
2
  import { execFile, spawn } from "node:child_process";
3
- import { extname, join, resolve as resolvePath, sep as pathSep } from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ import { basename, dirname, extname, join, resolve as resolvePath, sep as pathSep } from "node:path";
4
5
  import { activityMonitor } from "./activity.js";
5
6
  import { checkGhAvailable, checkRepoSize, fetchViaApi, showGhHint } from "./github-api.js";
6
7
  import { getWebSearchConfigPath } from "./utils.js";
@@ -103,21 +104,25 @@ export function parseGitHubUrl(url) {
103
104
  const host = parsed.hostname.toLowerCase();
104
105
  if (host !== "github.com" && host !== "www.github.com")
105
106
  return null;
106
- const segments = parsed.pathname
107
- .split("/")
108
- .filter(Boolean)
109
- .map((segment) => {
107
+ const segments = [];
108
+ for (const segment of parsed.pathname.split("/").filter(Boolean)) {
110
109
  try {
111
- return decodeURIComponent(segment);
110
+ segments.push(decodeURIComponent(segment));
112
111
  }
113
112
  catch {
114
- return segment;
113
+ return null;
115
114
  }
116
- });
115
+ }
117
116
  if (segments.length < 2)
118
117
  return null;
119
118
  const owner = segments[0];
120
119
  const repo = segments[1].replace(/\.git$/, "");
120
+ if (!/^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/.test(owner))
121
+ return null;
122
+ if (owner.includes("--"))
123
+ return null;
124
+ if (!/^[A-Za-z0-9._-]{1,100}$/.test(repo) || repo === "." || repo === "..")
125
+ return null;
121
126
  if (NON_CODE_SEGMENTS.has(segments[2]?.toLowerCase()))
122
127
  return null;
123
128
  if (segments.length === 2) {
@@ -129,6 +134,8 @@ export function parseGitHubUrl(url) {
129
134
  if (segments.length < 4)
130
135
  return null;
131
136
  const ref = segments[3];
137
+ if (ref.length === 0 || ref.length > 1024 || /[\0-\x1f\x7f]/.test(ref))
138
+ return null;
132
139
  const refIsFullSha = /^[0-9a-f]{40}$/.test(ref);
133
140
  const pathParts = segments.slice(4);
134
141
  const path = pathParts.length > 0 ? pathParts.join("/") : "";
@@ -144,9 +151,38 @@ export function parseGitHubUrl(url) {
144
151
  function cacheKey(owner, repo, ref) {
145
152
  return ref ? `${owner}/${repo}@${ref}` : `${owner}/${repo}`;
146
153
  }
147
- function cloneDir(config, owner, repo, ref) {
148
- const dirName = ref ? `${repo}@${ref}` : repo;
149
- return join(config.clonePath, owner, dirName);
154
+ function cloneDestination(config, owner, repo, ref) {
155
+ try {
156
+ mkdirSync(resolvePath(config.clonePath), { recursive: true });
157
+ const rootPath = realpathSync(resolvePath(config.clonePath));
158
+ const digest = createHash("sha256").update(JSON.stringify([owner, repo, ref ?? null])).digest("hex");
159
+ const localPath = resolvePath(rootPath, digest);
160
+ if (dirname(localPath) !== rootPath)
161
+ return null;
162
+ return { rootPath, localPath };
163
+ }
164
+ catch {
165
+ return null;
166
+ }
167
+ }
168
+ function removeCloneDestination(destination) {
169
+ const rootPath = resolvePath(destination.rootPath);
170
+ const localPath = resolvePath(destination.localPath);
171
+ if (dirname(localPath) !== rootPath || !/^[0-9a-f]{64}$/.test(basename(localPath)))
172
+ return false;
173
+ try {
174
+ const entry = lstatSync(localPath);
175
+ if (entry.isSymbolicLink())
176
+ unlinkSync(localPath);
177
+ else
178
+ rmSync(localPath, { recursive: true, force: true });
179
+ return true;
180
+ }
181
+ catch (err) {
182
+ if (err && typeof err === "object" && "code" in err && err.code === "ENOENT")
183
+ return true;
184
+ return false;
185
+ }
150
186
  }
151
187
  const PROCESS_KILL_GRACE_MS = 3000;
152
188
  function terminateProcessTree(child) {
@@ -181,8 +217,9 @@ function terminateProcessTree(child) {
181
217
  }, PROCESS_KILL_GRACE_MS);
182
218
  forceKill.unref();
183
219
  }
184
- function execClone(args, localPath, timeoutMs, signal) {
220
+ function execClone(args, destination, timeoutMs, signal) {
185
221
  return new Promise((resolve) => {
222
+ const { localPath } = destination;
186
223
  let settled = false;
187
224
  let timeout;
188
225
  let onAbort;
@@ -195,11 +232,7 @@ function execClone(args, localPath, timeoutMs, signal) {
195
232
  if (signal && onAbort)
196
233
  signal.removeEventListener("abort", onAbort);
197
234
  if (!success) {
198
- try {
199
- rmSync(localPath, { recursive: true, force: true });
200
- }
201
- catch {
202
- }
235
+ removeCloneDestination(destination);
203
236
  resolve(null);
204
237
  return;
205
238
  }
@@ -233,20 +266,17 @@ function execClone(args, localPath, timeoutMs, signal) {
233
266
  }
234
267
  });
235
268
  }
236
- async function cloneRepo(owner, repo, ref, config, signal) {
237
- const localPath = cloneDir(config, owner, repo, ref);
238
- try {
239
- rmSync(localPath, { recursive: true, force: true });
240
- }
241
- catch {
242
- }
269
+ async function cloneRepo(owner, repo, ref, config, destination, signal) {
270
+ const { localPath } = destination;
271
+ if (!removeCloneDestination(destination))
272
+ return null;
243
273
  const timeoutMs = config.cloneTimeoutSeconds * 1000;
244
274
  const hasGh = await checkGhAvailable();
245
275
  if (hasGh) {
246
276
  const args = ["gh", "repo", "clone", `${owner}/${repo}`, localPath, "--", "--depth", "1", "--single-branch"];
247
277
  if (ref)
248
278
  args.push("--branch", ref);
249
- return execClone(args, localPath, timeoutMs, signal);
279
+ return execClone(args, destination, timeoutMs, signal);
250
280
  }
251
281
  showGhHint();
252
282
  const gitUrl = `https://github.com/${owner}/${repo}.git`;
@@ -254,7 +284,7 @@ async function cloneRepo(owner, repo, ref, config, signal) {
254
284
  if (ref)
255
285
  args.push("--branch", ref);
256
286
  args.push(gitUrl, localPath);
257
- return execClone(args, localPath, timeoutMs, signal);
287
+ return execClone(args, destination, timeoutMs, signal);
258
288
  }
259
289
  function isBinaryFile(filePath) {
260
290
  const ext = extname(filePath).toLowerCase();
@@ -592,9 +622,17 @@ export async function extractGitHub(url, signal, forceClone) {
592
622
  }
593
623
  return cachedResult;
594
624
  }
595
- const clonePromise = cloneRepo(owner, repo, info.ref, config, signal);
596
- const localPath = cloneDir(config, owner, repo, info.ref);
597
- cloneCache.set(key, { localPath, clonePromise });
625
+ const destination = cloneDestination(config, owner, repo, info.ref);
626
+ if (!destination) {
627
+ const apiFallback = await fetchViaApi(url, owner, repo, info);
628
+ if (apiFallback)
629
+ activityMonitor.logComplete(activityId, 200);
630
+ else
631
+ activityMonitor.logError(activityId, "invalid clone destination");
632
+ return apiFallback;
633
+ }
634
+ const clonePromise = cloneRepo(owner, repo, info.ref, config, destination, signal);
635
+ cloneCache.set(key, { destination, clonePromise });
598
636
  const result = await clonePromise;
599
637
  if (signal?.aborted) {
600
638
  if (!result)
@@ -623,11 +661,7 @@ export async function extractGitHub(url, signal, forceClone) {
623
661
  }
624
662
  export function clearCloneCache() {
625
663
  for (const entry of cloneCache.values()) {
626
- try {
627
- rmSync(entry.localPath, { recursive: true, force: true });
628
- }
629
- catch {
630
- }
664
+ removeCloneDestination(entry.destination);
631
665
  }
632
666
  cloneCache.clear();
633
667
  cachedConfig = null;