@herbertgao/pi-extensions 2026.8.10 → 2026.8.12

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 (566) hide show
  1. package/README.md +18 -11
  2. package/{node_modules/@herbertgao/pi-inline-skills/LICENSE → THIRD_PARTY_NOTICES.md} +15 -1
  3. package/node_modules/@czottmann/pi-automode/CHANGELOG.md +15 -0
  4. package/node_modules/@czottmann/pi-automode/README.md +5 -3
  5. package/node_modules/@czottmann/pi-automode/docs/adr/ADR-001-permission-precedence-and-trust-boundaries.md +2 -0
  6. package/node_modules/@czottmann/pi-automode/docs/adr/ADR-002-global-config-in-extension-data-directory.md +60 -0
  7. package/node_modules/@czottmann/pi-automode/docs/adr/INDEX.md +1 -0
  8. package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +4 -4
  9. package/node_modules/@czottmann/pi-automode/docs/configuration.md +20 -4
  10. package/node_modules/@czottmann/pi-automode/docs/observability-logging.md +1 -1
  11. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/bash.ts +692 -0
  12. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +181 -3
  13. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +4 -1
  14. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +143 -36
  15. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +103 -148
  16. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +32 -6
  17. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +344 -22
  18. package/node_modules/@czottmann/pi-automode/extensions/auto-mode.ts +1 -0
  19. package/node_modules/@czottmann/pi-automode/package.json +4 -1
  20. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -1
  21. package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -1
  22. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +4 -0
  23. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +21 -1
  24. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +1 -1
  25. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +19 -19
  26. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +4 -2
  27. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +2 -1
  28. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +10 -2
  29. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  30. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +10 -0
  31. package/node_modules/@herbertgao/pi-subagents/README.md +21 -15
  32. package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
  33. package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +11 -8
  34. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +184 -106
  35. package/node_modules/@herbertgao/pi-subagents/src/cross-extension-rpc.ts +31 -11
  36. package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +9 -1
  37. package/node_modules/@herbertgao/pi-subagents/src/index.ts +156 -31
  38. package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +17 -0
  39. package/node_modules/@herbertgao/pi-subagents/src/model-resolver.ts +14 -0
  40. package/node_modules/@herbertgao/pi-subagents/src/schedule.ts +8 -0
  41. package/node_modules/@herbertgao/pi-subagents/src/settings.ts +32 -1
  42. package/node_modules/@herbertgao/pi-subagents/src/types.ts +17 -2
  43. package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +23 -2
  44. package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +259 -24
  45. package/node_modules/{resume-from → @herbertgao/resume-from}/README.md +10 -8
  46. package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/reader.js +11 -2
  47. package/node_modules/{resume-from → @herbertgao/resume-from}/package.json +24 -10
  48. package/node_modules/{resume-from → @herbertgao/resume-from}/shims/pi/extensions/resume-from.js +2 -2
  49. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  50. package/node_modules/@narumitw/pi-btw/dist/index.ts +143 -46
  51. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
  52. package/node_modules/@narumitw/pi-btw/package.json +6 -6
  53. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +136 -22
  54. package/node_modules/{@herbertgao → @tifan}/pi-copy-response/README.md +2 -4
  55. package/node_modules/{@herbertgao → @tifan}/pi-copy-response/package.json +5 -15
  56. package/node_modules/{@herbertgao → @tifan}/pi-handoff/README.md +4 -6
  57. package/node_modules/@tifan/pi-handoff/package.json +43 -0
  58. package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/index.ts +1 -1
  59. package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/README.md +2 -4
  60. package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/package.json +5 -15
  61. package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/README.md +5 -7
  62. package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/package.json +5 -19
  63. package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/README.md +4 -6
  64. package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/package.json +6 -16
  65. package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/src/index.ts +1 -6
  66. package/node_modules/{@herbertgao → @tifan}/pi-recap/README.md +4 -6
  67. package/node_modules/@tifan/pi-recap/package.json +42 -0
  68. package/node_modules/{@herbertgao → @tifan}/pi-recap/src/models.ts +1 -6
  69. package/node_modules/{@herbertgao → @tifan}/pi-rename/README.md +13 -8
  70. package/node_modules/@tifan/pi-rename/package.json +47 -0
  71. package/node_modules/@tifan/pi-rename/src/herdr-label.ts +4 -0
  72. package/node_modules/{@herbertgao → @tifan}/pi-rename/src/index.ts +4 -16
  73. package/node_modules/{@herbertgao → @tifan}/pi-rename/src/models.ts +1 -6
  74. package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/README.md +2 -4
  75. package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/package.json +5 -15
  76. package/node_modules/pi-lens/CHANGELOG.md +96 -1
  77. package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -1
  78. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +14 -5
  79. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +48 -18
  80. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +1 -3
  81. package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +16 -4
  82. package/node_modules/pi-lens/dist/clients/bash-file-access.js +3 -1
  83. package/node_modules/pi-lens/dist/clients/biome-client.js +1 -3
  84. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +21 -8
  85. package/node_modules/pi-lens/dist/clients/bounded-cache.js +24 -8
  86. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +4 -3
  87. package/node_modules/pi-lens/dist/clients/cache-manager.js +6 -7
  88. package/node_modules/pi-lens/dist/clients/cache-observability.js +461 -66
  89. package/node_modules/pi-lens/dist/clients/call-graph.js +238 -63
  90. package/node_modules/pi-lens/dist/clients/codebase-model.js +13 -5
  91. package/node_modules/pi-lens/dist/clients/complexity-client.js +1 -3
  92. package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -8
  93. package/node_modules/pi-lens/dist/clients/dead-code-logger.js +1 -2
  94. package/node_modules/pi-lens/dist/clients/deadline-utils.js +3 -1
  95. package/node_modules/pi-lens/dist/clients/debug-heap.js +8 -1
  96. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +1 -1
  97. package/node_modules/pi-lens/dist/clients/dependency-checker.js +11 -7
  98. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +39 -2
  99. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +5 -1
  100. package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +2 -3
  101. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +13 -1
  102. package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +3 -1
  103. package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +2 -1
  104. package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +1 -1
  105. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +9 -4
  106. package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +3 -1
  107. package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +6 -2
  108. package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +31 -7
  109. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +5 -2
  110. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +10 -14
  111. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +5 -1
  112. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +1 -1
  113. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +3 -1
  114. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +25 -6
  115. package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +1 -1
  116. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +1 -1
  117. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +3 -1
  118. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +13 -8
  119. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +4 -1
  120. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +25 -10
  121. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +1 -1
  122. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +1 -1
  123. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +1 -1
  124. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +28 -4
  125. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +6 -8
  126. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +212 -11
  127. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +1 -1
  128. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +8 -4
  129. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +10 -6
  130. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +23 -14
  131. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -1
  132. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +7 -9
  133. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +5 -2
  134. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +7 -7
  135. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +6 -8
  136. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +13 -8
  137. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +13 -8
  138. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +17 -3
  139. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +7 -1
  140. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +24 -1
  141. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +35 -0
  142. package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +1 -3
  143. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +6 -8
  144. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +1 -1
  145. package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +2 -1
  146. package/node_modules/pi-lens/dist/clients/dispatch/types.js +6 -1
  147. package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +6 -2
  148. package/node_modules/pi-lens/dist/clients/extension-log.js +5 -3
  149. package/node_modules/pi-lens/dist/clients/feature-hints.js +8 -1
  150. package/node_modules/pi-lens/dist/clients/file-kinds.js +34 -129
  151. package/node_modules/pi-lens/dist/clients/file-utils.js +17 -1
  152. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +57 -2
  153. package/node_modules/pi-lens/dist/clients/formatters.js +144 -27
  154. package/node_modules/pi-lens/dist/clients/freshness.js +38 -0
  155. package/node_modules/pi-lens/dist/clients/git-guard.js +43 -13
  156. package/node_modules/pi-lens/dist/clients/go-client.js +1 -3
  157. package/node_modules/pi-lens/dist/clients/grammar-source.js +1 -1
  158. package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +30 -4
  159. package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +1 -3
  160. package/node_modules/pi-lens/dist/clients/install-diagnostics.js +4 -2
  161. package/node_modules/pi-lens/dist/clients/installer/index.js +86 -77
  162. package/node_modules/pi-lens/dist/clients/instance-reaper.js +5 -2
  163. package/node_modules/pi-lens/dist/clients/instance-registry.js +4 -2
  164. package/node_modules/pi-lens/dist/clients/jscpd-client.js +6 -1
  165. package/node_modules/pi-lens/dist/clients/knip-client.js +29 -15
  166. package/node_modules/pi-lens/dist/clients/language-profile.js +4 -1
  167. package/node_modules/pi-lens/dist/clients/latency-logger.js +13 -2
  168. package/node_modules/pi-lens/dist/clients/lens-config.js +1 -1
  169. package/node_modules/pi-lens/dist/clients/lens-map.js +8 -3
  170. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +1 -1
  171. package/node_modules/pi-lens/dist/clients/lsp/config.js +4 -6
  172. package/node_modules/pi-lens/dist/clients/lsp/edits.js +119 -32
  173. package/node_modules/pi-lens/dist/clients/lsp/index.js +94 -35
  174. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +2 -1
  175. package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +4 -1
  176. package/node_modules/pi-lens/dist/clients/lsp/launch.js +11 -3
  177. package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +152 -0
  178. package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -7
  179. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +10 -2
  180. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +9 -4
  181. package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -3
  182. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +10 -20
  183. package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +1 -1
  184. package/node_modules/pi-lens/dist/clients/memory-sampler.js +73 -7
  185. package/node_modules/pi-lens/dist/clients/metrics-client.js +1 -3
  186. package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +8 -3
  187. package/node_modules/pi-lens/dist/clients/module-report-lsp.js +7 -1
  188. package/node_modules/pi-lens/dist/clients/module-report.js +14 -17
  189. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +3 -5
  190. package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +220 -0
  191. package/node_modules/pi-lens/dist/clients/package-manager.js +6 -1
  192. package/node_modules/pi-lens/dist/clients/pipeline.js +57 -9
  193. package/node_modules/pi-lens/dist/clients/project-conventions.js +2 -8
  194. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +10 -7
  195. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +2 -1
  196. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +3 -1
  197. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +13 -9
  198. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +3 -1
  199. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -2
  200. package/node_modules/pi-lens/dist/clients/project-lens-config.js +12 -5
  201. package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +48 -0
  202. package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +15 -1
  203. package/node_modules/pi-lens/dist/clients/project-snapshot.js +472 -66
  204. package/node_modules/pi-lens/dist/clients/read-expansion.js +12 -2
  205. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +5 -4
  206. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +5 -2
  207. package/node_modules/pi-lens/dist/clients/read-guard.js +1 -1
  208. package/node_modules/pi-lens/dist/clients/resource-sampler.js +1 -1
  209. package/node_modules/pi-lens/dist/clients/reverse-deps.js +6 -5
  210. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +42 -17
  211. package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +8 -2
  212. package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +10 -1
  213. package/node_modules/pi-lens/dist/clients/review-graph/query.js +2 -1
  214. package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +4 -2
  215. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +2 -2
  216. package/node_modules/pi-lens/dist/clients/ruff-client.js +6 -5
  217. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +63 -31
  218. package/node_modules/pi-lens/dist/clients/runtime-context.js +12 -4
  219. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +83 -4
  220. package/node_modules/pi-lens/dist/clients/runtime-session.js +14 -0
  221. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +59 -3
  222. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +148 -34
  223. package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -6
  224. package/node_modules/pi-lens/dist/clients/rust-client.js +1 -3
  225. package/node_modules/pi-lens/dist/clients/safe-spawn.js +150 -11
  226. package/node_modules/pi-lens/dist/clients/security-scan-client.js +1 -3
  227. package/node_modules/pi-lens/dist/clients/session-summary.js +3 -1
  228. package/node_modules/pi-lens/dist/clients/sg-runner.js +1 -3
  229. package/node_modules/pi-lens/dist/clients/source-filter.js +10 -6
  230. package/node_modules/pi-lens/dist/clients/source-walker.js +1 -1
  231. package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +96 -0
  232. package/node_modules/pi-lens/dist/clients/startup-scan.js +4 -1
  233. package/node_modules/pi-lens/dist/clients/tool-definition.js +7 -0
  234. package/node_modules/pi-lens/dist/clients/tool-policy.js +26 -11
  235. package/node_modules/pi-lens/dist/clients/tool-render.js +2 -1
  236. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +10 -4
  237. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
  238. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +12 -5
  239. package/node_modules/pi-lens/dist/clients/warm-attach.js +12 -5
  240. package/node_modules/pi-lens/dist/clients/widget-state.js +27 -11
  241. package/node_modules/pi-lens/dist/clients/word-index.js +3 -1
  242. package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -2
  243. package/node_modules/pi-lens/dist/clients/zizmor-config.js +9 -1
  244. package/node_modules/pi-lens/dist/i18n.js +13 -5
  245. package/node_modules/pi-lens/dist/index.js +10797 -8627
  246. package/node_modules/pi-lens/dist/mcp/server.js +3 -1
  247. package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +68 -12
  248. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +21 -7
  249. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +164 -35
  250. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +24 -7
  251. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +3 -1
  252. package/node_modules/pi-lens/dist/tools/module-report.js +1 -1
  253. package/node_modules/pi-lens/dist/tools/project-report.js +1 -1
  254. package/node_modules/pi-lens/dist/tools/symbol-search.js +5 -2
  255. package/node_modules/pi-lens/docs/durable-store-audit-1202.md +1 -1
  256. package/node_modules/pi-lens/docs/servercapabilities.md +1 -1
  257. package/node_modules/pi-lens/package.json +160 -156
  258. package/node_modules/pi-lens/rules/typos/_typos.toml +2 -2
  259. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +31 -13
  260. package/node_modules/pi-lens/scripts/download-grammars.js +9 -3
  261. package/node_modules/pi-lens/scripts/rpc-load-check.mjs +30 -9
  262. package/node_modules/pi-mcp-adapter/CHANGELOG.md +34 -0
  263. package/node_modules/pi-mcp-adapter/README.md +42 -13
  264. package/node_modules/pi-mcp-adapter/commands.ts +4 -2
  265. package/node_modules/pi-mcp-adapter/config.ts +35 -5
  266. package/node_modules/pi-mcp-adapter/direct-tools.ts +103 -92
  267. package/node_modules/pi-mcp-adapter/dist/agent-dir.d.ts +10 -0
  268. package/node_modules/pi-mcp-adapter/dist/agent-dir.js +63 -0
  269. package/node_modules/pi-mcp-adapter/dist/agent-dir.js.map +1 -0
  270. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.d.ts +8 -0
  271. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js +356 -0
  272. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js.map +1 -0
  273. package/node_modules/pi-mcp-adapter/dist/config.d.ts +123 -0
  274. package/node_modules/pi-mcp-adapter/dist/config.js +1077 -0
  275. package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -0
  276. package/node_modules/pi-mcp-adapter/dist/metadata-cache.d.ts +19 -0
  277. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +319 -0
  278. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +1 -0
  279. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.d.ts +2 -0
  280. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js +156 -0
  281. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js.map +1 -0
  282. package/node_modules/pi-mcp-adapter/dist/resource-tools.d.ts +1 -0
  283. package/node_modules/pi-mcp-adapter/dist/resource-tools.js +15 -0
  284. package/node_modules/pi-mcp-adapter/dist/resource-tools.js.map +1 -0
  285. package/node_modules/pi-mcp-adapter/dist/types.d.ts +564 -0
  286. package/node_modules/pi-mcp-adapter/dist/types.js +287 -0
  287. package/node_modules/pi-mcp-adapter/dist/types.js.map +1 -0
  288. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.d.ts +6 -0
  289. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js +37 -0
  290. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js.map +1 -0
  291. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.d.ts +104 -0
  292. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js +59 -0
  293. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js.map +1 -0
  294. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.d.ts +4 -0
  295. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js +27 -0
  296. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js.map +1 -0
  297. package/node_modules/pi-mcp-adapter/dist/utils.d.ts +32 -0
  298. package/node_modules/pi-mcp-adapter/dist/utils.js +338 -0
  299. package/node_modules/pi-mcp-adapter/dist/utils.js.map +1 -0
  300. package/node_modules/pi-mcp-adapter/failure-backoff.ts +23 -0
  301. package/node_modules/pi-mcp-adapter/index.ts +204 -82
  302. package/node_modules/pi-mcp-adapter/init.ts +36 -29
  303. package/node_modules/pi-mcp-adapter/lifecycle.ts +16 -8
  304. package/node_modules/pi-mcp-adapter/mcp-code.ts +2 -0
  305. package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +66 -16
  306. package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +95 -7
  307. package/node_modules/pi-mcp-adapter/mcp-probe.ts +18 -4
  308. package/node_modules/pi-mcp-adapter/mcp-references.ts +368 -0
  309. package/node_modules/pi-mcp-adapter/mcp-status.ts +8 -19
  310. package/node_modules/pi-mcp-adapter/metadata-cache.ts +20 -12
  311. package/node_modules/pi-mcp-adapter/namespace-tools.ts +276 -0
  312. package/node_modules/pi-mcp-adapter/package.json +24 -6
  313. package/node_modules/pi-mcp-adapter/proxy-modes.ts +66 -10
  314. package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -0
  315. package/node_modules/pi-mcp-adapter/server-manager.ts +63 -12
  316. package/node_modules/pi-mcp-adapter/state.ts +1 -3
  317. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +16 -2
  318. package/node_modules/pi-mcp-adapter/types.ts +48 -1
  319. package/node_modules/pi-mcp-adapter/ui-server.ts +3 -19
  320. package/node_modules/pi-mcp-adapter/ui-session.ts +2 -1
  321. package/node_modules/pi-mcp-adapter/utils.ts +21 -19
  322. package/node_modules/pi-web-access/CHANGELOG.md +26 -0
  323. package/node_modules/pi-web-access/README.md +71 -14
  324. package/node_modules/pi-web-access/chrome-cookies.ts +115 -35
  325. package/node_modules/pi-web-access/credential-source.ts +6 -2
  326. package/node_modules/pi-web-access/curator-page.ts +5 -3
  327. package/node_modules/pi-web-access/curator-server.ts +2 -1
  328. package/node_modules/pi-web-access/extract.ts +89 -9
  329. package/node_modules/pi-web-access/fetch-params.ts +13 -0
  330. package/node_modules/pi-web-access/gemini-adc.ts +298 -0
  331. package/node_modules/pi-web-access/gemini-api.ts +59 -15
  332. package/node_modules/pi-web-access/gemini-search.ts +58 -18
  333. package/node_modules/pi-web-access/gemini-url-context.ts +3 -2
  334. package/node_modules/pi-web-access/gemini-web-config.ts +57 -7
  335. package/node_modules/pi-web-access/gemini-web.ts +9 -3
  336. package/node_modules/pi-web-access/github-api.ts +5 -4
  337. package/node_modules/pi-web-access/github-issue-pr.ts +700 -0
  338. package/node_modules/pi-web-access/index.ts +403 -297
  339. package/node_modules/pi-web-access/kimi-search.ts +234 -0
  340. package/node_modules/pi-web-access/openai-search.ts +118 -21
  341. package/node_modules/pi-web-access/package.json +3 -2
  342. package/node_modules/pi-web-access/ssrf-protection.ts +4 -1
  343. package/node_modules/pi-web-access/utils.ts +307 -1
  344. package/node_modules/pi-web-access/youtube-extract.ts +2 -2
  345. package/package.json +44 -41
  346. package/node_modules/@herbertgao/pi-copy-response/CHANGELOG.md +0 -49
  347. package/node_modules/@herbertgao/pi-copy-response/LICENSE +0 -22
  348. package/node_modules/@herbertgao/pi-handoff/CHANGELOG.md +0 -83
  349. package/node_modules/@herbertgao/pi-handoff/LICENSE +0 -22
  350. package/node_modules/@herbertgao/pi-handoff/package.json +0 -60
  351. package/node_modules/@herbertgao/pi-inline-skills/CHANGELOG.md +0 -57
  352. package/node_modules/@herbertgao/pi-mermaid-open/CHANGELOG.md +0 -39
  353. package/node_modules/@herbertgao/pi-mermaid-open/LICENSE +0 -22
  354. package/node_modules/@herbertgao/pi-preferred-thinking/CHANGELOG.md +0 -63
  355. package/node_modules/@herbertgao/pi-preferred-thinking/LICENSE +0 -22
  356. package/node_modules/@herbertgao/pi-recap/CHANGELOG.md +0 -101
  357. package/node_modules/@herbertgao/pi-recap/LICENSE +0 -22
  358. package/node_modules/@herbertgao/pi-recap/package.json +0 -55
  359. package/node_modules/@herbertgao/pi-rename/CHANGELOG.md +0 -49
  360. package/node_modules/@herbertgao/pi-rename/LICENSE +0 -22
  361. package/node_modules/@herbertgao/pi-rename/package.json +0 -63
  362. package/node_modules/@herbertgao/pi-titlebar-spinner/CHANGELOG.md +0 -25
  363. package/node_modules/@herbertgao/pi-titlebar-spinner/LICENSE +0 -22
  364. /package/node_modules/{resume-from → @herbertgao/resume-from}/LICENSE +0 -0
  365. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/adapter.d.ts +0 -0
  366. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/adapter.js +0 -0
  367. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/contract.d.ts +0 -0
  368. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/contract.js +0 -0
  369. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/entries.d.ts +0 -0
  370. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/entries.js +0 -0
  371. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/index.d.ts +0 -0
  372. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/index.js +0 -0
  373. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/layout.d.ts +0 -0
  374. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/layout.js +0 -0
  375. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/readback.d.ts +0 -0
  376. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/readback.js +0 -0
  377. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/reader.d.ts +0 -0
  378. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/redaction.d.ts +0 -0
  379. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/redaction.js +0 -0
  380. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/validation.d.ts +0 -0
  381. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/validation.js +0 -0
  382. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/writer.d.ts +0 -0
  383. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/claude-code/writer.js +0 -0
  384. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/contract.d.ts +0 -0
  385. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/contract.js +0 -0
  386. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/index.d.ts +0 -0
  387. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/index.js +0 -0
  388. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/read.d.ts +0 -0
  389. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/read.js +0 -0
  390. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/readback.d.ts +0 -0
  391. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/readback.js +0 -0
  392. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/redaction.d.ts +0 -0
  393. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/redaction.js +0 -0
  394. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/rollout.d.ts +0 -0
  395. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/rollout.js +0 -0
  396. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/validation.d.ts +0 -0
  397. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/validation.js +0 -0
  398. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/write.d.ts +0 -0
  399. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/codex/write.js +0 -0
  400. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/contract.d.ts +0 -0
  401. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/contract.js +0 -0
  402. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/adapter.d.ts +0 -0
  403. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/adapter.js +0 -0
  404. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/contract.d.ts +0 -0
  405. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/contract.js +0 -0
  406. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/format.d.ts +0 -0
  407. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/format.js +0 -0
  408. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/index.d.ts +0 -0
  409. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/index.js +0 -0
  410. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/parse.d.ts +0 -0
  411. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/parse.js +0 -0
  412. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/redaction.d.ts +0 -0
  413. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/redaction.js +0 -0
  414. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/serialize.d.ts +0 -0
  415. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/serialize.js +0 -0
  416. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/validate.d.ts +0 -0
  417. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/adapters/pi/validate.js +0 -0
  418. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/bin.d.ts +0 -0
  419. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/bin.js +0 -0
  420. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/contract.d.ts +0 -0
  421. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/contract.js +0 -0
  422. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/agents.d.ts +0 -0
  423. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/agents.js +0 -0
  424. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/cli/args.d.ts +0 -0
  425. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/cli/args.js +0 -0
  426. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/cli/contract.d.ts +0 -0
  427. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/cli/contract.js +0 -0
  428. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/cli/index.d.ts +0 -0
  429. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/cli/index.js +0 -0
  430. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/cli/presentation.d.ts +0 -0
  431. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/cli/presentation.js +0 -0
  432. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/cli/render.d.ts +0 -0
  433. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/cli/render.js +0 -0
  434. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/cli/runner.d.ts +0 -0
  435. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/cli/runner.js +0 -0
  436. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/contract.d.ts +0 -0
  437. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/contract.js +0 -0
  438. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/entry.d.ts +0 -0
  439. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/entry.js +0 -0
  440. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/index.d.ts +0 -0
  441. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/index.js +0 -0
  442. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/command.d.ts +0 -0
  443. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/command.js +0 -0
  444. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/contract.d.ts +0 -0
  445. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/contract.js +0 -0
  446. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/index.d.ts +0 -0
  447. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/index.js +0 -0
  448. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/picker.d.ts +0 -0
  449. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/picker.js +0 -0
  450. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/presentation.d.ts +0 -0
  451. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/presentation.js +0 -0
  452. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/register.d.ts +0 -0
  453. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/register.js +0 -0
  454. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/ui.d.ts +0 -0
  455. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/pi-extension/ui.js +0 -0
  456. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/profile.d.ts +0 -0
  457. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/profile.js +0 -0
  458. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/registry.d.ts +0 -0
  459. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/registry.js +0 -0
  460. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/wiring.d.ts +0 -0
  461. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/host/wiring.js +0 -0
  462. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/confirmation.d.ts +0 -0
  463. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/confirmation.js +0 -0
  464. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/contract.d.ts +0 -0
  465. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/contract.js +0 -0
  466. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/discovery/contract.d.ts +0 -0
  467. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/discovery/contract.js +0 -0
  468. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/discovery/errors.d.ts +0 -0
  469. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/discovery/errors.js +0 -0
  470. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/discovery/finder.d.ts +0 -0
  471. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/discovery/finder.js +0 -0
  472. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/discovery/homes.d.ts +0 -0
  473. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/discovery/homes.js +0 -0
  474. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/discovery/index.d.ts +0 -0
  475. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/discovery/index.js +0 -0
  476. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/discovery/ordering.d.ts +0 -0
  477. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/discovery/ordering.js +0 -0
  478. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/errors.d.ts +0 -0
  479. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/errors.js +0 -0
  480. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/index.d.ts +0 -0
  481. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/index.js +0 -0
  482. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/landing/contract.d.ts +0 -0
  483. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/landing/contract.js +0 -0
  484. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/landing/errors.d.ts +0 -0
  485. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/landing/errors.js +0 -0
  486. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/landing/handover.d.ts +0 -0
  487. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/landing/handover.js +0 -0
  488. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/landing/index.d.ts +0 -0
  489. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/landing/index.js +0 -0
  490. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/landing/lander.d.ts +0 -0
  491. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/landing/lander.js +0 -0
  492. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/landing/marker.d.ts +0 -0
  493. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/landing/marker.js +0 -0
  494. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/pipeline.d.ts +0 -0
  495. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/pipeline.js +0 -0
  496. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/preview/builder.d.ts +0 -0
  497. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/preview/builder.js +0 -0
  498. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/preview/contract.d.ts +0 -0
  499. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/preview/contract.js +0 -0
  500. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/preview/format.d.ts +0 -0
  501. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/preview/format.js +0 -0
  502. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/preview/index.d.ts +0 -0
  503. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/preview/index.js +0 -0
  504. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/preview/warnings.d.ts +0 -0
  505. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/preview/warnings.js +0 -0
  506. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/transfer/contract.d.ts +0 -0
  507. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/transfer/contract.js +0 -0
  508. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/transfer/index.d.ts +0 -0
  509. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/transfer/index.js +0 -0
  510. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/transfer/rules.d.ts +0 -0
  511. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/transfer/rules.js +0 -0
  512. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/wiring.d.ts +0 -0
  513. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/import/wiring.js +0 -0
  514. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/index.d.ts +0 -0
  515. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/index.js +0 -0
  516. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/contract.d.ts +0 -0
  517. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/contract.js +0 -0
  518. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/defaults.d.ts +0 -0
  519. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/defaults.js +0 -0
  520. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/errors.d.ts +0 -0
  521. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/errors.js +0 -0
  522. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/index.d.ts +0 -0
  523. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/index.js +0 -0
  524. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/loader.d.ts +0 -0
  525. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/loader.js +0 -0
  526. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/paths.d.ts +0 -0
  527. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/paths.js +0 -0
  528. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/validate.d.ts +0 -0
  529. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/config/validate.js +0 -0
  530. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/repo/contract.d.ts +0 -0
  531. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/repo/contract.js +0 -0
  532. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/repo/git.d.ts +0 -0
  533. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/repo/git.js +0 -0
  534. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/repo/index.d.ts +0 -0
  535. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/repo/index.js +0 -0
  536. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/repo/reader.d.ts +0 -0
  537. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/repo/reader.js +0 -0
  538. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/store/contract.d.ts +0 -0
  539. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/store/contract.js +0 -0
  540. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/store/file-committer.d.ts +0 -0
  541. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/store/file-committer.js +0 -0
  542. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/store/index.d.ts +0 -0
  543. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/store/index.js +0 -0
  544. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/tokens/contract.d.ts +0 -0
  545. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/tokens/contract.js +0 -0
  546. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/tokens/estimator.d.ts +0 -0
  547. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/tokens/estimator.js +0 -0
  548. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/tokens/index.d.ts +0 -0
  549. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/platform/tokens/index.js +0 -0
  550. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/session/contract.d.ts +0 -0
  551. /package/node_modules/{resume-from → @herbertgao/resume-from}/dist/session/contract.js +0 -0
  552. /package/node_modules/{@herbertgao → @tifan}/pi-copy-response/src/index.ts +0 -0
  553. /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/complete-text.ts +0 -0
  554. /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/session-query.ts +0 -0
  555. /package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/src/index.ts +0 -0
  556. /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/herdr-plugin.toml +0 -0
  557. /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/viewer.mjs +0 -0
  558. /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/src/index.ts +0 -0
  559. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/index.ts +0 -0
  560. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/model-picker.ts +0 -0
  561. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/sanitize.ts +0 -0
  562. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/tui.ts +0 -0
  563. /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/model-picker.ts +0 -0
  564. /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/naming.ts +0 -0
  565. /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/sanitize.ts +0 -0
  566. /package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/src/index.ts +0 -0
@@ -0,0 +1,700 @@
1
+ import { execFile } from "node:child_process";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import type { ExtractedContent, ExtractOptions } from "./extract.ts";
4
+ import { checkGhAvailable, showGhHint } from "./github-api.ts";
5
+ import { fetchRemoteUrl, loadFetchContentDomainPolicy, loadSsrfConfig } from "./ssrf-protection.ts";
6
+ import { getWebSearchConfigPath } from "./utils.ts";
7
+
8
+ const CONFIG_PATH = getWebSearchConfigPath();
9
+ const GH_TIMEOUT_MS = 10_000;
10
+ const GH_TOTAL_TIMEOUT_MS = 20_000;
11
+ const MAX_DOC_CHARS = 150_000;
12
+ const BODY_INLINE_CHARS = 4_000;
13
+ const COMMENT_INLINE_CHARS = 700;
14
+ const MAX_INLINE_COMMENTS = 15;
15
+ const MAX_INLINE_REVIEWS = 10;
16
+ const MAX_INLINE_CHECKS = 15;
17
+ const MAX_INLINE_FILES = 50;
18
+ const MAX_INLINE_COMMITS = 20;
19
+ const MAX_INLINE_REVIEW_THREADS = 30;
20
+ const REST_HEADERS = { "Accept": "application/vnd.github+json", "User-Agent": "pi-web-access" };
21
+ const PR_SUBPATHS = new Set(["files", "commits", "checks", "conversation"]);
22
+
23
+ const PR_FIELDS = [
24
+ "title", "number", "state", "isDraft", "author", "baseRefName", "headRefName", "headRepositoryOwner",
25
+ "createdAt", "mergedAt", "closedAt", "labels", "milestone", "additions", "deletions", "changedFiles",
26
+ "files", "commits", "reviews", "statusCheckRollup", "comments", "body", "closingIssuesReferences", "url",
27
+ ];
28
+ const PR_CORE_FIELDS = [
29
+ "title", "number", "state", "isDraft", "author", "baseRefName", "headRefName", "headRepositoryOwner",
30
+ "createdAt", "mergedAt", "closedAt", "labels", "milestone", "additions", "deletions", "changedFiles",
31
+ "files", "commits", "reviews", "comments", "body", "url",
32
+ ];
33
+ const ISSUE_FIELDS = [
34
+ "title", "number", "state", "stateReason", "author", "createdAt", "closedAt", "labels", "assignees", "milestone",
35
+ "comments", "body", "closedByPullRequestsReferences", "url",
36
+ ];
37
+ const ISSUE_CORE_FIELDS = ["title", "number", "state", "author", "createdAt", "closedAt", "labels", "assignees", "milestone", "comments", "body", "url"];
38
+
39
+ type Kind = "pull" | "issue";
40
+
41
+ export interface GitHubIssuePrUrlInfo {
42
+ owner: string;
43
+ repo: string;
44
+ kind: Kind;
45
+ number: number;
46
+ anchor?: string;
47
+ }
48
+
49
+ interface GitHubPrIssueConfig {
50
+ enabled: boolean;
51
+ }
52
+
53
+ interface GhResult {
54
+ ok: boolean;
55
+ stdout: string;
56
+ stderr: string;
57
+ code: number | null;
58
+ error?: string;
59
+ }
60
+
61
+ interface RenderData {
62
+ url: string;
63
+ owner: string;
64
+ repo: string;
65
+ kind: Kind;
66
+ number: number;
67
+ anchor?: string;
68
+ view: Record<string, unknown>;
69
+ reviewThreads: Record<string, unknown>[];
70
+ reviewThreadsBounded?: boolean;
71
+ reviewThreadsUnavailable?: boolean;
72
+ fallbackNotes: string[];
73
+ }
74
+
75
+ let cachedConfig: GitHubPrIssueConfig | null = null;
76
+
77
+ function loadConfig(): GitHubPrIssueConfig {
78
+ if (cachedConfig) return cachedConfig;
79
+ const defaults = { enabled: true };
80
+ if (!existsSync(CONFIG_PATH)) {
81
+ cachedConfig = defaults;
82
+ return cachedConfig;
83
+ }
84
+ let parsed: unknown;
85
+ try {
86
+ parsed = JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
87
+ } catch (err) {
88
+ const message = err instanceof Error ? err.message : String(err);
89
+ throw new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);
90
+ }
91
+ const root = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed as Record<string, unknown> : {};
92
+ const value = root.githubPrIssue;
93
+ if (value !== undefined && (typeof value !== "object" || value === null || Array.isArray(value))) {
94
+ throw new Error(`githubPrIssue in ${CONFIG_PATH} must be an object`);
95
+ }
96
+ const enabled = typeof (value as { enabled?: unknown } | undefined)?.enabled === "boolean"
97
+ ? (value as { enabled: boolean }).enabled
98
+ : true;
99
+ cachedConfig = { enabled };
100
+ return cachedConfig;
101
+ }
102
+
103
+ function validOwner(owner: string): boolean {
104
+ return /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/.test(owner) && !owner.includes("--");
105
+ }
106
+
107
+ function validRepo(repo: string): boolean {
108
+ return /^[A-Za-z0-9._-]{1,100}$/.test(repo) && repo !== "." && repo !== "..";
109
+ }
110
+
111
+ function errorMessage(err: unknown): string {
112
+ return err instanceof Error ? err.message : String(err);
113
+ }
114
+
115
+ function isAbortError(err: unknown): boolean {
116
+ return errorMessage(err).toLowerCase().includes("abort");
117
+ }
118
+
119
+ export function parseGitHubIssuePrUrl(url: string): GitHubIssuePrUrlInfo | null {
120
+ let parsed: URL;
121
+ try {
122
+ parsed = new URL(url);
123
+ } catch {
124
+ return null;
125
+ }
126
+ const host = parsed.hostname.toLowerCase();
127
+ if (host !== "github.com" && host !== "www.github.com") return null;
128
+ const segments: string[] = [];
129
+ for (const segment of parsed.pathname.split("/").filter(Boolean)) {
130
+ try {
131
+ segments.push(decodeURIComponent(segment));
132
+ } catch {
133
+ return null;
134
+ }
135
+ }
136
+ if (segments.length < 4) return null;
137
+ const owner = segments[0];
138
+ const repo = segments[1].replace(/\.git$/, "");
139
+ if (!validOwner(owner) || !validRepo(repo)) return null;
140
+ const route = segments[2].toLowerCase();
141
+ if (route !== "pull" && route !== "issues") return null;
142
+ if (!/^\d+$/.test(segments[3])) return null;
143
+ const subpath = segments[4]?.toLowerCase();
144
+ if (route === "pull" && subpath && !PR_SUBPATHS.has(subpath)) return null;
145
+ if (route === "issues" && subpath) return null;
146
+ const number = Number.parseInt(segments[3], 10);
147
+ if (!Number.isSafeInteger(number) || number <= 0) return null;
148
+ const fragment = parsed.hash.slice(1);
149
+ const anchorPattern = route === "pull" ? /^(?:issuecomment-\d+|discussion_r\d+)$/i : /^issuecomment-\d+$/i;
150
+ const anchor = anchorPattern.test(fragment) ? fragment : undefined;
151
+ return { owner, repo, kind: route === "pull" ? "pull" : "issue", number, ...(anchor ? { anchor } : {}) };
152
+ }
153
+
154
+ function runGh(args: string[], timeoutMs = GH_TIMEOUT_MS, signal?: AbortSignal): Promise<GhResult> {
155
+ return new Promise((resolve) => {
156
+ execFile("gh", args, {
157
+ timeout: timeoutMs,
158
+ maxBuffer: 10 * 1024 * 1024,
159
+ ...(signal ? { signal } : {}),
160
+ env: { ...process.env, GH_PROMPT_DISABLED: "1", GIT_TERMINAL_PROMPT: "0" },
161
+ }, (err, stdout, stderr) => {
162
+ const nodeErr = err as NodeJS.ErrnoException | null;
163
+ resolve({
164
+ ok: !err,
165
+ stdout,
166
+ stderr,
167
+ code: typeof nodeErr?.code === "number" ? nodeErr.code : null,
168
+ ...(err ? { error: nodeErr?.message ?? String(err) } : {}),
169
+ });
170
+ });
171
+ });
172
+ }
173
+
174
+ function remainingGhTimeout(deadlineMs: number): number {
175
+ return Math.max(1, Math.min(GH_TIMEOUT_MS, deadlineMs - Date.now()));
176
+ }
177
+
178
+ function unknownJsonField(result: GhResult): boolean {
179
+ return /unknown (?:json )?field|UnknownField|Unknown JSON field/i.test(`${result.stderr}\n${result.error ?? ""}`);
180
+ }
181
+
182
+ async function ghView(info: GitHubIssuePrUrlInfo, deadlineMs: number, signal?: AbortSignal): Promise<{ view: Record<string, unknown>; notes: string[] } | null> {
183
+ const repoArg = `${info.owner}/${info.repo}`;
184
+ const command = info.kind === "pull" ? "pr" : "issue";
185
+ const fields = info.kind === "pull" ? PR_FIELDS : ISSUE_FIELDS;
186
+ const coreFields = info.kind === "pull" ? PR_CORE_FIELDS : ISSUE_CORE_FIELDS;
187
+ let result = await runGh([command, "view", String(info.number), "--repo", repoArg, "--json", fields.join(",")], remainingGhTimeout(deadlineMs), signal);
188
+ const notes: string[] = [];
189
+ let linkedReferencesUnavailable = false;
190
+ if (!result.ok && unknownJsonField(result)) {
191
+ result = await runGh([command, "view", String(info.number), "--repo", repoArg, "--json", coreFields.join(",")], remainingGhTimeout(deadlineMs), signal);
192
+ notes.push("Some GitHub fields were unavailable from this gh version; retried with the core field set.");
193
+ linkedReferencesUnavailable = true;
194
+ }
195
+ if (!result.ok) return null;
196
+ try {
197
+ const parsed = JSON.parse(result.stdout) as unknown;
198
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
199
+ const view = parsed as Record<string, unknown>;
200
+ if (linkedReferencesUnavailable) view.linkedReferencesUnavailable = true;
201
+ return { view, notes };
202
+ } catch {
203
+ return null;
204
+ }
205
+ }
206
+
207
+ async function ghReviewThreads(info: GitHubIssuePrUrlInfo, deadlineMs: number, signal?: AbortSignal): Promise<{ comments: Record<string, unknown>[]; note?: string; bounded?: boolean; unavailable?: boolean; anchorUnavailable?: boolean }> {
208
+ if (info.kind !== "pull") return { comments: [] };
209
+ const comments: Record<string, unknown>[] = [];
210
+ let bounded = false;
211
+ let pageFailed = false;
212
+ for (let page = 1; page <= 3; page++) {
213
+ const result = await runGh(["api", `repos/${info.owner}/${info.repo}/pulls/${info.number}/comments?per_page=100&page=${page}`], remainingGhTimeout(deadlineMs), signal);
214
+ if (!result.ok) {
215
+ pageFailed = true;
216
+ break;
217
+ }
218
+ let pageItems: unknown;
219
+ try {
220
+ pageItems = JSON.parse(result.stdout);
221
+ } catch {
222
+ pageFailed = true;
223
+ break;
224
+ }
225
+ if (!Array.isArray(pageItems) || pageItems.length === 0) break;
226
+ comments.push(...pageItems.filter((item): item is Record<string, unknown> => !!item && typeof item === "object" && !Array.isArray(item)));
227
+ if (pageItems.length < 100) break;
228
+ if (page === 3) bounded = true;
229
+ }
230
+ const discussionId = anchorId(info.anchor, "discussion_r");
231
+ if (discussionId && !hasCommentId(comments, discussionId)) {
232
+ const result = await runGh(["api", `repos/${info.owner}/${info.repo}/pulls/comments/${discussionId}`], remainingGhTimeout(deadlineMs), signal);
233
+ if (result.ok) {
234
+ try {
235
+ const comment = JSON.parse(result.stdout) as unknown;
236
+ if (comment && typeof comment === "object" && !Array.isArray(comment) && belongsToPull(comment as Record<string, unknown>, discussionId, info)) comments.push(comment as Record<string, unknown>);
237
+ else return { comments, bounded: bounded || (pageFailed && comments.length > 0), unavailable: pageFailed && comments.length === 0, anchorUnavailable: true };
238
+ } catch {
239
+ return { comments, bounded: bounded || (pageFailed && comments.length > 0), unavailable: pageFailed && comments.length === 0, note: "Anchored review thread comment unavailable from gh." };
240
+ }
241
+ } else {
242
+ return { comments, bounded: bounded || (pageFailed && comments.length > 0), unavailable: pageFailed && comments.length === 0, anchorUnavailable: true };
243
+ }
244
+ }
245
+ return { comments, bounded: bounded || (pageFailed && comments.length > 0), unavailable: pageFailed && comments.length === 0 };
246
+ }
247
+
248
+ function isRateLimited(response: Response): boolean {
249
+ return response.status === 403 && response.headers.get("x-ratelimit-remaining") === "0";
250
+ }
251
+
252
+ function anchorId(anchor: string | undefined, prefix: "issuecomment" | "discussion_r"): string | null {
253
+ const match = anchor?.match(prefix === "issuecomment" ? /^issuecomment-(\d+)$/i : /^discussion_r(\d+)$/i);
254
+ return match?.[1] ?? null;
255
+ }
256
+
257
+ function hasCommentId(comments: Record<string, unknown>[], id: string): boolean {
258
+ return comments.some(comment => commentId(comment) === id);
259
+ }
260
+
261
+ function belongsToIssue(comment: Record<string, unknown>, id: string, info: GitHubIssuePrUrlInfo): boolean {
262
+ return commentId(comment) === id && associationMatches(comment.issue_url, info, "issues");
263
+ }
264
+
265
+ function belongsToPull(comment: Record<string, unknown>, id: string, info: GitHubIssuePrUrlInfo): boolean {
266
+ return commentId(comment) === id && associationMatches(comment.pull_request_url, info, "pulls");
267
+ }
268
+
269
+ function associationMatches(value: unknown, info: GitHubIssuePrUrlInfo, route: "issues" | "pulls"): boolean {
270
+ if (typeof value !== "string") return false;
271
+ try {
272
+ const parsed = new URL(value);
273
+ if (parsed.protocol !== "https:" || parsed.hostname.toLowerCase() !== "api.github.com") return false;
274
+ return parsed.pathname.toLowerCase() === `/repos/${info.owner}/${info.repo}/${route}/${info.number}`.toLowerCase();
275
+ } catch {
276
+ return false;
277
+ }
278
+ }
279
+
280
+ function rateLimitResult(url: string, info: GitHubIssuePrUrlInfo, response: Response): ExtractedContent {
281
+ const reset = response.headers.get("x-ratelimit-reset");
282
+ const resetNote = reset ? ` Rate limit resets at Unix time ${reset}.` : "";
283
+ return {
284
+ url,
285
+ title: `${info.owner}/${info.repo}#${info.number}`,
286
+ content: `GitHub API rate limit reached for ${info.owner}/${info.repo} ${info.kind} #${info.number}.${resetNote}\n\nAuthenticate the gh CLI and retry:\n\n\`gh auth login\`\n\nThen fetch this URL again.`,
287
+ error: "GitHub API rate limit reached; authenticate gh to fetch this PR or issue.",
288
+ status: response.status,
289
+ };
290
+ }
291
+
292
+ async function restJson(url: string, options?: ExtractOptions, signal?: AbortSignal): Promise<{ value: unknown; response: Response } | null> {
293
+ const ssrf = loadSsrfConfig();
294
+ const domainPolicy = loadFetchContentDomainPolicy();
295
+ const response = await fetchRemoteUrl(url, { headers: REST_HEADERS, ...(signal ? { signal } : {}) }, {
296
+ allowRanges: ssrf.allowRanges,
297
+ trustEnvProxy: ssrf.trustEnvProxy,
298
+ domainPolicy,
299
+ ...(options?.lookup ? { lookup: options.lookup } : {}),
300
+ });
301
+ if (!response.ok) return { value: null, response };
302
+ return { value: await response.json(), response };
303
+ }
304
+
305
+ async function restFallback(url: string, info: GitHubIssuePrUrlInfo, options?: ExtractOptions, signal?: AbortSignal): Promise<ExtractedContent | { data: RenderData } | null> {
306
+ try {
307
+ const base = `https://api.github.com/repos/${info.owner}/${info.repo}`;
308
+ const mainPath = info.kind === "pull" ? `${base}/pulls/${info.number}` : `${base}/issues/${info.number}`;
309
+ const main = await restJson(mainPath, options, signal);
310
+ if (!main) return null;
311
+ if (isRateLimited(main.response)) return rateLimitResult(url, info, main.response);
312
+ if (!main.response.ok) return null;
313
+ const view = mapRestView(info, main.value);
314
+ view.linkedReferencesUnavailable = true;
315
+ const comments = await restJson(`${base}/issues/${info.number}/comments?per_page=50`, options, signal);
316
+ if (comments && isRateLimited(comments.response)) return rateLimitResult(url, info, comments.response);
317
+ const conversationComments = comments?.response.ok && Array.isArray(comments.value)
318
+ ? comments.value.filter((item): item is Record<string, unknown> => !!item && typeof item === "object" && !Array.isArray(item))
319
+ : [];
320
+ const issueCommentId = anchorId(info.anchor, "issuecomment");
321
+ if (issueCommentId && !hasCommentId(conversationComments, issueCommentId)) {
322
+ const anchoredComment = await restJson(`${base}/issues/comments/${issueCommentId}`, options, signal);
323
+ if (anchoredComment && isRateLimited(anchoredComment.response)) return rateLimitResult(url, info, anchoredComment.response);
324
+ if (anchoredComment?.response.ok && anchoredComment.value && typeof anchoredComment.value === "object" && !Array.isArray(anchoredComment.value)) {
325
+ const comment = anchoredComment.value as Record<string, unknown>;
326
+ if (belongsToIssue(comment, issueCommentId, info)) conversationComments.push(comment);
327
+ else view.anchorUnavailable = true;
328
+ } else {
329
+ view.anchorUnavailable = true;
330
+ }
331
+ }
332
+ view.comments = conversationComments;
333
+ const reviewThreads: Record<string, unknown>[] = [];
334
+ const notes = [info.kind === "pull" ? "Checks unavailable in REST fallback; install or authenticate gh for check status." : "REST fallback used; gh fields unavailable."];
335
+ if (info.kind === "pull") {
336
+ view.reviewsUnavailable = true;
337
+ view.commitsUnavailable = true;
338
+ const files = await restJson(`${base}/pulls/${info.number}/files?per_page=50`, options, signal);
339
+ if (files && isRateLimited(files.response)) return rateLimitResult(url, info, files.response);
340
+ if (files?.response.ok && Array.isArray(files.value)) view.files = files.value;
341
+ const threads = await restJson(`${base}/pulls/${info.number}/comments?per_page=50`, options, signal);
342
+ if (threads && isRateLimited(threads.response)) return rateLimitResult(url, info, threads.response);
343
+ if (threads?.response.ok && Array.isArray(threads.value)) {
344
+ reviewThreads.push(...threads.value.filter((item): item is Record<string, unknown> => !!item && typeof item === "object" && !Array.isArray(item)));
345
+ }
346
+ const discussionId = anchorId(info.anchor, "discussion_r");
347
+ if (discussionId && !hasCommentId(reviewThreads, discussionId)) {
348
+ const anchoredThread = await restJson(`${base}/pulls/comments/${discussionId}`, options, signal);
349
+ if (anchoredThread && isRateLimited(anchoredThread.response)) return rateLimitResult(url, info, anchoredThread.response);
350
+ if (anchoredThread?.response.ok && anchoredThread.value && typeof anchoredThread.value === "object" && !Array.isArray(anchoredThread.value)) {
351
+ const comment = anchoredThread.value as Record<string, unknown>;
352
+ if (belongsToPull(comment, discussionId, info)) reviewThreads.push(comment);
353
+ else view.anchorUnavailable = true;
354
+ } else {
355
+ view.anchorUnavailable = true;
356
+ }
357
+ }
358
+ }
359
+ return { data: { url, owner: info.owner, repo: info.repo, kind: info.kind, number: info.number, anchor: info.anchor, view, reviewThreads, fallbackNotes: notes } };
360
+ } catch (err) {
361
+ if (signal?.aborted || isAbortError(err)) return { url, title: "", content: "", error: "Aborted" };
362
+ const message = errorMessage(err);
363
+ return { url, title: `${info.owner}/${info.repo}#${info.number}`, content: message, error: `GitHub REST fallback failed: ${message}` };
364
+ }
365
+ }
366
+
367
+ function mapRestView(info: GitHubIssuePrUrlInfo, value: unknown): Record<string, unknown> {
368
+ const source = value && typeof value === "object" && !Array.isArray(value) ? value as Record<string, unknown> : {};
369
+ const user = source.user && typeof source.user === "object" ? source.user as Record<string, unknown> : undefined;
370
+ const base = source.base && typeof source.base === "object" ? source.base as Record<string, unknown> : undefined;
371
+ const head = source.head && typeof source.head === "object" ? source.head as Record<string, unknown> : undefined;
372
+ return {
373
+ title: stringValue(source.title),
374
+ number: numberValue(source.number) ?? info.number,
375
+ state: stringValue(source.state),
376
+ stateReason: stringValue(source.state_reason),
377
+ isDraft: Boolean(source.draft),
378
+ author: { login: user ? stringValue(user.login) : "" },
379
+ baseRefName: base ? stringValue(base.ref) : "",
380
+ headRefName: head ? stringValue(head.ref) : "",
381
+ headRepositoryOwner: { login: head && typeof head.repo === "object" && head.repo && typeof (head.repo as Record<string, unknown>).owner === "object" ? stringValue(((head.repo as Record<string, unknown>).owner as Record<string, unknown>).login) : "" },
382
+ createdAt: stringValue(source.created_at),
383
+ mergedAt: stringValue(source.merged_at),
384
+ closedAt: stringValue(source.closed_at),
385
+ labels: source.labels,
386
+ assignees: source.assignees,
387
+ milestone: source.milestone,
388
+ additions: source.additions,
389
+ deletions: source.deletions,
390
+ changedFiles: source.changed_files,
391
+ body: stringValue(source.body),
392
+ url: stringValue(source.html_url),
393
+ commentsCount: source.comments,
394
+ reviewCommentsCount: source.review_comments,
395
+ };
396
+ }
397
+
398
+ function stringValue(value: unknown): string {
399
+ return typeof value === "string" ? value : "";
400
+ }
401
+
402
+ function numberValue(value: unknown): number | null {
403
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
404
+ }
405
+
406
+ function authorLogin(value: unknown): string {
407
+ if (!value || typeof value !== "object" || Array.isArray(value)) return "unknown";
408
+ const login = (value as Record<string, unknown>).login;
409
+ return typeof login === "string" && login ? login : "unknown";
410
+ }
411
+
412
+ function listNames(value: unknown): string {
413
+ if (!Array.isArray(value) || value.length === 0) return "none";
414
+ const names = value.map((item) => {
415
+ if (!item || typeof item !== "object" || Array.isArray(item)) return "";
416
+ const record = item as Record<string, unknown>;
417
+ return stringValue(record.name) || stringValue(record.login) || stringValue(record.title);
418
+ }).filter(Boolean);
419
+ return names.length > 0 ? names.join(", ") : "none";
420
+ }
421
+
422
+ function milestoneTitle(value: unknown): string {
423
+ if (!value || typeof value !== "object" || Array.isArray(value)) return "none";
424
+ return stringValue((value as Record<string, unknown>).title) || "none";
425
+ }
426
+
427
+ function truncateText(text: string, limit: number, label: string, appendix: string[]): string {
428
+ if (text.length <= limit) return text;
429
+ appendix.push(`## Full ${label}\n\n${text}`);
430
+ return `${text.slice(0, limit)}\n\n[${label} truncated; use get_search_content findText or offset for the full text]`;
431
+ }
432
+
433
+ function appendLimitedSection(lines: string[], title: string, items: string[], max: number, marker: string): void {
434
+ lines.push(`## ${title}`);
435
+ if (items.length === 0) {
436
+ lines.push("none", "");
437
+ return;
438
+ }
439
+ lines.push(...items.slice(0, max));
440
+ if (items.length > max) lines.push(`[${max} of ${items.length} ${marker} shown; use get_search_content offset or the gh command below for more]`);
441
+ lines.push("");
442
+ }
443
+
444
+ function objectArray(value: unknown): Record<string, unknown>[] {
445
+ if (!Array.isArray(value)) return [];
446
+ return value.filter((item): item is Record<string, unknown> => !!item && typeof item === "object" && !Array.isArray(item));
447
+ }
448
+
449
+ function commentId(comment: Record<string, unknown>): string {
450
+ return String(comment.id ?? comment.databaseId ?? "");
451
+ }
452
+
453
+ function anchorMatches(anchor: string | undefined, comment: Record<string, unknown>): boolean {
454
+ if (!anchor) return false;
455
+ const id = commentId(comment);
456
+ return anchor === `issuecomment-${id}` || anchor === `discussion_r${id}`;
457
+ }
458
+
459
+ function renderComments(comments: Record<string, unknown>[], anchor: string | undefined, appendix: string[]): string[] {
460
+ const forced = anchor ? comments.find(comment => anchorMatches(anchor, comment)) : undefined;
461
+ const selected = comments.slice(0, MAX_INLINE_COMMENTS);
462
+ if (forced && !selected.includes(forced)) selected.push(forced);
463
+ const lines = selected.map((comment) => {
464
+ const body = stringValue(comment.body);
465
+ const label = `comment ${commentId(comment) || selected.indexOf(comment) + 1}`;
466
+ return `- ${authorLogin(comment.author ?? comment.user)} at ${stringValue(comment.createdAt) || stringValue(comment.created_at)}${forced === comment ? " [anchored]" : ""}:\n ${truncateText(body, COMMENT_INLINE_CHARS, label, appendix).replace(/\n/g, "\n ")}`;
467
+ });
468
+ return lines;
469
+ }
470
+
471
+ function renderCommentMarker(comments: Record<string, unknown>[], renderedCount: number, total: unknown): string | null {
472
+ const knownTotal = numberValue(total);
473
+ if (knownTotal !== null && knownTotal > comments.length) {
474
+ return `[${renderedCount} comments shown from at least ${knownTotal}; use get_search_content findText or offset, or gh issue view -c]`;
475
+ }
476
+ if (comments.length > renderedCount) return `[${renderedCount} of ${comments.length} comments shown; use get_search_content findText or offset, or gh issue view -c]`;
477
+ return null;
478
+ }
479
+
480
+ function commentCountText(view: Record<string, unknown>): string {
481
+ const comments = objectArray(view.comments).length;
482
+ const total = numberValue(view.commentsCount);
483
+ if (total !== null && total > comments) return `at least ${total}`;
484
+ return String(comments || total || 0);
485
+ }
486
+
487
+ function reviewThreadCountText(comments: Record<string, unknown>[], total: unknown, bounded?: boolean, unavailable?: boolean): string {
488
+ if (unavailable) return "unavailable";
489
+ const knownTotal = numberValue(total);
490
+ if (bounded) return `at least ${comments.length}`;
491
+ if (knownTotal !== null && knownTotal > comments.length) return `at least ${knownTotal}`;
492
+ return String(comments.length || knownTotal || 0);
493
+ }
494
+
495
+ function renderChecks(value: unknown): string[] {
496
+ const checks = objectArray(value);
497
+ if (checks.length === 0) return ["No check rollup data available."];
498
+ const rows = checks.map((check) => {
499
+ const name = stringValue(check.name) || stringValue(check.context) || stringValue(check.workflowName) || "check";
500
+ const state = stringValue(check.conclusion) || stringValue(check.status) || stringValue(check.state) || "unknown";
501
+ return `- ${name}: ${state}`;
502
+ });
503
+ const failing = rows.filter(row => !/(success|neutral|skipped|completed)$/i.test(row));
504
+ return [`Rollup: ${failing.length === 0 ? "no failing checks in shown data" : `${failing.length} non-passing checks in shown data`}`, ...rows.slice(0, MAX_INLINE_CHECKS), ...(rows.length > MAX_INLINE_CHECKS ? [`[${MAX_INLINE_CHECKS} of ${rows.length} checks shown]`] : [])];
505
+ }
506
+
507
+ function renderReviewVerdicts(value: unknown, appendix: string[]): string[] {
508
+ const latest = new Map<string, Record<string, unknown>>();
509
+ for (const review of objectArray(value)) latest.set(authorLogin(review.author ?? review.user), review);
510
+ return [...latest.entries()].map(([author, review]) => {
511
+ const state = stringValue(review.state) || "COMMENTED";
512
+ const body = truncateText(stringValue(review.body), 300, `review by ${author}`, appendix);
513
+ return `- ${author}: ${state}${body ? ` — ${body.replace(/\n/g, " ")}` : ""}`;
514
+ });
515
+ }
516
+
517
+ function renderReviewVerdictsOrUnavailable(view: Record<string, unknown>, appendix: string[]): string[] {
518
+ const rendered = renderReviewVerdicts(view.reviews, appendix);
519
+ if (rendered.length > 0) return rendered;
520
+ return view.reviewsUnavailable === true ? ["Unavailable in this GitHub fetch path; use gh for review verdicts."] : [];
521
+ }
522
+
523
+ function renderFiles(value: unknown): string[] {
524
+ return objectArray(value).map((file) => {
525
+ const path = stringValue(file.path) || stringValue(file.filename) || "file";
526
+ const additions = numberValue(file.additions) ?? 0;
527
+ const deletions = numberValue(file.deletions) ?? 0;
528
+ return `- ${path} (+${additions}/−${deletions})`;
529
+ });
530
+ }
531
+
532
+ function appendFilesSection(lines: string[], view: Record<string, unknown>): void {
533
+ lines.push("## Files");
534
+ const files = renderFiles(view.files);
535
+ if (files.length === 0) {
536
+ const total = numberValue(view.changedFiles);
537
+ if (total !== null && total > 0) {
538
+ lines.push(`[0 files shown from at least ${total}; use get_search_content offset or the gh command below for more]`, "");
539
+ return;
540
+ }
541
+ lines.push("none", "");
542
+ return;
543
+ }
544
+ lines.push(...files.slice(0, MAX_INLINE_FILES));
545
+ const total = numberValue(view.changedFiles);
546
+ if (total !== null && total > files.length) {
547
+ lines.push(`[${Math.min(files.length, MAX_INLINE_FILES)} files shown from at least ${total}; use get_search_content offset or the gh command below for more]`);
548
+ } else if (files.length > MAX_INLINE_FILES) {
549
+ lines.push(`[${MAX_INLINE_FILES} of ${files.length} files shown; use get_search_content offset or the gh command below for more]`);
550
+ }
551
+ lines.push("");
552
+ }
553
+
554
+ function renderCommits(value: unknown): string[] {
555
+ return objectArray(value).map((commit) => {
556
+ const oid = stringValue(commit.oid) || stringValue(commit.sha);
557
+ const message = stringValue(commit.messageHeadline) || (commit.commit && typeof commit.commit === "object" ? stringValue((commit.commit as Record<string, unknown>).message).split("\n")[0] : "");
558
+ return `- ${oid.slice(0, 7)} ${message}`.trim();
559
+ });
560
+ }
561
+
562
+ function renderCommitsOrUnavailable(view: Record<string, unknown>): string[] {
563
+ const rendered = renderCommits(view.commits);
564
+ if (rendered.length > 0) return rendered;
565
+ return view.commitsUnavailable === true ? ["Unavailable in this GitHub fetch path; use gh for commits."] : [];
566
+ }
567
+
568
+ function renderLinked(value: unknown, kind: "closing" | "closedBy"): string[] {
569
+ return objectArray(value).map((item) => `- #${numberValue(item.number) ?? "?"} ${stringValue(item.title)}${kind === "closedBy" ? ` (${stringValue(item.url)})` : ""}`);
570
+ }
571
+
572
+ function renderLinkedOrUnavailable(view: Record<string, unknown>, field: "closingIssuesReferences" | "closedByPullRequestsReferences", kind: "closing" | "closedBy"): string[] {
573
+ const linked = renderLinked(view[field], kind);
574
+ if (linked.length > 0) return linked;
575
+ return view.linkedReferencesUnavailable === true ? ["Unavailable in this GitHub fetch path; use gh for linked references."] : [];
576
+ }
577
+
578
+ function renderReviewThreads(comments: Record<string, unknown>[], anchor: string | undefined, appendix: string[], total?: unknown, bounded?: boolean, unavailable?: boolean): string[] {
579
+ if (unavailable) return ["Unavailable in this GitHub fetch path; use gh for review thread comments."];
580
+ const forced = anchor ? comments.find(comment => anchorMatches(anchor, comment)) : undefined;
581
+ const selected = comments.slice(0, MAX_INLINE_REVIEW_THREADS);
582
+ if (forced && !selected.includes(forced)) selected.push(forced);
583
+ const lines = selected.map((comment) => {
584
+ const path = stringValue(comment.path) || "unknown path";
585
+ const line = numberValue(comment.line) ?? numberValue(comment.original_line) ?? numberValue(comment.position) ?? "?";
586
+ const body = truncateText(stringValue(comment.body), COMMENT_INLINE_CHARS, `review thread comment ${commentId(comment) || selected.indexOf(comment) + 1}`, appendix);
587
+ return `- ${path}:${line} — ${authorLogin(comment.user ?? comment.author)}${forced === comment ? " [anchored]" : ""} (resolution state unknown):\n ${body.replace(/\n/g, "\n ")}`;
588
+ });
589
+ const knownTotal = numberValue(total);
590
+ if (bounded) {
591
+ lines.push(`[${selected.length} review thread comments shown from at least ${comments.length}; use get_search_content offset, or gh api repos/<owner>/<repo>/pulls/<number>/comments]`);
592
+ } else if (knownTotal !== null && knownTotal > comments.length) {
593
+ lines.push(`[${selected.length} review thread comments shown from at least ${knownTotal}; use get_search_content offset, or gh api repos/<owner>/<repo>/pulls/<number>/comments]`);
594
+ } else if (comments.length > selected.length) {
595
+ lines.push(`[${selected.length} of ${comments.length} review thread comments shown; use get_search_content offset, or gh api repos/<owner>/<repo>/pulls/<number>/comments]`);
596
+ }
597
+ return lines;
598
+ }
599
+
600
+ export function renderGitHubPrIssue(data: RenderData): ExtractedContent {
601
+ const { view } = data;
602
+ const appendix: string[] = [];
603
+ const title = stringValue(view.title) || `${data.owner}/${data.repo}#${data.number}`;
604
+ const number = numberValue(view.number) ?? data.number;
605
+ const stateParts = [stringValue(view.state) || "unknown"];
606
+ if (view.isDraft === true) stateParts.push("draft");
607
+ const lines: string[] = [`#${number} ${title}`, ""];
608
+ lines.push(`- type: ${data.kind}`);
609
+ lines.push(`- state: ${stateParts.join(" ")}${stringValue(view.stateReason) ? ` (${stringValue(view.stateReason)})` : ""}`);
610
+ lines.push(`- author: ${authorLogin(view.author)}`);
611
+ if (data.kind === "pull") {
612
+ const headOwner = authorLogin(view.headRepositoryOwner);
613
+ const headRef = stringValue(view.headRefName);
614
+ const head = headOwner !== "unknown" && headOwner !== data.owner ? `${headOwner}:${headRef}` : headRef;
615
+ lines.push(`- branch: ${stringValue(view.baseRefName)} ← ${head}`);
616
+ const commitSummary = view.commitsUnavailable === true ? "commits unavailable" : `${objectArray(view.commits).length} commits`;
617
+ lines.push(`- changes: +${numberValue(view.additions) ?? 0} −${numberValue(view.deletions) ?? 0}, ${numberValue(view.changedFiles) ?? objectArray(view.files).length} files, ${commitSummary}`);
618
+ } else {
619
+ lines.push(`- assignees: ${listNames(view.assignees)}`);
620
+ }
621
+ lines.push(`- created: ${stringValue(view.createdAt) || "unknown"}`);
622
+ if (stringValue(view.mergedAt)) lines.push(`- merged: ${stringValue(view.mergedAt)}`);
623
+ if (stringValue(view.closedAt)) lines.push(`- closed: ${stringValue(view.closedAt)}`);
624
+ lines.push(`- labels: ${listNames(view.labels)}`);
625
+ lines.push(`- milestone: ${milestoneTitle(view.milestone)}`);
626
+ lines.push(`- comments: ${commentCountText(view)}; review threads: ${reviewThreadCountText(data.reviewThreads, view.reviewCommentsCount, data.reviewThreadsBounded, data.reviewThreadsUnavailable)}`);
627
+ if (data.anchor) lines.push(`- requested anchor: #${data.anchor}`);
628
+ lines.push("");
629
+
630
+ lines.push("## Body");
631
+ lines.push(truncateText(stringValue(view.body) || "(empty)", BODY_INLINE_CHARS, "body", appendix), "");
632
+
633
+ if (data.kind === "pull") {
634
+ lines.push("## Checks");
635
+ lines.push(...renderChecks(view.statusCheckRollup), "");
636
+ appendLimitedSection(lines, "Review verdicts", renderReviewVerdictsOrUnavailable(view, appendix), MAX_INLINE_REVIEWS, "review verdicts");
637
+ appendLimitedSection(lines, "Linked references", renderLinkedOrUnavailable(view, "closingIssuesReferences", "closing"), 20, "linked references");
638
+ appendFilesSection(lines, view);
639
+ appendLimitedSection(lines, "Commits", renderCommitsOrUnavailable(view), MAX_INLINE_COMMITS, "commits");
640
+ } else {
641
+ appendLimitedSection(lines, "Closed by pull requests", renderLinkedOrUnavailable(view, "closedByPullRequestsReferences", "closedBy"), 20, "pull requests");
642
+ }
643
+ lines.push("## Conversation comments");
644
+ const commentLines = renderComments(objectArray(view.comments), data.anchor, appendix);
645
+ const commentMarker = renderCommentMarker(objectArray(view.comments), commentLines.length, view.commentsCount);
646
+ if (commentMarker) commentLines.push(commentMarker);
647
+ if (view.anchorUnavailable === true && data.anchor?.startsWith("issuecomment-")) commentLines.push("[anchored comment unavailable for this issue or pull request]");
648
+ lines.push(...(commentLines.length > 0 ? commentLines : ["none"]), "");
649
+ if (data.kind === "pull") {
650
+ lines.push("## Review thread comments");
651
+ const threadLines = renderReviewThreads(data.reviewThreads, data.anchor, appendix, view.reviewCommentsCount, data.reviewThreadsBounded, data.reviewThreadsUnavailable);
652
+ if (view.anchorUnavailable === true && data.anchor?.startsWith("discussion_r")) threadLines.push("[anchored review thread comment unavailable for this pull request]");
653
+ lines.push(...(threadLines.length > 0 ? threadLines : ["none"]), "");
654
+ }
655
+ if (data.fallbackNotes.length > 0) {
656
+ lines.push("## Availability notes", ...data.fallbackNotes.map(note => `- ${note}`), "");
657
+ }
658
+ if (appendix.length > 0) lines.push("## Appendix", ...appendix, "");
659
+ const viewCommand = data.kind === "pull" ? `gh pr view ${data.number} --repo ${data.owner}/${data.repo}` : `gh issue view ${data.number} --repo ${data.owner}/${data.repo} -c`;
660
+ lines.push("## Escalation commands");
661
+ lines.push(`- Full view: \`${viewCommand}\``);
662
+ if (data.kind === "pull") lines.push(`- Complete diff: \`gh pr diff ${data.number} --repo ${data.owner}/${data.repo}\``);
663
+ lines.push("- Stored full document: use `get_search_content` with `offset` or `findText`.");
664
+ const content = lines.join("\n");
665
+ return {
666
+ url: data.url,
667
+ title: `${data.owner}/${data.repo} ${data.kind} #${data.number}: ${title}`,
668
+ content: content.length > MAX_DOC_CHARS ? `${content.slice(0, MAX_DOC_CHARS)}\n\n[GitHub document truncated at ${MAX_DOC_CHARS} chars; use the gh escalation commands for complete data]` : content,
669
+ error: null,
670
+ };
671
+ }
672
+
673
+ export async function extractGitHubIssuePr(url: string, signal?: AbortSignal, options?: ExtractOptions): Promise<ExtractedContent | null> {
674
+ const info = parseGitHubIssuePrUrl(url);
675
+ if (!info) return null;
676
+ if (!loadConfig().enabled) return null;
677
+ if (signal?.aborted) return { url, title: "", content: "", error: "Aborted" };
678
+
679
+ const ghAvailable = await checkGhAvailable(signal);
680
+ if (signal?.aborted) return { url, title: "", content: "", error: "Aborted" };
681
+ if (ghAvailable) {
682
+ const ghDeadlineMs = Date.now() + GH_TOTAL_TIMEOUT_MS;
683
+ const viewed = await ghView(info, ghDeadlineMs, signal);
684
+ if (signal?.aborted) return { url, title: "", content: "", error: "Aborted" };
685
+ if (viewed) {
686
+ const threads = await ghReviewThreads(info, ghDeadlineMs, signal);
687
+ if (signal?.aborted) return { url, title: "", content: "", error: "Aborted" };
688
+ if (threads.anchorUnavailable) viewed.view.anchorUnavailable = true;
689
+ const notes = [...viewed.notes, ...(threads.note ? [threads.note] : [])];
690
+ return renderGitHubPrIssue({ url, owner: info.owner, repo: info.repo, kind: info.kind, number: info.number, anchor: info.anchor, view: viewed.view, reviewThreads: threads.comments, reviewThreadsBounded: threads.bounded, reviewThreadsUnavailable: threads.unavailable, fallbackNotes: notes });
691
+ }
692
+ } else {
693
+ showGhHint();
694
+ }
695
+
696
+ const fallback = await restFallback(url, info, options, signal);
697
+ if (!fallback) return null;
698
+ if ("data" in fallback) return renderGitHubPrIssue(fallback.data);
699
+ return fallback;
700
+ }