shortcutxl 0.3.76 → 0.3.78

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 (480) hide show
  1. package/BINARY-INVENTORY.json +813 -813
  2. package/CHANGELOG.md +14 -0
  3. package/dist/ai/models.d.ts +10 -6
  4. package/dist/ai/models.generated.d.ts +72 -0
  5. package/dist/ai/models.generated.js +33 -0
  6. package/dist/ai/models.js +36 -13
  7. package/dist/ai/providers/anthropic.d.ts +4 -2
  8. package/dist/ai/providers/anthropic.js +59 -29
  9. package/dist/ai/providers/azure-openai-responses.d.ts +2 -1
  10. package/dist/ai/providers/azure-openai-responses.js +4 -20
  11. package/dist/ai/providers/google-vertex.d.ts +8 -2
  12. package/dist/ai/providers/google-vertex.js +66 -54
  13. package/dist/ai/providers/google.js +15 -48
  14. package/dist/ai/providers/openai-completions.d.ts +4 -1
  15. package/dist/ai/providers/openai-completions.js +26 -10
  16. package/dist/ai/providers/openai-reasoning.d.ts +5 -0
  17. package/dist/ai/providers/openai-reasoning.js +13 -0
  18. package/dist/ai/providers/openai-responses-shared.js +1 -1
  19. package/dist/ai/providers/openai-responses.d.ts +6 -2
  20. package/dist/ai/providers/openai-responses.js +28 -23
  21. package/dist/ai/providers/simple-options.d.ts +2 -3
  22. package/dist/ai/providers/simple-options.js +4 -6
  23. package/dist/ai/types.d.ts +19 -2
  24. package/dist/app/agent-session-runtime-adapter.js +7 -6
  25. package/dist/app/agent-session.d.ts +0 -15
  26. package/dist/app/agent-session.js +0 -37
  27. package/dist/app/approvals/approval-errors.d.ts +15 -0
  28. package/dist/app/approvals/approval-errors.js +14 -0
  29. package/dist/app/approvals/runtime-approval-gates.d.ts +1 -2
  30. package/dist/app/approvals/tool-approval.d.ts +1 -0
  31. package/dist/app/approvals/tool-approval.js +11 -23
  32. package/dist/app/approvals/types.d.ts +0 -14
  33. package/dist/app/approvals/types.js +0 -2
  34. package/dist/app/background/tool-summaries.js +0 -2
  35. package/dist/app/extensions/slash-commands.js +1 -3
  36. package/dist/app/local/tools/execute-code/executor.d.ts +1 -1
  37. package/dist/app/local/tools/execute-code/executor.js +20 -10
  38. package/dist/app/local/tools/execute-code/tool.js +21 -2
  39. package/dist/app/modes/action/agent.js +4 -5
  40. package/dist/app/modes/ask/agent.js +4 -6
  41. package/dist/app/modes/index.js +20 -10
  42. package/dist/app/modes/installation/agent.js +4 -5
  43. package/dist/app/modes/manage/agent.js +3 -4
  44. package/dist/app/modes/manage/prompt.js +1 -2
  45. package/dist/app/modes/metadata.d.ts +31 -0
  46. package/dist/app/modes/metadata.js +35 -0
  47. package/dist/app/modes/plan/agent.js +5 -8
  48. package/dist/app/modes/plan/prompt.js +3 -3
  49. package/dist/app/permissions/runtime-approval-flow.d.ts +1 -5
  50. package/dist/app/permissions/runtime-approval-flow.js +0 -28
  51. package/dist/app/permissions/tool-gates.d.ts +2 -3
  52. package/dist/app/permissions/tool-gates.js +3 -81
  53. package/dist/app/prompts/com-api.js +1 -1
  54. package/dist/app/prompts/shared-guidelines.js +7 -3
  55. package/dist/app/providers/google-vertex-gateway.js +4 -51
  56. package/dist/app/providers/model-registry.d.ts +1 -0
  57. package/dist/app/providers/model-registry.js +39 -0
  58. package/dist/app/providers/model-resolver.js +10 -7
  59. package/dist/app/providers/register-shortcut-provider.js +6 -6
  60. package/dist/app/providers/shortcut-api-v2-transport.js +4 -0
  61. package/dist/app/providers/shortcut-llm-proxy-client.d.ts +2 -2
  62. package/dist/app/providers/shortcut-llm-proxy-client.js +1 -0
  63. package/dist/app/resources/package-manager.js +2 -123
  64. package/dist/app/resources/resource-patterns.d.ts +9 -0
  65. package/dist/app/resources/resource-patterns.js +120 -0
  66. package/dist/app/session/forked-agent.d.ts +2 -2
  67. package/dist/app/session/model-manager.js +3 -2
  68. package/dist/app/session/session-lifecycle.js +3 -2
  69. package/dist/app/session/session-models.d.ts +2 -0
  70. package/dist/app/session/session-models.js +14 -6
  71. package/dist/app/settings-manager.d.ts +3 -3
  72. package/dist/app/shared/tools/execute-code/mog.d.ts +3 -1
  73. package/dist/app/shared/tools/execute-code/mog.js +18 -2
  74. package/dist/app/tools/bash.js +3 -3
  75. package/dist/app/tools/execute-code/index.d.ts +1 -0
  76. package/dist/app/tools/execute-code/index.js +3 -1
  77. package/dist/app/tools/find-ignore-files.d.ts +3 -0
  78. package/dist/app/tools/find-ignore-files.js +33 -0
  79. package/dist/app/tools/find.js +2 -21
  80. package/dist/app/tools/llm-analysis.js +0 -2
  81. package/dist/app/tools/refresh-context.d.ts +1 -1
  82. package/dist/app/tools/session-settings/update-session-settings.js +2 -2
  83. package/dist/app/tools/switch-mode.js +2 -2
  84. package/dist/app/tools/take-screenshot.js +0 -2
  85. package/dist/app/tools/task/runner.js +1 -2
  86. package/dist/app/tools/task/task.d.ts +1 -3
  87. package/dist/app/tools/task/task.js +20 -40
  88. package/dist/app/tools/web-search.js +12 -2
  89. package/dist/autocomplete/core.d.ts +33 -0
  90. package/dist/autocomplete/core.js +113 -0
  91. package/dist/{tui → autocomplete}/fuzzy.d.ts +0 -1
  92. package/dist/{tui → autocomplete}/fuzzy.js +0 -1
  93. package/dist/{tui/autocomplete.d.ts → autocomplete/index.d.ts} +0 -1
  94. package/dist/{tui/autocomplete.js → autocomplete/index.js} +62 -158
  95. package/dist/cli/args.js +1 -1
  96. package/dist/cli/list-models.js +1 -1
  97. package/dist/cli.js +26227 -30480
  98. package/dist/constants.d.ts +0 -2
  99. package/dist/constants.js +0 -3
  100. package/dist/contracts/agent-session-store.d.ts +1 -1
  101. package/dist/contracts/agent-settings.d.ts +1 -0
  102. package/dist/contracts/agent-settings.js +2 -1
  103. package/dist/contracts/model-call.d.ts +1 -2
  104. package/dist/contracts/model-call.js +1 -2
  105. package/dist/contracts/model-stream.d.ts +1 -0
  106. package/dist/contracts/model-stream.js +1 -0
  107. package/dist/contracts/wire.d.ts +10 -7
  108. package/dist/contracts/wire.js +8 -0
  109. package/dist/core/agent-engine.js +1 -1
  110. package/dist/core/core-types.d.ts +1 -21
  111. package/dist/core/defaults.d.ts +1 -1
  112. package/dist/core/defaults.js +9 -1
  113. package/dist/core/prompts/agent-guidelines.d.ts +4 -5
  114. package/dist/core/prompts/agent-guidelines.js +28 -42
  115. package/dist/core/session-schema.d.ts +1 -1
  116. package/dist/embedded-agent/ai-invoke.d.ts +1 -2
  117. package/dist/embedded-agent/ai-invoke.js +2 -70
  118. package/dist/embedded-agent/anthropic-messages-transport.d.ts +4 -20
  119. package/dist/embedded-agent/anthropic-messages-transport.js +23 -786
  120. package/dist/embedded-agent/bootstrap.js +2 -2
  121. package/dist/embedded-agent/compose.js +8 -7
  122. package/dist/embedded-agent/gateway-base-url.d.ts +3 -0
  123. package/dist/embedded-agent/gateway-base-url.js +35 -0
  124. package/dist/embedded-agent/google-vertex-transport.d.ts +2 -11
  125. package/dist/embedded-agent/google-vertex-transport.js +20 -117
  126. package/dist/embedded-agent/host-runtime-options.d.ts +0 -8
  127. package/dist/embedded-agent/host-runtime-options.js +10 -2
  128. package/dist/embedded-agent/host-tools/invoke-llm/contract.d.ts +2 -2
  129. package/dist/embedded-agent/host-tools/invoke-llm/contract.js +4 -2
  130. package/dist/embedded-agent/host-tools/sandbox-llm/contract.d.ts +8 -3
  131. package/dist/embedded-agent/host-tools/sandbox-llm/contract.js +12 -8
  132. package/dist/embedded-agent/host-tools/sandbox-llm/index.d.ts +1 -1
  133. package/dist/embedded-agent/host-tools/sandbox-llm/index.js +1 -1
  134. package/dist/embedded-agent/host-tools/shared/index.d.ts +1 -1
  135. package/dist/embedded-agent/host-tools/shared/index.js +1 -1
  136. package/dist/embedded-agent/host-tools/shared/llm-stream-error.d.ts +7 -0
  137. package/dist/embedded-agent/host-tools/shared/llm-stream-error.js +10 -0
  138. package/dist/embedded-agent/host-tools/take-screenshot/contract.d.ts +0 -2
  139. package/dist/embedded-agent/host-tools/take-screenshot/contract.js +1 -3
  140. package/dist/embedded-agent/host-tools/take-screenshot/index.d.ts +1 -1
  141. package/dist/embedded-agent/host-tools/take-screenshot/index.js +1 -1
  142. package/dist/embedded-agent/host-tools/task/agents/clone.js +1 -2
  143. package/dist/embedded-agent/host-tools/task/contract.js +1 -1
  144. package/dist/embedded-agent/index.d.ts +3 -4
  145. package/dist/embedded-agent/index.js +2 -3
  146. package/dist/embedded-agent/model-selection.d.ts +0 -6
  147. package/dist/embedded-agent/model-selection.js +15 -8
  148. package/dist/embedded-agent/openai-completions-transport.d.ts +2 -11
  149. package/dist/embedded-agent/openai-completions-transport.js +20 -120
  150. package/dist/embedded-agent/openai-responses-transport.d.ts +2 -11
  151. package/dist/embedded-agent/openai-responses-transport.js +15 -170
  152. package/dist/embedded-agent/prompt/build.js +1 -2
  153. package/dist/embedded-agent/prompt/sections.d.ts +1 -1
  154. package/dist/embedded-agent/prompt/sections.js +2 -0
  155. package/dist/embedded-agent/provider-native-request.d.ts +29 -0
  156. package/dist/embedded-agent/provider-native-request.js +65 -0
  157. package/dist/embedded-agent/run-stats.d.ts +1 -1
  158. package/dist/embedded-agent/stream.d.ts +10 -96
  159. package/dist/embedded-agent/stream.js +31 -556
  160. package/dist/embedded-agent/suggestions.d.ts +1 -1
  161. package/dist/embedded-agent/suggestions.js +1 -1
  162. package/dist/embedded-agent/worker-bridge/host-client.d.ts +7 -0
  163. package/dist/embedded-agent/worker-bridge/host-client.js +15 -0
  164. package/dist/embedded-agent/worker-bridge/worker-port.js +17 -1
  165. package/dist/main.js +18 -14
  166. package/dist/rpc/index.d.ts +1 -1
  167. package/dist/rpc/rpc-approval-gates.js +1 -2
  168. package/dist/rpc/rpc-host.d.ts +4 -0
  169. package/dist/rpc/rpc-host.js +13 -24
  170. package/dist/rpc/rpc-types.d.ts +6 -17
  171. package/dist/shared/platform/open.d.ts +4 -1
  172. package/dist/shared/platform/open.js +14 -2
  173. package/dist/shell/approvals/runtime-approval-gates.js +1 -3
  174. package/dist/shell/components/selectors/model-selector.js +2 -1
  175. package/dist/shell/components/selectors/session-selector-search.js +1 -1
  176. package/dist/shell/components/selectors/thinking-selector.js +7 -6
  177. package/dist/shell/index.d.ts +0 -1
  178. package/dist/shell/index.js +0 -1
  179. package/dist/shell/interactive/interactive-mode-options.d.ts +10 -0
  180. package/dist/shell/interactive/interactive-mode.d.ts +6 -12
  181. package/dist/shell/interactive/interactive-mode.js +39 -158
  182. package/dist/shell/interactive/slash-commands.d.ts +0 -34
  183. package/dist/shell/interactive/slash-commands.js +0 -2
  184. package/dist/shell/links/local-file-link-input.d.ts +15 -0
  185. package/dist/shell/links/local-file-link-input.js +38 -0
  186. package/dist/shell/links/local-file-link.d.ts +7 -0
  187. package/dist/shell/links/local-file-link.js +35 -0
  188. package/dist/shell/links/local-file-opener.d.ts +16 -0
  189. package/dist/shell/links/local-file-opener.js +90 -0
  190. package/dist/shell/session-client.d.ts +0 -1
  191. package/dist/shell/session-client.js +0 -6
  192. package/dist/shell/status/update-check-scheduler.d.ts +30 -0
  193. package/dist/shell/status/update-check-scheduler.js +71 -0
  194. package/dist/shell/status/update-reminder-controller.d.ts +22 -0
  195. package/dist/shell/status/update-reminder-controller.js +40 -0
  196. package/dist/shell/status/update-reminder.d.ts +6 -0
  197. package/dist/shell/status/update-reminder.js +4 -0
  198. package/dist/shell/theme/dark.json +1 -2
  199. package/dist/shell/theme/light.json +1 -2
  200. package/dist/shell/theme/runtime.d.ts +2 -3
  201. package/dist/shell/theme/runtime.js +2 -6
  202. package/dist/shell/theme/theme-schema.json +1 -6
  203. package/dist/shortcut-model-catalog.d.ts +7 -2
  204. package/dist/shortcut-model-catalog.js +134 -10
  205. package/dist/startup/update-manager.d.ts +6 -6
  206. package/dist/startup/update-manager.js +23 -38
  207. package/dist/startup/update-prompt.d.ts +1 -0
  208. package/dist/startup/update-prompt.js +2 -2
  209. package/dist/tui/components/editor.d.ts +1 -1
  210. package/dist/tui/components/editor.js +1 -1
  211. package/dist/tui/components/markdown.js +15 -6
  212. package/dist/tui/components/settings-list.js +1 -1
  213. package/dist/tui/editor-component.d.ts +1 -1
  214. package/dist/tui/index.d.ts +7 -8
  215. package/dist/tui/index.js +7 -6
  216. package/dist/tui/tui.d.ts +2 -0
  217. package/dist/tui/tui.js +16 -1
  218. package/dist/tui/utils.d.ts +7 -0
  219. package/dist/tui/utils.js +58 -8
  220. package/native-app/main/index.js +3200 -48
  221. package/native-app/main/{photon_rs-SoVDgheu.js → photon_rs-XkYyYTVA.js} +2 -2
  222. package/native-app/package.json +1 -1
  223. package/native-app/preload/index.cjs +2 -0
  224. package/native-app/renderer/assets/{index-CFc-oZuS.js → index-B4jz6epR.js} +825 -155
  225. package/native-app/renderer/assets/{index-OhGE0UY4.css → index-C__g36ft.css} +412 -162
  226. package/native-app/renderer/assets/shortcutagent-DxFsGSkw.png +0 -0
  227. package/native-app/renderer/index.html +2 -2
  228. package/package.json +17 -3
  229. package/skills/add-custom-model/SKILL.md +52 -0
  230. package/user-docs/dist/index.html +1 -1
  231. package/user-docs/dist/shortcutxl-docs.pdf +0 -0
  232. package/xll/ShortcutXL.xll +0 -0
  233. package/xll/modules/shortcut_xl/_managed.py +26 -7
  234. package/xll/modules/shortcut_xl/_tracking.py +141 -251
  235. package/xll/modules/shortcut_xl/api/__init__.py +60 -0
  236. package/xll/modules/shortcut_xl/api/workbook.py +9 -1
  237. package/xll/modules/shortcut_xl/api/worksheet.py +4 -1
  238. package/xll/python/Lib/site-packages/httpx-0.28.1.dist-info/RECORD +1 -1
  239. package/xll/python/Lib/site-packages/idna-3.18.dist-info/RECORD +1 -1
  240. package/xll/python/Lib/site-packages/pip/__init__.py +1 -1
  241. package/xll/python/Lib/site-packages/pip/_internal/build_env/__init__.py +25 -0
  242. package/xll/python/Lib/site-packages/pip/_internal/build_env/base.py +103 -0
  243. package/xll/python/Lib/site-packages/pip/_internal/build_env/installer.py +333 -0
  244. package/xll/python/Lib/site-packages/pip/_internal/build_env/noop.py +42 -0
  245. package/xll/python/Lib/site-packages/pip/_internal/build_env/venv.py +145 -0
  246. package/xll/python/Lib/site-packages/pip/_internal/build_env/virtual.py +139 -0
  247. package/xll/python/Lib/site-packages/pip/_internal/cache.py +4 -1
  248. package/xll/python/Lib/site-packages/pip/_internal/cli/autocompletion.py +4 -1
  249. package/xll/python/Lib/site-packages/pip/_internal/cli/base_command.py +11 -14
  250. package/xll/python/Lib/site-packages/pip/_internal/cli/cmdoptions.py +133 -22
  251. package/xll/python/Lib/site-packages/pip/_internal/cli/index_command.py +11 -6
  252. package/xll/python/Lib/site-packages/pip/_internal/cli/main.py +2 -1
  253. package/xll/python/Lib/site-packages/pip/_internal/cli/main_parser.py +1 -2
  254. package/xll/python/Lib/site-packages/pip/_internal/cli/parser.py +10 -2
  255. package/xll/python/Lib/site-packages/pip/_internal/cli/progress_bars.py +2 -2
  256. package/xll/python/Lib/site-packages/pip/_internal/cli/req_command.py +57 -25
  257. package/xll/python/Lib/site-packages/pip/_internal/cli/status_codes.py +1 -0
  258. package/xll/python/Lib/site-packages/pip/_internal/commands/cache.py +7 -6
  259. package/xll/python/Lib/site-packages/pip/_internal/commands/configuration.py +2 -1
  260. package/xll/python/Lib/site-packages/pip/_internal/commands/debug.py +4 -5
  261. package/xll/python/Lib/site-packages/pip/_internal/commands/download.py +4 -0
  262. package/xll/python/Lib/site-packages/pip/_internal/commands/freeze.py +1 -1
  263. package/xll/python/Lib/site-packages/pip/_internal/commands/index.py +10 -3
  264. package/xll/python/Lib/site-packages/pip/_internal/commands/inspect.py +1 -1
  265. package/xll/python/Lib/site-packages/pip/_internal/commands/install.py +6 -6
  266. package/xll/python/Lib/site-packages/pip/_internal/commands/list.py +11 -6
  267. package/xll/python/Lib/site-packages/pip/_internal/commands/lock.py +4 -6
  268. package/xll/python/Lib/site-packages/pip/_internal/commands/show.py +14 -8
  269. package/xll/python/Lib/site-packages/pip/_internal/commands/wheel.py +7 -1
  270. package/xll/python/Lib/site-packages/pip/_internal/configuration.py +2 -3
  271. package/xll/python/Lib/site-packages/pip/_internal/distributions/base.py +5 -3
  272. package/xll/python/Lib/site-packages/pip/_internal/distributions/installed.py +3 -2
  273. package/xll/python/Lib/site-packages/pip/_internal/distributions/sdist.py +45 -20
  274. package/xll/python/Lib/site-packages/pip/_internal/distributions/wheel.py +3 -2
  275. package/xll/python/Lib/site-packages/pip/_internal/exceptions.py +174 -0
  276. package/xll/python/Lib/site-packages/pip/_internal/index/collector.py +70 -48
  277. package/xll/python/Lib/site-packages/pip/_internal/index/package_finder.py +46 -7
  278. package/xll/python/Lib/site-packages/pip/_internal/index/sources.py +1 -2
  279. package/xll/python/Lib/site-packages/pip/_internal/locations/_sysconfig.py +1 -1
  280. package/xll/python/Lib/site-packages/pip/_internal/locations/base.py +1 -1
  281. package/xll/python/Lib/site-packages/pip/_internal/metadata/base.py +10 -5
  282. package/xll/python/Lib/site-packages/pip/_internal/metadata/importlib/_dists.py +1 -1
  283. package/xll/python/Lib/site-packages/pip/_internal/metadata/importlib/_envs.py +8 -3
  284. package/xll/python/Lib/site-packages/pip/_internal/models/candidate.py +5 -1
  285. package/xll/python/Lib/site-packages/pip/_internal/models/link.py +53 -13
  286. package/xll/python/Lib/site-packages/pip/_internal/network/auth.py +38 -21
  287. package/xll/python/Lib/site-packages/pip/_internal/network/cache.py +2 -2
  288. package/xll/python/Lib/site-packages/pip/_internal/network/download.py +58 -11
  289. package/xll/python/Lib/site-packages/pip/_internal/network/session.py +35 -40
  290. package/xll/python/Lib/site-packages/pip/_internal/network/utils.py +109 -1
  291. package/xll/python/Lib/site-packages/pip/_internal/operations/check.py +2 -3
  292. package/xll/python/Lib/site-packages/pip/_internal/operations/install/wheel.py +23 -18
  293. package/xll/python/Lib/site-packages/pip/_internal/operations/prepare.py +152 -7
  294. package/xll/python/Lib/site-packages/pip/_internal/req/__init__.py +2 -0
  295. package/xll/python/Lib/site-packages/pip/_internal/req/constructors.py +54 -69
  296. package/xll/python/Lib/site-packages/pip/_internal/req/req_file.py +6 -6
  297. package/xll/python/Lib/site-packages/pip/_internal/req/req_install.py +25 -21
  298. package/xll/python/Lib/site-packages/pip/_internal/req/req_uninstall.py +13 -8
  299. package/xll/python/Lib/site-packages/pip/_internal/resolution/base.py +2 -2
  300. package/xll/python/Lib/site-packages/pip/_internal/resolution/legacy/resolver.py +2 -2
  301. package/xll/python/Lib/site-packages/pip/_internal/resolution/resolvelib/base.py +1 -1
  302. package/xll/python/Lib/site-packages/pip/_internal/resolution/resolvelib/candidates.py +0 -1
  303. package/xll/python/Lib/site-packages/pip/_internal/resolution/resolvelib/factory.py +39 -52
  304. package/xll/python/Lib/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py +3 -3
  305. package/xll/python/Lib/site-packages/pip/_internal/resolution/resolvelib/provider.py +3 -0
  306. package/xll/python/Lib/site-packages/pip/_internal/resolution/resolvelib/resolver.py +9 -0
  307. package/xll/python/Lib/site-packages/pip/_internal/utils/compat.py +15 -9
  308. package/xll/python/Lib/site-packages/pip/_internal/utils/deprecation.py +6 -1
  309. package/xll/python/Lib/site-packages/pip/_internal/utils/filesystem.py +2 -2
  310. package/xll/python/Lib/site-packages/pip/_internal/utils/logging.py +11 -3
  311. package/xll/python/Lib/site-packages/pip/_internal/utils/misc.py +48 -4
  312. package/xll/python/Lib/site-packages/pip/_internal/utils/pylock.py +18 -2
  313. package/xll/python/Lib/site-packages/pip/_internal/utils/retry.py +2 -1
  314. package/xll/python/Lib/site-packages/pip/_internal/utils/subprocess.py +4 -3
  315. package/xll/python/Lib/site-packages/pip/_internal/utils/temp_dir.py +1 -2
  316. package/xll/python/Lib/site-packages/pip/_internal/utils/unpacking.py +30 -4
  317. package/xll/python/Lib/site-packages/pip/_internal/utils/urls.py +5 -2
  318. package/xll/python/Lib/site-packages/pip/_internal/utils/virtualenv.py +2 -36
  319. package/xll/python/Lib/site-packages/pip/_internal/vcs/git.py +8 -5
  320. package/xll/python/Lib/site-packages/pip/_internal/vcs/versioncontrol.py +1 -2
  321. package/xll/python/Lib/site-packages/pip/_internal/wheel_builder.py +5 -1
  322. package/xll/python/Lib/site-packages/pip/_vendor/bom.cdx.json +231 -0
  323. package/xll/python/Lib/site-packages/pip/_vendor/certifi/__init__.py +1 -1
  324. package/xll/python/Lib/site-packages/pip/_vendor/certifi/cacert.pem +0 -631
  325. package/xll/python/Lib/site-packages/pip/_vendor/distlib/__init__.py +1 -1
  326. package/xll/python/Lib/site-packages/pip/_vendor/distlib/compat.py +34 -64
  327. package/xll/python/Lib/site-packages/pip/_vendor/distlib/resources.py +28 -14
  328. package/xll/python/Lib/site-packages/pip/_vendor/distlib/scripts.py +7 -3
  329. package/xll/python/Lib/site-packages/pip/_vendor/distlib/util.py +48 -11
  330. package/xll/python/Lib/site-packages/pip/_vendor/idna/LICENSE.md +1 -1
  331. package/xll/python/Lib/site-packages/pip/_vendor/idna/__main__.py +6 -0
  332. package/xll/python/Lib/site-packages/pip/_vendor/idna/cli.py +128 -0
  333. package/xll/python/Lib/site-packages/pip/_vendor/idna/codec.py +50 -13
  334. package/xll/python/Lib/site-packages/pip/_vendor/idna/compat.py +26 -0
  335. package/xll/python/Lib/site-packages/pip/_vendor/idna/core.py +352 -141
  336. package/xll/python/Lib/site-packages/pip/_vendor/idna/idnadata.py +571 -2983
  337. package/xll/python/Lib/site-packages/pip/_vendor/idna/intranges.py +5 -7
  338. package/xll/python/Lib/site-packages/pip/_vendor/idna/package_data.py +1 -1
  339. package/xll/python/Lib/site-packages/pip/_vendor/idna/uts46data.py +16887 -8832
  340. package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/__init__.py +352 -66
  341. package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/__main__.py +11 -0
  342. package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/_xdg.py +171 -0
  343. package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/android.py +92 -41
  344. package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/api.py +213 -49
  345. package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/macos.py +128 -51
  346. package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/unix.py +176 -127
  347. package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/version.py +8 -18
  348. package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/windows.py +185 -68
  349. package/xll/python/Lib/site-packages/pip/_vendor/pygments/__init__.py +2 -2
  350. package/xll/python/Lib/site-packages/pip/_vendor/pygments/__main__.py +1 -1
  351. package/xll/python/Lib/site-packages/pip/_vendor/pygments/console.py +1 -1
  352. package/xll/python/Lib/site-packages/pip/_vendor/pygments/filter.py +1 -1
  353. package/xll/python/Lib/site-packages/pip/_vendor/pygments/filters/__init__.py +10 -8
  354. package/xll/python/Lib/site-packages/pip/_vendor/pygments/formatter.py +1 -1
  355. package/xll/python/Lib/site-packages/pip/_vendor/pygments/formatters/__init__.py +1 -1
  356. package/xll/python/Lib/site-packages/pip/_vendor/pygments/lexer.py +7 -5
  357. package/xll/python/Lib/site-packages/pip/_vendor/pygments/lexers/__init__.py +1 -1
  358. package/xll/python/Lib/site-packages/pip/_vendor/pygments/lexers/_mapping.py +9 -8
  359. package/xll/python/Lib/site-packages/pip/_vendor/pygments/lexers/python.py +35 -32
  360. package/xll/python/Lib/site-packages/pip/_vendor/pygments/modeline.py +1 -1
  361. package/xll/python/Lib/site-packages/pip/_vendor/pygments/plugin.py +3 -1
  362. package/xll/python/Lib/site-packages/pip/_vendor/pygments/regexopt.py +13 -2
  363. package/xll/python/Lib/site-packages/pip/_vendor/pygments/scanner.py +1 -1
  364. package/xll/python/Lib/site-packages/pip/_vendor/pygments/sphinxext.py +1 -1
  365. package/xll/python/Lib/site-packages/pip/_vendor/pygments/style.py +1 -1
  366. package/xll/python/Lib/site-packages/pip/_vendor/pygments/styles/__init__.py +1 -1
  367. package/xll/python/Lib/site-packages/pip/_vendor/pygments/token.py +1 -1
  368. package/xll/python/Lib/site-packages/pip/_vendor/pygments/unistring.py +1 -1
  369. package/xll/python/Lib/site-packages/pip/_vendor/pygments/util.py +2 -2
  370. package/xll/python/Lib/site-packages/pip/_vendor/requests/__init__.py +52 -16
  371. package/xll/python/Lib/site-packages/pip/_vendor/requests/__version__.py +2 -2
  372. package/xll/python/Lib/site-packages/pip/_vendor/requests/_internal_utils.py +2 -2
  373. package/xll/python/Lib/site-packages/pip/_vendor/requests/_types.py +183 -0
  374. package/xll/python/Lib/site-packages/pip/_vendor/requests/adapters.py +101 -50
  375. package/xll/python/Lib/site-packages/pip/_vendor/requests/api.py +31 -8
  376. package/xll/python/Lib/site-packages/pip/_vendor/requests/auth.py +80 -40
  377. package/xll/python/Lib/site-packages/pip/_vendor/requests/compat.py +9 -3
  378. package/xll/python/Lib/site-packages/pip/_vendor/requests/cookies.py +143 -79
  379. package/xll/python/Lib/site-packages/pip/_vendor/requests/exceptions.py +15 -5
  380. package/xll/python/Lib/site-packages/pip/_vendor/requests/help.py +13 -10
  381. package/xll/python/Lib/site-packages/pip/_vendor/requests/hooks.py +23 -9
  382. package/xll/python/Lib/site-packages/pip/_vendor/requests/models.py +265 -126
  383. package/xll/python/Lib/site-packages/pip/_vendor/requests/py.typed +0 -0
  384. package/xll/python/Lib/site-packages/pip/_vendor/requests/sessions.py +164 -78
  385. package/xll/python/Lib/site-packages/pip/_vendor/requests/status_codes.py +2 -2
  386. package/xll/python/Lib/site-packages/pip/_vendor/requests/structures.py +51 -20
  387. package/xll/python/Lib/site-packages/pip/_vendor/requests/utils.py +161 -89
  388. package/xll/python/Lib/site-packages/pip/_vendor/tomli/__init__.py +1 -1
  389. package/xll/python/Lib/site-packages/pip/_vendor/tomli/_parser.py +9 -4
  390. package/xll/python/Lib/site-packages/pip/_vendor/tomli/_re.py +13 -9
  391. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/_base_connection.py +3 -1
  392. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/_collections.py +0 -1
  393. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/_version.py +8 -18
  394. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/connection.py +4 -4
  395. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/connectionpool.py +23 -10
  396. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/contrib/emscripten/response.py +5 -1
  397. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py +7 -8
  398. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/contrib/socks.py +1 -1
  399. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/exceptions.py +2 -2
  400. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/fields.py +14 -14
  401. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/poolmanager.py +8 -6
  402. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/response.py +35 -22
  403. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/util/retry.py +8 -0
  404. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/util/ssl_.py +11 -61
  405. package/xll/python/Lib/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py +5 -11
  406. package/xll/python/Lib/site-packages/pip/_vendor/vendor.txt +8 -8
  407. package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/METADATA +3 -2
  408. package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/RECORD +208 -188
  409. package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/AUTHORS.txt +20 -0
  410. package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/idna/LICENSE.md +1 -1
  411. package/xll/python/Lib/site-packages/pywin32-311.dist-info/RECORD +2 -2
  412. package/xll/python/Scripts/httpx.exe +0 -0
  413. package/xll/python/Scripts/idna.exe +0 -0
  414. package/xll/python/Scripts/pip.exe +0 -0
  415. package/xll/python/Scripts/pip3.13.exe +0 -0
  416. package/xll/python/Scripts/pip3.exe +0 -0
  417. package/xll/python/Scripts/pywin32_postinstall.exe +0 -0
  418. package/xll/python/Scripts/pywin32_testall.exe +0 -0
  419. package/dist/app/collab/awareness.d.ts +0 -32
  420. package/dist/app/collab/awareness.js +0 -52
  421. package/dist/app/collab/collab-client.d.ts +0 -37
  422. package/dist/app/collab/collab-client.js +0 -208
  423. package/dist/app/collab/collab-manager.d.ts +0 -91
  424. package/dist/app/collab/collab-manager.js +0 -218
  425. package/dist/app/collab/collab-sync.d.ts +0 -62
  426. package/dist/app/collab/collab-sync.js +0 -215
  427. package/dist/app/collab/index.d.ts +0 -9
  428. package/dist/app/collab/index.js +0 -6
  429. package/dist/app/collab/super-fight.d.ts +0 -90
  430. package/dist/app/collab/super-fight.js +0 -310
  431. package/dist/app/collab/sync-bridge.d.ts +0 -35
  432. package/dist/app/collab/sync-bridge.js +0 -109
  433. package/dist/app/collab/types.d.ts +0 -75
  434. package/dist/app/collab/types.js +0 -5
  435. package/dist/embedded-agent/ai-content.d.ts +0 -52
  436. package/dist/embedded-agent/ai-content.js +0 -101
  437. package/dist/embedded-agent/host-tools/shared/llm-stream.d.ts +0 -31
  438. package/dist/embedded-agent/host-tools/shared/llm-stream.js +0 -136
  439. package/dist/embedded-agent/model-call-orchestrator.d.ts +0 -22
  440. package/dist/embedded-agent/model-call-orchestrator.js +0 -22
  441. package/dist/embedded-agent/stream-errors.d.ts +0 -10
  442. package/dist/embedded-agent/stream-errors.js +0 -73
  443. package/dist/embedded-agent/stream-message-state.d.ts +0 -14
  444. package/dist/embedded-agent/stream-message-state.js +0 -271
  445. package/dist/embedded-agent/stream-sse.d.ts +0 -78
  446. package/dist/embedded-agent/stream-sse.js +0 -73
  447. package/dist/shell/approvals/task-spawn-approval.d.ts +0 -20
  448. package/dist/shell/approvals/task-spawn-approval.js +0 -93
  449. package/dist/shell/interactive/collab-command.d.ts +0 -9
  450. package/dist/shell/interactive/collab-command.js +0 -115
  451. package/dist/shell/interactive/super-fight-ui.d.ts +0 -80
  452. package/dist/shell/interactive/super-fight-ui.js +0 -484
  453. package/dist/shell/status/collab-status.d.ts +0 -18
  454. package/dist/shell/status/collab-status.js +0 -46
  455. package/xll/python/Lib/site-packages/pip/_internal/build_env.py +0 -606
  456. /package/dist/{tui → autocomplete}/skill-autocomplete.js +0 -0
  457. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/INSTALLER +0 -0
  458. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/REQUESTED +0 -0
  459. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/WHEEL +0 -0
  460. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/entry_points.txt +0 -0
  461. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/LICENSE.txt +0 -0
  462. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +0 -0
  463. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/certifi/LICENSE +0 -0
  464. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/distlib/LICENSE.txt +0 -0
  465. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/distro/LICENSE +0 -0
  466. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/msgpack/COPYING +0 -0
  467. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE +0 -0
  468. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +0 -0
  469. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE.BSD +0 -0
  470. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/pkg_resources/LICENSE +0 -0
  471. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/platformdirs/LICENSE +0 -0
  472. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/pygments/LICENSE +0 -0
  473. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +0 -0
  474. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/requests/LICENSE +0 -0
  475. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/resolvelib/LICENSE +0 -0
  476. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/rich/LICENSE +0 -0
  477. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/tomli/LICENSE +0 -0
  478. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/tomli_w/LICENSE +0 -0
  479. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/truststore/LICENSE +0 -0
  480. /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/urllib3/LICENSE.txt +0 -0
@@ -12,8 +12,6 @@ from collections.abc import Iterable
12
12
  from dataclasses import dataclass
13
13
  from typing import (
14
14
  TYPE_CHECKING,
15
- Optional,
16
- Union,
17
15
  )
18
16
 
19
17
  from pip._vendor.packaging import specifiers
@@ -49,15 +47,15 @@ from pip._internal.utils.packaging import check_requires_python
49
47
  from pip._internal.utils.unpacking import SUPPORTED_EXTENSIONS
50
48
 
51
49
  if TYPE_CHECKING:
52
- from typing_extensions import TypeGuard
50
+ from typing import TypeGuard
53
51
 
54
52
  __all__ = ["FormatControl", "BestCandidateResult", "PackageFinder"]
55
53
 
56
54
 
57
55
  logger = getLogger(__name__)
58
56
 
59
- BuildTag = Union[tuple[()], tuple[int, str]]
60
- CandidateSortingKey = tuple[int, int, int, _BaseVersion, Optional[int], BuildTag]
57
+ BuildTag = tuple[()] | tuple[int, str]
58
+ CandidateSortingKey = tuple[int, int, int, _BaseVersion, int | None, BuildTag]
61
59
 
62
60
 
63
61
  def _check_link_requires_python(
@@ -664,6 +662,9 @@ class PackageFinder:
664
662
  BestCandidateResult,
665
663
  ] = {}
666
664
 
665
+ # projects for which a link is locked from a pylock
666
+ self._locked_links: dict[NormalizedName, Link] = {}
667
+
667
668
  # Don't include an allow_yanked default value to make sure each call
668
669
  # site considers whether yanked releases are allowed. This also causes
669
670
  # that decision to be made explicit in the calling code, which helps
@@ -724,10 +725,18 @@ class PackageFinder:
724
725
  def index_urls(self) -> list[str]:
725
726
  return self.search_scope.index_urls
726
727
 
728
+ @property
729
+ def refresh_package(self) -> set[str]:
730
+ return self._link_collector.session.refresh_package
731
+
727
732
  @property
728
733
  def proxy(self) -> str | None:
729
734
  return self._link_collector.session.pip_proxy
730
735
 
736
+ @property
737
+ def no_proxy_env(self) -> bool:
738
+ return self._link_collector.session.pip_no_proxy_env
739
+
731
740
  @property
732
741
  def trusted_hosts(self) -> Iterable[str]:
733
742
  for host_port in self._link_collector.session.pip_trusted_origins:
@@ -851,7 +860,9 @@ class PackageFinder:
851
860
  "Fetching project page and analyzing links: %s",
852
861
  project_url,
853
862
  )
854
- index_response = self._link_collector.fetch_response(project_url)
863
+ index_response = self._link_collector.fetch_response(
864
+ project_url, package_name=link_evaluator.project_name
865
+ )
855
866
  if index_response is None:
856
867
  return []
857
868
 
@@ -868,7 +879,8 @@ class PackageFinder:
868
879
  def find_all_candidates(self, project_name: str) -> list[InstallationCandidate]:
869
880
  """Find all available InstallationCandidate for project_name
870
881
 
871
- This checks index_urls and find_links.
882
+ This checks index_urls and find_links, unless a locked link is known
883
+ for that project.
872
884
  All versions found are returned as an InstallationCandidate list.
873
885
 
874
886
  See LinkEvaluator.evaluate_link() for details on which files
@@ -879,6 +891,23 @@ class PackageFinder:
879
891
 
880
892
  link_evaluator = self.make_link_evaluator(project_name)
881
893
 
894
+ if locked_link := self._locked_links.get(canonicalize_name(project_name)):
895
+ # If a locked link is known for that project, do not check
896
+ # index_urls nor find_links. We don't use get_install_candidate here,
897
+ # because if a locked link is unsupported (due to format control,
898
+ # release control or otherwise), we want to error out immediately
899
+ # instead of ignoring it.
900
+ result, detail = link_evaluator.evaluate_link(locked_link)
901
+ if result != LinkType.candidate:
902
+ raise InstallationError(
903
+ f"Could not install locked package {project_name!r} "
904
+ f"from {locked_link.comes_from!r}: {detail}"
905
+ )
906
+ self._all_candidates[project_name] = [
907
+ InstallationCandidate(project_name, detail, locked_link, locked=True)
908
+ ]
909
+ return self._all_candidates[project_name]
910
+
882
911
  collected_sources = self._link_collector.collect_sources(
883
912
  project_name=project_name,
884
913
  candidates_from_page=functools.partial(
@@ -1068,6 +1097,16 @@ class PackageFinder:
1068
1097
  )
1069
1098
  raise BestVersionAlreadyInstalled
1070
1099
 
1100
+ def add_locked_link(self, project_name: NormalizedName, locked_link: Link) -> None:
1101
+ assert not self._all_candidates
1102
+ if project_name in self._locked_links:
1103
+ raise InstallationError(
1104
+ f"Multiple locked links provided for {project_name}: "
1105
+ f"{self._locked_links[project_name]} and {locked_link}"
1106
+ )
1107
+
1108
+ self._locked_links[project_name] = locked_link
1109
+
1071
1110
 
1072
1111
  def _find_name_version_sep(fragment: str, canonical_name: str) -> int:
1073
1112
  """Find the separator's index based on the package's canonical name.
@@ -4,8 +4,7 @@ import logging
4
4
  import mimetypes
5
5
  import os
6
6
  from collections import defaultdict
7
- from collections.abc import Iterable
8
- from typing import Callable
7
+ from collections.abc import Callable, Iterable
9
8
 
10
9
  from pip._vendor.packaging.utils import (
11
10
  InvalidSdistFilename,
@@ -4,7 +4,7 @@ import logging
4
4
  import os
5
5
  import sys
6
6
  import sysconfig
7
- from typing import Callable
7
+ from collections.abc import Callable
8
8
 
9
9
  from pip._internal.exceptions import InvalidSchemeCombination, UserInstallationInvalid
10
10
  from pip._internal.models.scheme import SCHEME_KEYS, Scheme
@@ -41,7 +41,7 @@ def change_root(new_root: str, pathname: str) -> str:
41
41
  return os.path.join(new_root, pathname[1:])
42
42
 
43
43
  elif os.name == "nt":
44
- (drive, path) = os.path.splitdrive(pathname)
44
+ drive, path = os.path.splitdrive(pathname)
45
45
  if path[0] == "\\":
46
46
  path = path[1:]
47
47
  return os.path.join(new_root, path)
@@ -14,7 +14,6 @@ from typing import (
14
14
  Any,
15
15
  NamedTuple,
16
16
  Protocol,
17
- Union,
18
17
  )
19
18
 
20
19
  from pip._vendor.packaging.requirements import Requirement
@@ -29,14 +28,21 @@ from pip._internal.models.direct_url import (
29
28
  DirectUrl,
30
29
  DirectUrlValidationError,
31
30
  )
32
- from pip._internal.utils.compat import stdlib_pkgs # TODO: Move definition here.
33
31
  from pip._internal.utils.egg_link import egg_link_path_from_sys_path
34
32
  from pip._internal.utils.misc import is_local, normalize_path
35
33
  from pip._internal.utils.urls import url_to_path
36
34
 
37
35
  from ._json import msg_to_json
38
36
 
39
- InfoPath = Union[str, pathlib.PurePath]
37
+ # packages in the stdlib that may have installation metadata, but should not be
38
+ # considered 'installed'. this theoretically could be determined based on
39
+ # dist.location (py27:`sysconfig.get_paths()['stdlib']`,
40
+ # py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may
41
+ # make this ineffective, so hard-coding
42
+ stdlib_pkgs = {"python", "wsgiref", "argparse"}
43
+
44
+
45
+ InfoPath = str | pathlib.PurePath
40
46
 
41
47
  logger = logging.getLogger(__name__)
42
48
 
@@ -152,14 +158,13 @@ class BaseDistribution(Protocol):
152
158
  """
153
159
  raise NotImplementedError()
154
160
 
155
- @property
161
+ @functools.cached_property
156
162
  def editable_project_location(self) -> str | None:
157
163
  """The project location for editable distributions.
158
164
 
159
165
  This is the directory where pyproject.toml or setup.py is located.
160
166
  None if the distribution is not installed in editable mode.
161
167
  """
162
- # TODO: this property is relatively costly to compute, memoize it ?
163
168
  direct_url = self.direct_url
164
169
  if direct_url:
165
170
  if direct_url.is_local_editable():
@@ -177,7 +177,7 @@ class Distribution(BaseDistribution):
177
177
 
178
178
  @property
179
179
  def raw_version(self) -> str:
180
- return self._dist.version
180
+ return self.metadata["Version"]
181
181
 
182
182
  def is_file(self, path: InfoPath) -> bool:
183
183
  return self._dist.read_text(str(path)) is not None
@@ -7,7 +7,6 @@ import pathlib
7
7
  import sys
8
8
  import zipfile
9
9
  from collections.abc import Iterator, Sequence
10
- from typing import Optional
11
10
 
12
11
  from pip._vendor.packaging.utils import (
13
12
  InvalidWheelFilename,
@@ -24,6 +23,10 @@ from ._dists import Distribution
24
23
 
25
24
  logger = logging.getLogger(__name__)
26
25
 
26
+ # Used to avoid emitting duplicate invalid distribution metadata warnings for
27
+ # the same dist-info directory.
28
+ _warned_bad_metadata: set[BasePath | None] = set()
29
+
27
30
 
28
31
  def _looks_like_wheel(location: str) -> bool:
29
32
  if not location.endswith(WHEEL_EXTENSION):
@@ -50,7 +53,7 @@ class _DistributionFinder:
50
53
  installations as well. It's useful feature, after all.
51
54
  """
52
55
 
53
- FoundResult = tuple[importlib.metadata.Distribution, Optional[BasePath]]
56
+ FoundResult = tuple[importlib.metadata.Distribution, BasePath | None]
54
57
 
55
58
  def __init__(self) -> None:
56
59
  self._found_names: set[NormalizedName] = set()
@@ -69,7 +72,9 @@ class _DistributionFinder:
69
72
  try:
70
73
  name = get_dist_canonical_name(dist)
71
74
  except BadMetadata as e:
72
- logger.warning("Skipping %s due to %s", info_location, e.reason)
75
+ if info_location not in _warned_bad_metadata:
76
+ logger.warning("Skipping %s due to %s", info_location, e.reason)
77
+ _warned_bad_metadata.add(info_location)
73
78
  continue
74
79
  if name in self._found_names:
75
80
  continue
@@ -13,11 +13,15 @@ class InstallationCandidate:
13
13
  name: str
14
14
  version: Version
15
15
  link: Link
16
+ locked: bool
16
17
 
17
- def __init__(self, name: str, version: str, link: Link) -> None:
18
+ def __init__(
19
+ self, name: str, version: str, link: Link, locked: bool = False
20
+ ) -> None:
18
21
  object.__setattr__(self, "name", name)
19
22
  object.__setattr__(self, "version", parse_version(version))
20
23
  object.__setattr__(self, "link", link)
24
+ object.__setattr__(self, "locked", locked)
21
25
 
22
26
  def __str__(self) -> str:
23
27
  return f"{self.name!r} candidate (version {self.version} at {self.link})"
@@ -8,12 +8,12 @@ import os
8
8
  import posixpath
9
9
  import re
10
10
  import urllib.parse
11
- import urllib.request
12
11
  from collections.abc import Mapping
13
12
  from dataclasses import dataclass
14
13
  from typing import (
15
14
  Any,
16
15
  NamedTuple,
16
+ NewType,
17
17
  )
18
18
 
19
19
  from pip._internal.exceptions import InvalidEggFragment
@@ -31,6 +31,49 @@ from pip._internal.utils.urls import path_to_url, url_to_path
31
31
  logger = logging.getLogger(__name__)
32
32
 
33
33
 
34
+ # A single path component: percent-decoded once and reduced to a basename, so it
35
+ # contains no path separator and is not a ``.`` or ``..`` reference. The empty
36
+ # string means "no component".
37
+ PathComponent = NewType("PathComponent", str)
38
+
39
+
40
+ def _to_path_component(name: str) -> PathComponent:
41
+ """Reduce ``name`` to a single path component, or ``""`` if it has none.
42
+
43
+ ``os.path.basename`` drops any directory part, drive letter, or separator;
44
+ a ``.``, ``..``, or empty result is not a component and becomes ``""``.
45
+ """
46
+ name = os.path.basename(name)
47
+ if name in ("", os.curdir, os.pardir):
48
+ return PathComponent("")
49
+
50
+ return PathComponent(name)
51
+
52
+
53
+ def as_path_component(name: str) -> PathComponent:
54
+ """Like ``_to_path_component`` but reject the empty result.
55
+
56
+ Use where a file is about to be written, so a missing name is an error
57
+ rather than a silent fallback to the directory itself.
58
+ """
59
+ component = _to_path_component(name)
60
+ if not component:
61
+ raise ValueError(f"Unexpected file name derived from URL: {name!r}")
62
+
63
+ return component
64
+
65
+
66
+ def join_within_directory(directory: str, component: PathComponent) -> str:
67
+ """Join a single path ``component`` onto ``directory``.
68
+
69
+ ``component`` is a :data:`PathComponent`, so by type it has no separator and
70
+ is not a ``.`` or ``..`` reference; the result can never escape ``directory``.
71
+ Requiring ``PathComponent`` rather than ``str`` lets the type checker enforce
72
+ at the call site that the name was reduced to a safe component beforehand.
73
+ """
74
+ return os.path.join(directory, component)
75
+
76
+
34
77
  # Order matters, earlier hashes have a precedence over later hashes for what
35
78
  # we will pick to use.
36
79
  _SUPPORTED_HASHES = ("sha512", "sha384", "sha256", "sha224", "sha1", "md5")
@@ -125,6 +168,8 @@ def _clean_file_url_path(part: str) -> str:
125
168
  Clean the first part of a URL path that corresponds to a local
126
169
  filesystem path (i.e. the first part after splitting on "@" characters).
127
170
  """
171
+ import urllib.request
172
+
128
173
  # We unquote prior to quoting to make sure nothing is double quoted.
129
174
  # Also, on Windows the path part might contain a drive letter which
130
175
  # should not be quoted. On Linux where drive letters do not
@@ -423,18 +468,13 @@ class Link:
423
468
  return redact_auth_from_url(self.url)
424
469
 
425
470
  @property
426
- def filename(self) -> str:
427
- path = self.path.rstrip("/")
428
- name = posixpath.basename(path)
429
- if not name:
430
- # Make sure we don't leak auth information if the netloc
431
- # includes a username and password.
432
- netloc, user_pass = split_auth_from_netloc(self.netloc)
433
- return netloc
434
-
435
- name = urllib.parse.unquote(name)
436
- assert name, f"URL {self._url!r} produced no filename"
437
- return name
471
+ def filename(self) -> PathComponent:
472
+ name = _to_path_component(posixpath.basename(self.path.rstrip("/")))
473
+ if name:
474
+ return name
475
+
476
+ # No component in the path; fall back to the netloc, dropping any auth.
477
+ return _to_path_component(split_auth_from_netloc(self.netloc)[0])
438
478
 
439
479
  @property
440
480
  def file_path(self) -> str:
@@ -6,6 +6,7 @@ providing credentials in the context of network requests.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
+ import json
9
10
  import logging
10
11
  import os
11
12
  import shutil
@@ -118,34 +119,48 @@ class KeyRingCliProvider(KeyRingBaseProvider):
118
119
  self.keyring = cmd
119
120
 
120
121
  def get_auth_info(self, url: str, username: str | None) -> AuthInfo | None:
121
- # This is the default implementation of keyring.get_credential
122
- # https://github.com/jaraco/keyring/blob/97689324abcf01bd1793d49063e7ca01e03d7d07/keyring/backend.py#L134-L139
123
- if username is not None:
124
- password = self._get_password(url, username)
125
- if password is not None:
126
- return username, password
127
- return None
122
+ return self._get_creds(url, username)
128
123
 
129
124
  def save_auth_info(self, url: str, username: str, password: str) -> None:
130
125
  return self._set_password(url, username, password)
131
126
 
132
- def _get_password(self, service_name: str, username: str) -> str | None:
133
- """Mirror the implementation of keyring.get_password using cli"""
127
+ def _get_creds(self, service_name: str, username: str | None) -> AuthInfo | None:
128
+ """Mirror the implementation of keyring.get_credential using cli"""
134
129
  if self.keyring is None:
135
130
  return None
136
131
 
137
- cmd = [self.keyring, "get", service_name, username]
132
+ cmd = [self.keyring, "--mode=creds", "--output=json", "get", service_name]
133
+ if username is not None:
134
+ cmd.append(username)
135
+
138
136
  env = os.environ.copy()
139
137
  env["PYTHONIOENCODING"] = "utf-8"
140
- res = subprocess.run(
138
+ res = subprocess.run( # noqa: UP022
141
139
  cmd,
142
140
  stdin=subprocess.DEVNULL,
143
141
  stdout=subprocess.PIPE,
142
+ stderr=subprocess.PIPE,
144
143
  env=env,
145
144
  )
145
+
146
+ # Detect if the user is running an outdated version of keyring without support
147
+ # for querying credentials without username
148
+ errs = res.stderr.decode("utf-8")
149
+ if (
150
+ res.returncode == 2
151
+ and "unrecognized arguments" in errs
152
+ and "--mode=creds" in errs
153
+ ):
154
+ raise RuntimeError(
155
+ "Keyring util is outdated; must be at least version 25.2.1, "
156
+ "please upgrade it"
157
+ )
158
+
146
159
  if res.returncode:
147
160
  return None
148
- return res.stdout.decode("utf-8").strip(os.linesep)
161
+
162
+ data = json.loads(res.stdout.decode("utf-8"))
163
+ return (data["username"], data["password"])
149
164
 
150
165
  def _set_password(self, service_name: str, username: str, password: str) -> None:
151
166
  """Mirror the implementation of keyring.set_password using cli"""
@@ -487,15 +502,17 @@ class MultiDomainBasicAuth(AuthBase):
487
502
  if resp.status_code != 401:
488
503
  return resp
489
504
 
490
- username, password = None, None
491
-
492
- # Query the keyring for credentials:
493
- if self.use_keyring:
494
- username, password = self._get_new_credentials(
495
- resp.url,
496
- allow_netrc=False,
497
- allow_keyring=True,
498
- )
505
+ # Look for credentials for the (possibly redirected) URL. Credentials
506
+ # embedded in the URL -- e.g. carried in the ``Location`` of a
507
+ # cross-origin redirect, whose ``Authorization`` header requests strips
508
+ # -- are always honoured, since recovering them needs no user
509
+ # interaction. Keyring is only consulted when it is enabled, because it
510
+ # may require interaction and is therefore disabled under --no-input.
511
+ username, password = self._get_new_credentials(
512
+ resp.url,
513
+ allow_netrc=False,
514
+ allow_keyring=self.use_keyring,
515
+ )
499
516
 
500
517
  # We are not able to prompt the user so simply return the response
501
518
  if not self.prompting and not username and not password:
@@ -4,10 +4,10 @@ from __future__ import annotations
4
4
 
5
5
  import os
6
6
  import shutil
7
- from collections.abc import Generator
7
+ from collections.abc import Callable, Generator
8
8
  from contextlib import contextmanager
9
9
  from datetime import datetime
10
- from typing import Any, BinaryIO, Callable
10
+ from typing import Any, BinaryIO
11
11
 
12
12
  from pip._vendor.cachecontrol.cache import SeparateBodyBaseCache
13
13
  from pip._vendor.cachecontrol.caches import SeparateBodyFileCache
@@ -15,11 +15,23 @@ from pip._vendor.requests import PreparedRequest
15
15
  from pip._vendor.requests.models import Response
16
16
  from pip._vendor.urllib3 import HTTPResponse as URLlib3Response
17
17
  from pip._vendor.urllib3._collections import HTTPHeaderDict
18
- from pip._vendor.urllib3.exceptions import ReadTimeoutError
18
+ from pip._vendor.urllib3.exceptions import ProtocolError, ReadTimeoutError
19
19
 
20
20
  from pip._internal.cli.progress_bars import BarType, get_download_progress_renderer
21
- from pip._internal.exceptions import IncompleteDownloadError, NetworkConnectionError
22
- from pip._internal.models.link import Link
21
+ from pip._internal.exceptions import (
22
+ ConnectionFailedError,
23
+ ConnectionTimeoutError,
24
+ IncompleteDownloadError,
25
+ NetworkConnectionError,
26
+ ProxyConnectionError,
27
+ SSLVerificationError,
28
+ )
29
+ from pip._internal.models.link import (
30
+ Link,
31
+ PathComponent,
32
+ as_path_component,
33
+ join_within_directory,
34
+ )
23
35
  from pip._internal.network.cache import SafeFileCache, is_from_cache
24
36
  from pip._internal.network.session import CacheControlAdapter, PipSession
25
37
  from pip._internal.network.utils import HEADERS, raise_for_status, response_chunks
@@ -30,9 +42,14 @@ logger = logging.getLogger(__name__)
30
42
 
31
43
  def _get_http_response_size(resp: Response) -> int | None:
32
44
  try:
33
- return int(resp.headers["content-length"])
45
+ size = int(resp.headers["content-length"])
34
46
  except (ValueError, KeyError, TypeError):
35
47
  return None
48
+ # A negative length would make _FileDownload.is_incomplete() report a
49
+ # truncated download as complete, so treat it as unknown instead.
50
+ if size < 0:
51
+ return None
52
+ return size
36
53
 
37
54
 
38
55
  def _get_http_response_etag_or_last_modified(resp: Response) -> str | None:
@@ -116,11 +133,14 @@ def parse_content_disposition(content_disposition: str, default_filename: str) -
116
133
  return filename or default_filename
117
134
 
118
135
 
119
- def _get_http_response_filename(resp: Response, link: Link) -> str:
136
+ def _get_http_response_filename(resp: Response, link: Link) -> PathComponent:
120
137
  """Get an ideal filename from the given HTTP response, falling back to
121
138
  the link filename if not provided.
139
+
140
+ The result is validated as a single path component, so it can be joined onto
141
+ a download directory without escaping it.
122
142
  """
123
- filename = link.filename # fallback
143
+ filename: str = link.filename # fallback
124
144
  # Have a look at the Content-Disposition header for a better guess
125
145
  content_disposition = resp.headers.get("content-disposition")
126
146
  if content_disposition:
@@ -134,7 +154,7 @@ def _get_http_response_filename(resp: Response, link: Link) -> str:
134
154
  ext = os.path.splitext(resp.url)[1]
135
155
  if ext:
136
156
  filename += ext
137
- return filename
157
+ return as_path_component(filename)
138
158
 
139
159
 
140
160
  @dataclass
@@ -187,7 +207,9 @@ class Downloader:
187
207
  resp = self._http_get(link)
188
208
  download_size = _get_http_response_size(resp)
189
209
 
190
- filepath = os.path.join(location, _get_http_response_filename(resp, link))
210
+ filepath = join_within_directory(
211
+ location, _get_http_response_filename(resp, link)
212
+ )
191
213
  with open(filepath, "wb") as content_file:
192
214
  download = _FileDownload(link, content_file, download_size)
193
215
  self._process_response(download, resp)
@@ -209,12 +231,12 @@ class Downloader:
209
231
  try:
210
232
  for chunk in chunks:
211
233
  download.write_chunk(chunk)
212
- except ReadTimeoutError as e:
234
+ except (ReadTimeoutError, ProtocolError) as e:
213
235
  # If the download size is not known, then give up downloading the file.
214
236
  if download.size is None:
215
237
  raise e
216
238
 
217
- logger.warning("Connection timed out while downloading.")
239
+ logger.warning("Connection interrupted while downloading.")
218
240
 
219
241
  def _attempt_resumes_or_redownloads(
220
242
  self, download: _FileDownload, first_resp: Response
@@ -241,9 +263,34 @@ class Downloader:
241
263
  download.reset_file()
242
264
  download.size = _get_http_response_size(resume_resp)
243
265
  first_resp = resume_resp
266
+ else:
267
+ # If the resume request starts at the wrong location, fail
268
+ # outright since the server is misbehaving.
269
+ content_range = resume_resp.headers.get("Content-Range", "")
270
+ resumed_at = content_range.lower().partition("bytes ")[2]
271
+ resumed_at = resumed_at.partition("-")[0]
272
+ if resumed_at and resumed_at != str(download.bytes_received):
273
+ raise IncompleteDownloadError(download)
244
274
 
245
275
  self._process_response(download, resume_resp)
246
- except (ConnectionError, ReadTimeoutError, OSError):
276
+ except (
277
+ ConnectionFailedError,
278
+ ConnectionTimeoutError,
279
+ ProxyConnectionError,
280
+ SSLVerificationError,
281
+ ReadTimeoutError,
282
+ ProtocolError,
283
+ OSError,
284
+ ):
285
+ # The error handling here is tricky, a few notes:
286
+ #
287
+ # - The diagnostic connection errors are raised by our custom
288
+ # requests.request() connection exception handler.
289
+ # - ProtocolError is raised by urllib3 when the returned data length
290
+ # doesn't match the response Content-Length.
291
+ # - ReadTimeoutError / ProtocolError come straight from urllib3 (via
292
+ # process_response) and aren't caught by our connection exception
293
+ # handler since they occur while *streaming* a response.
247
294
  continue
248
295
 
249
296
  # No more resume attempts. Raise an error if the download is still incomplete.