@kr78/pi-coding-agent 17.2.10

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 (1593) hide show
  1. package/CHANGELOG.md +14861 -0
  2. package/README.md +35 -0
  3. package/dist/CHANGELOG-chtdxh1z.md +14861 -0
  4. package/dist/cli.js +20483 -0
  5. package/dist/template-c2hyaytt.js +1653 -0
  6. package/dist/template-f8wx9vfn.css +1355 -0
  7. package/dist/template-qat058wr.html +55 -0
  8. package/dist/tool-views.generated-jdfmzwmn.js +35 -0
  9. package/examples/README.md +21 -0
  10. package/examples/custom-tools/README.md +104 -0
  11. package/examples/custom-tools/hello/index.ts +20 -0
  12. package/examples/extensions/README.md +142 -0
  13. package/examples/extensions/api-demo.ts +78 -0
  14. package/examples/extensions/chalk-logger.ts +25 -0
  15. package/examples/extensions/hello.ts +31 -0
  16. package/examples/extensions/pirate.ts +43 -0
  17. package/examples/extensions/plan-mode.ts +549 -0
  18. package/examples/extensions/reload-runtime.ts +38 -0
  19. package/examples/extensions/thinking-note.ts +13 -0
  20. package/examples/extensions/tools.ts +145 -0
  21. package/examples/extensions/with-deps/index.ts +36 -0
  22. package/examples/extensions/with-deps/package-lock.json +31 -0
  23. package/examples/extensions/with-deps/package.json +17 -0
  24. package/examples/hooks/README.md +56 -0
  25. package/examples/hooks/auto-commit-on-exit.ts +48 -0
  26. package/examples/hooks/confirm-destructive.ts +58 -0
  27. package/examples/hooks/custom-compaction.ts +115 -0
  28. package/examples/hooks/dirty-repo-guard.ts +51 -0
  29. package/examples/hooks/file-trigger.ts +40 -0
  30. package/examples/hooks/git-checkpoint.ts +52 -0
  31. package/examples/hooks/handoff.ts +149 -0
  32. package/examples/hooks/permission-gate.ts +33 -0
  33. package/examples/hooks/protected-paths.ts +29 -0
  34. package/examples/hooks/qna.ts +118 -0
  35. package/examples/hooks/status-line.ts +39 -0
  36. package/examples/sdk/01-minimal.ts +21 -0
  37. package/examples/sdk/02-custom-model.ts +49 -0
  38. package/examples/sdk/03-custom-prompt.ts +46 -0
  39. package/examples/sdk/04-skills.ts +43 -0
  40. package/examples/sdk/06-extensions.ts +82 -0
  41. package/examples/sdk/06-hooks.ts +61 -0
  42. package/examples/sdk/07-context-files.ts +35 -0
  43. package/examples/sdk/08-prompt-templates.ts +41 -0
  44. package/examples/sdk/08-slash-commands.ts +46 -0
  45. package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
  46. package/examples/sdk/11-sessions.ts +47 -0
  47. package/examples/sdk/12-redis-sessions.ts +54 -0
  48. package/examples/sdk/13-sql-sessions.ts +61 -0
  49. package/examples/sdk/README.md +169 -0
  50. package/package.json +587 -0
  51. package/scripts/bench-guard.ts +71 -0
  52. package/scripts/bench-title-models.ts +332 -0
  53. package/scripts/build-binary.ts +117 -0
  54. package/scripts/bundle-dist.ts +123 -0
  55. package/scripts/compile-binary.ts +69 -0
  56. package/scripts/embed-mupdf-wasm.ts +67 -0
  57. package/scripts/format-prompts.ts +68 -0
  58. package/scripts/generate-aria-snapshot.ts +134 -0
  59. package/scripts/generate-docs-index.ts +58 -0
  60. package/scripts/generate-share-viewer.ts +34 -0
  61. package/scripts/legacy-pi-virtual-module.ts +205 -0
  62. package/scripts/measure-prompt-tokens.ts +63 -0
  63. package/scripts/omp +51 -0
  64. package/scripts/omp.ts +19 -0
  65. package/scripts/security-compare.ts +40 -0
  66. package/src/advisor/advise-tool.ts +234 -0
  67. package/src/advisor/config.ts +341 -0
  68. package/src/advisor/emission-guard.ts +172 -0
  69. package/src/advisor/index.ts +6 -0
  70. package/src/advisor/runtime.ts +1412 -0
  71. package/src/advisor/transcript-recorder.ts +215 -0
  72. package/src/advisor/watchdog.ts +135 -0
  73. package/src/async/index.ts +1 -0
  74. package/src/async/job-manager.ts +847 -0
  75. package/src/auto-thinking/classifier.ts +220 -0
  76. package/src/autolearn/controller.ts +152 -0
  77. package/src/autolearn/managed-skills.ts +255 -0
  78. package/src/autoresearch/command-resume.md +14 -0
  79. package/src/autoresearch/dashboard.ts +436 -0
  80. package/src/autoresearch/git.ts +331 -0
  81. package/src/autoresearch/helpers.ts +218 -0
  82. package/src/autoresearch/index.ts +541 -0
  83. package/src/autoresearch/prompt-setup.md +43 -0
  84. package/src/autoresearch/prompt.md +103 -0
  85. package/src/autoresearch/resume-message.md +10 -0
  86. package/src/autoresearch/state.ts +273 -0
  87. package/src/autoresearch/storage.ts +700 -0
  88. package/src/autoresearch/tools/init-experiment.ts +268 -0
  89. package/src/autoresearch/tools/log-experiment.ts +520 -0
  90. package/src/autoresearch/tools/run-experiment.ts +407 -0
  91. package/src/autoresearch/tools/update-notes.ts +109 -0
  92. package/src/autoresearch/types.ts +168 -0
  93. package/src/capability/context-file.ts +44 -0
  94. package/src/capability/extension-module.ts +34 -0
  95. package/src/capability/extension.ts +47 -0
  96. package/src/capability/fs.ts +117 -0
  97. package/src/capability/hook.ts +40 -0
  98. package/src/capability/index.ts +467 -0
  99. package/src/capability/instruction.ts +37 -0
  100. package/src/capability/mcp.ts +115 -0
  101. package/src/capability/prompt.ts +35 -0
  102. package/src/capability/rule-buckets.ts +66 -0
  103. package/src/capability/rule.ts +298 -0
  104. package/src/capability/settings.ts +34 -0
  105. package/src/capability/skill.ts +69 -0
  106. package/src/capability/slash-command.ts +40 -0
  107. package/src/capability/ssh.ts +41 -0
  108. package/src/capability/system-prompt.ts +34 -0
  109. package/src/capability/tool.ts +38 -0
  110. package/src/capability/types.ts +187 -0
  111. package/src/cleanse/agent.ts +226 -0
  112. package/src/cleanse/balance.ts +79 -0
  113. package/src/cleanse/checkers.ts +996 -0
  114. package/src/cleanse/index.ts +190 -0
  115. package/src/cleanse/loop.ts +51 -0
  116. package/src/cleanse/parsers.ts +726 -0
  117. package/src/cleanse/progress.ts +50 -0
  118. package/src/cleanse/prompts/assignment.md +47 -0
  119. package/src/cleanse/types.ts +72 -0
  120. package/src/cli/agents-cli.ts +138 -0
  121. package/src/cli/args.ts +368 -0
  122. package/src/cli/auth-broker-cli.ts +940 -0
  123. package/src/cli/auth-gateway-cli.ts +674 -0
  124. package/src/cli/bench-cli.ts +990 -0
  125. package/src/cli/browser-relay-cli.ts +119 -0
  126. package/src/cli/classify-install-target.ts +76 -0
  127. package/src/cli/claude-trace-cli.ts +795 -0
  128. package/src/cli/command-help.ts +107 -0
  129. package/src/cli/commands/init-xdg.ts +27 -0
  130. package/src/cli/completion-gen.ts +550 -0
  131. package/src/cli/config-cli.ts +459 -0
  132. package/src/cli/dry-balance-cli.ts +864 -0
  133. package/src/cli/extension-flags.ts +48 -0
  134. package/src/cli/file-processor.ts +132 -0
  135. package/src/cli/flag-tables.ts +367 -0
  136. package/src/cli/gallery-cli.ts +272 -0
  137. package/src/cli/gallery-fixtures/agentic.ts +420 -0
  138. package/src/cli/gallery-fixtures/codeintel.ts +187 -0
  139. package/src/cli/gallery-fixtures/edit.ts +254 -0
  140. package/src/cli/gallery-fixtures/fs.ts +245 -0
  141. package/src/cli/gallery-fixtures/index.ts +40 -0
  142. package/src/cli/gallery-fixtures/interaction.ts +46 -0
  143. package/src/cli/gallery-fixtures/memory.ts +81 -0
  144. package/src/cli/gallery-fixtures/misc.ts +177 -0
  145. package/src/cli/gallery-fixtures/search.ts +135 -0
  146. package/src/cli/gallery-fixtures/shell.ts +241 -0
  147. package/src/cli/gallery-fixtures/types.ts +57 -0
  148. package/src/cli/gallery-fixtures/web.ts +158 -0
  149. package/src/cli/gallery-screenshot.ts +279 -0
  150. package/src/cli/gc-cli.ts +1566 -0
  151. package/src/cli/grep-cli.ts +161 -0
  152. package/src/cli/grievances-cli.ts +256 -0
  153. package/src/cli/help-extra.ts +89 -0
  154. package/src/cli/initial-message.ts +58 -0
  155. package/src/cli/models-cli.ts +385 -0
  156. package/src/cli/plugin-cli.ts +996 -0
  157. package/src/cli/profile-alias.ts +369 -0
  158. package/src/cli/profile-bootstrap.ts +233 -0
  159. package/src/cli/read-cli.ts +99 -0
  160. package/src/cli/session-picker.ts +110 -0
  161. package/src/cli/setup-cli.ts +312 -0
  162. package/src/cli/setup-model-picker.ts +43 -0
  163. package/src/cli/shell-cli.ts +176 -0
  164. package/src/cli/ssh-cli.ts +179 -0
  165. package/src/cli/startup-cwd.ts +58 -0
  166. package/src/cli/stats-cli.ts +229 -0
  167. package/src/cli/thinking-levels.ts +7 -0
  168. package/src/cli/tiny-models-cli.ts +153 -0
  169. package/src/cli/ttsr-cli.ts +1013 -0
  170. package/src/cli/update-cli.ts +1184 -0
  171. package/src/cli/usage-cli.ts +1084 -0
  172. package/src/cli/usage-error.ts +7 -0
  173. package/src/cli/web-search-cli.ts +144 -0
  174. package/src/cli/worktree-cli.ts +311 -0
  175. package/src/cli-commands.ts +308 -0
  176. package/src/cli.ts +428 -0
  177. package/src/collab/crypto.ts +63 -0
  178. package/src/collab/display-name.ts +13 -0
  179. package/src/collab/guest.ts +764 -0
  180. package/src/collab/host.ts +692 -0
  181. package/src/collab/protocol.ts +296 -0
  182. package/src/collab/relay-client.ts +282 -0
  183. package/src/collab/replication-shrink.ts +111 -0
  184. package/src/commands/acp.ts +35 -0
  185. package/src/commands/agents.ts +58 -0
  186. package/src/commands/auth-broker.ts +100 -0
  187. package/src/commands/auth-gateway.ts +70 -0
  188. package/src/commands/bench.ts +64 -0
  189. package/src/commands/browser-relay.ts +53 -0
  190. package/src/commands/cleanse.ts +45 -0
  191. package/src/commands/commit.ts +47 -0
  192. package/src/commands/complete.ts +67 -0
  193. package/src/commands/completions.ts +61 -0
  194. package/src/commands/config.ts +52 -0
  195. package/src/commands/dry-balance.ts +43 -0
  196. package/src/commands/gallery.ts +61 -0
  197. package/src/commands/gc.ts +47 -0
  198. package/src/commands/grep.ts +49 -0
  199. package/src/commands/grievances.ts +52 -0
  200. package/src/commands/install.ts +107 -0
  201. package/src/commands/join.ts +40 -0
  202. package/src/commands/launch-help.ts +116 -0
  203. package/src/commands/launch.ts +34 -0
  204. package/src/commands/models.ts +61 -0
  205. package/src/commands/plugin.ts +79 -0
  206. package/src/commands/read.ts +39 -0
  207. package/src/commands/say.ts +146 -0
  208. package/src/commands/setup.ts +68 -0
  209. package/src/commands/share.ts +71 -0
  210. package/src/commands/shell.ts +30 -0
  211. package/src/commands/ssh.ts +61 -0
  212. package/src/commands/stats.ts +30 -0
  213. package/src/commands/tiny-models.ts +36 -0
  214. package/src/commands/token.ts +164 -0
  215. package/src/commands/ttsr.ts +125 -0
  216. package/src/commands/update.ts +34 -0
  217. package/src/commands/usage.ts +55 -0
  218. package/src/commands/web-search.ts +43 -0
  219. package/src/commands/worktree.ts +63 -0
  220. package/src/commit/agentic/agent.ts +322 -0
  221. package/src/commit/agentic/fallback.ts +96 -0
  222. package/src/commit/agentic/index.ts +383 -0
  223. package/src/commit/agentic/lock-files.ts +107 -0
  224. package/src/commit/agentic/prompts/analyze-file.md +22 -0
  225. package/src/commit/agentic/prompts/session-user.md +25 -0
  226. package/src/commit/agentic/prompts/split-confirm.md +1 -0
  227. package/src/commit/agentic/prompts/system.md +38 -0
  228. package/src/commit/agentic/state.ts +60 -0
  229. package/src/commit/agentic/tools/analyze-file.ts +148 -0
  230. package/src/commit/agentic/tools/git-file-diff.ts +191 -0
  231. package/src/commit/agentic/tools/git-hunk.ts +52 -0
  232. package/src/commit/agentic/tools/git-overview.ts +62 -0
  233. package/src/commit/agentic/tools/index.ts +54 -0
  234. package/src/commit/agentic/tools/propose-changelog.ts +147 -0
  235. package/src/commit/agentic/tools/propose-commit.ts +109 -0
  236. package/src/commit/agentic/tools/recent-commits.ts +81 -0
  237. package/src/commit/agentic/tools/schemas.ts +11 -0
  238. package/src/commit/agentic/tools/split-commit.ts +241 -0
  239. package/src/commit/agentic/topo-sort.ts +44 -0
  240. package/src/commit/agentic/trivial.ts +51 -0
  241. package/src/commit/agentic/validation.ts +183 -0
  242. package/src/commit/analysis/conventional.ts +64 -0
  243. package/src/commit/analysis/index.ts +4 -0
  244. package/src/commit/analysis/scope.ts +242 -0
  245. package/src/commit/analysis/summary.ts +107 -0
  246. package/src/commit/analysis/validation.ts +66 -0
  247. package/src/commit/changelog/detect.ts +40 -0
  248. package/src/commit/changelog/generate.ts +101 -0
  249. package/src/commit/changelog/index.ts +234 -0
  250. package/src/commit/changelog/parse.ts +44 -0
  251. package/src/commit/cli.ts +85 -0
  252. package/src/commit/git/diff.ts +148 -0
  253. package/src/commit/index.ts +5 -0
  254. package/src/commit/map-reduce/index.ts +69 -0
  255. package/src/commit/map-reduce/map-phase.ts +193 -0
  256. package/src/commit/map-reduce/reduce-phase.ts +49 -0
  257. package/src/commit/map-reduce/utils.ts +9 -0
  258. package/src/commit/message.ts +11 -0
  259. package/src/commit/model-selection.ts +95 -0
  260. package/src/commit/pipeline.ts +244 -0
  261. package/src/commit/prompts/analysis-system.md +148 -0
  262. package/src/commit/prompts/analysis-user.md +38 -0
  263. package/src/commit/prompts/changelog-system.md +50 -0
  264. package/src/commit/prompts/changelog-user.md +18 -0
  265. package/src/commit/prompts/file-observer-system.md +24 -0
  266. package/src/commit/prompts/file-observer-user.md +8 -0
  267. package/src/commit/prompts/reduce-system.md +50 -0
  268. package/src/commit/prompts/reduce-user.md +17 -0
  269. package/src/commit/prompts/summary-retry.md +3 -0
  270. package/src/commit/prompts/summary-system.md +38 -0
  271. package/src/commit/prompts/summary-user.md +13 -0
  272. package/src/commit/prompts/types-description.md +2 -0
  273. package/src/commit/shared-llm.ts +70 -0
  274. package/src/commit/types.ts +118 -0
  275. package/src/commit/utils/exclusions.ts +42 -0
  276. package/src/commit/utils.ts +58 -0
  277. package/src/config/api-key-resolver.ts +81 -0
  278. package/src/config/append-only-context-mode.ts +76 -0
  279. package/src/config/config-file.ts +347 -0
  280. package/src/config/inline-tool-descriptors-mode.ts +26 -0
  281. package/src/config/keybindings.ts +703 -0
  282. package/src/config/mcp-schema.json +252 -0
  283. package/src/config/model-discovery.ts +1077 -0
  284. package/src/config/model-registry.ts +2822 -0
  285. package/src/config/model-resolver.ts +2115 -0
  286. package/src/config/model-roles.ts +113 -0
  287. package/src/config/models-config-schema-bundle.ts +315 -0
  288. package/src/config/models-config-schema.ts +14 -0
  289. package/src/config/models-config.ts +130 -0
  290. package/src/config/prompt-templates.ts +205 -0
  291. package/src/config/provider-globals.ts +25 -0
  292. package/src/config/resolve-config-value.ts +95 -0
  293. package/src/config/service-tier.ts +146 -0
  294. package/src/config/settings-schema.ts +5887 -0
  295. package/src/config/settings.ts +2394 -0
  296. package/src/config.ts +242 -0
  297. package/src/cursor-bridge-tools.ts +81 -0
  298. package/src/cursor.ts +960 -0
  299. package/src/dap/client.ts +1043 -0
  300. package/src/dap/config.ts +480 -0
  301. package/src/dap/defaults.json +212 -0
  302. package/src/dap/index.ts +4 -0
  303. package/src/dap/session.ts +1841 -0
  304. package/src/dap/types.ts +611 -0
  305. package/src/debug/index.ts +584 -0
  306. package/src/debug/log-formatting.ts +58 -0
  307. package/src/debug/log-viewer.ts +966 -0
  308. package/src/debug/profiler.ts +168 -0
  309. package/src/debug/protocol-probe.ts +267 -0
  310. package/src/debug/raw-sse-buffer.ts +421 -0
  311. package/src/debug/raw-sse.ts +312 -0
  312. package/src/debug/remote-debugger.ts +151 -0
  313. package/src/debug/report-bundle.ts +411 -0
  314. package/src/debug/system-info.ts +111 -0
  315. package/src/debug/terminal-info.ts +124 -0
  316. package/src/discovery/agent-plugin-format.ts +551 -0
  317. package/src/discovery/agent-plugins.ts +341 -0
  318. package/src/discovery/agents-md.ts +67 -0
  319. package/src/discovery/agents.ts +300 -0
  320. package/src/discovery/at-imports.ts +273 -0
  321. package/src/discovery/builtin-defaults.ts +39 -0
  322. package/src/discovery/builtin-rules/go-add-cleanup.md +33 -0
  323. package/src/discovery/builtin-rules/go-bench-loop.md +36 -0
  324. package/src/discovery/builtin-rules/go-exp-promoted.md +40 -0
  325. package/src/discovery/builtin-rules/go-ioutil.md +37 -0
  326. package/src/discovery/builtin-rules/go-join-hostport.md +30 -0
  327. package/src/discovery/builtin-rules/go-new-expr.md +44 -0
  328. package/src/discovery/builtin-rules/go-rand-v2.md +41 -0
  329. package/src/discovery/builtin-rules/go-range-int.md +45 -0
  330. package/src/discovery/builtin-rules/index.ts +74 -0
  331. package/src/discovery/builtin-rules/rs-box-leak.md +49 -0
  332. package/src/discovery/builtin-rules/rs-future-prelude.md +24 -0
  333. package/src/discovery/builtin-rules/rs-lazylock.md +52 -0
  334. package/src/discovery/builtin-rules/rs-match-ergonomics.md +68 -0
  335. package/src/discovery/builtin-rules/rs-parking-lot.md +45 -0
  336. package/src/discovery/builtin-rules/rs-result-type.md +20 -0
  337. package/src/discovery/builtin-rules/ts-bare-catch.md +39 -0
  338. package/src/discovery/builtin-rules/ts-import-type.md +43 -0
  339. package/src/discovery/builtin-rules/ts-no-any.md +66 -0
  340. package/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md +45 -0
  341. package/src/discovery/builtin-rules/ts-no-dynamic-import.md +40 -0
  342. package/src/discovery/builtin-rules/ts-no-inline-cast-access.md +56 -0
  343. package/src/discovery/builtin-rules/ts-no-local-is-record.md +48 -0
  344. package/src/discovery/builtin-rules/ts-no-return-type.md +45 -0
  345. package/src/discovery/builtin-rules/ts-no-test-timers.md +55 -0
  346. package/src/discovery/builtin-rules/ts-no-tiny-functions.md +51 -0
  347. package/src/discovery/builtin-rules/ts-promise-with-resolvers.md +66 -0
  348. package/src/discovery/builtin-rules/ts-redundant-clear-guard.md +75 -0
  349. package/src/discovery/builtin-rules/ts-set-map.md +28 -0
  350. package/src/discovery/builtin.ts +945 -0
  351. package/src/discovery/claude-plugins.ts +640 -0
  352. package/src/discovery/claude.ts +591 -0
  353. package/src/discovery/cline.ts +83 -0
  354. package/src/discovery/codex.ts +553 -0
  355. package/src/discovery/contained-path.ts +78 -0
  356. package/src/discovery/cursor.ts +223 -0
  357. package/src/discovery/gemini.ts +386 -0
  358. package/src/discovery/github.ts +337 -0
  359. package/src/discovery/helpers.ts +1183 -0
  360. package/src/discovery/index.ts +82 -0
  361. package/src/discovery/mcp-json.ts +182 -0
  362. package/src/discovery/omp-extension-roots.ts +272 -0
  363. package/src/discovery/omp-plugins.ts +409 -0
  364. package/src/discovery/opencode.ts +441 -0
  365. package/src/discovery/plugin-dir-roots.ts +28 -0
  366. package/src/discovery/ssh.ts +153 -0
  367. package/src/discovery/substitute-plugin-root.ts +77 -0
  368. package/src/discovery/vscode.ts +106 -0
  369. package/src/discovery/windsurf.ts +149 -0
  370. package/src/edit/apply-patch/index.ts +87 -0
  371. package/src/edit/apply-patch/parser.ts +174 -0
  372. package/src/edit/diff.ts +1008 -0
  373. package/src/edit/edit-clipboard.ts +23 -0
  374. package/src/edit/file-snapshot-store.ts +148 -0
  375. package/src/edit/hashline/block-resolver.ts +33 -0
  376. package/src/edit/hashline/diff.ts +402 -0
  377. package/src/edit/hashline/execute.ts +313 -0
  378. package/src/edit/hashline/filesystem.ts +247 -0
  379. package/src/edit/hashline/index.ts +5 -0
  380. package/src/edit/hashline/noop-loop-guard.ts +99 -0
  381. package/src/edit/hashline/params.ts +12 -0
  382. package/src/edit/index.ts +699 -0
  383. package/src/edit/modes/apply-patch.lark +19 -0
  384. package/src/edit/modes/apply-patch.ts +53 -0
  385. package/src/edit/modes/patch.ts +1958 -0
  386. package/src/edit/modes/replace.ts +1191 -0
  387. package/src/edit/normalize.ts +345 -0
  388. package/src/edit/notebook.ts +242 -0
  389. package/src/edit/read-file.ts +25 -0
  390. package/src/edit/renderer.ts +998 -0
  391. package/src/edit/snapshot-details.ts +77 -0
  392. package/src/edit/streaming.ts +710 -0
  393. package/src/eval/agent-bridge.ts +224 -0
  394. package/src/eval/backend-helpers.ts +48 -0
  395. package/src/eval/backend.ts +71 -0
  396. package/src/eval/bridge-timeout.ts +65 -0
  397. package/src/eval/budget-bridge.ts +48 -0
  398. package/src/eval/completion-bridge.ts +212 -0
  399. package/src/eval/concurrency-bridge.ts +34 -0
  400. package/src/eval/executor-base.ts +562 -0
  401. package/src/eval/idle-timeout.ts +91 -0
  402. package/src/eval/index.ts +6 -0
  403. package/src/eval/jl/executor.ts +551 -0
  404. package/src/eval/jl/index.ts +54 -0
  405. package/src/eval/jl/kernel.ts +236 -0
  406. package/src/eval/jl/prelude.jl +736 -0
  407. package/src/eval/jl/prelude.ts +3 -0
  408. package/src/eval/jl/runner.jl +666 -0
  409. package/src/eval/jl/runtime.ts +118 -0
  410. package/src/eval/js/context-manager.ts +872 -0
  411. package/src/eval/js/executor.ts +178 -0
  412. package/src/eval/js/index.ts +41 -0
  413. package/src/eval/js/process-entry.ts +31 -0
  414. package/src/eval/js/shared/helpers.ts +170 -0
  415. package/src/eval/js/shared/indirect-eval.ts +30 -0
  416. package/src/eval/js/shared/local-module-loader.ts +364 -0
  417. package/src/eval/js/shared/prelude.ts +2 -0
  418. package/src/eval/js/shared/prelude.txt +294 -0
  419. package/src/eval/js/shared/rewrite-imports.ts +550 -0
  420. package/src/eval/js/shared/runtime.ts +590 -0
  421. package/src/eval/js/shared/types.ts +18 -0
  422. package/src/eval/js/tool-bridge.ts +163 -0
  423. package/src/eval/js/worker-core.ts +380 -0
  424. package/src/eval/js/worker-entry.ts +37 -0
  425. package/src/eval/js/worker-protocol.ts +47 -0
  426. package/src/eval/kernel-base.ts +569 -0
  427. package/src/eval/py/display.ts +71 -0
  428. package/src/eval/py/executor.ts +643 -0
  429. package/src/eval/py/index.ts +57 -0
  430. package/src/eval/py/kernel.ts +235 -0
  431. package/src/eval/py/prelude.py +673 -0
  432. package/src/eval/py/prelude.ts +3 -0
  433. package/src/eval/py/runner.py +1425 -0
  434. package/src/eval/py/runtime.ts +276 -0
  435. package/src/eval/py/spawn-options.ts +134 -0
  436. package/src/eval/py/tool-bridge.ts +201 -0
  437. package/src/eval/rb/executor.ts +511 -0
  438. package/src/eval/rb/index.ts +54 -0
  439. package/src/eval/rb/kernel.ts +231 -0
  440. package/src/eval/rb/prelude.rb +551 -0
  441. package/src/eval/rb/prelude.ts +3 -0
  442. package/src/eval/rb/runner.rb +581 -0
  443. package/src/eval/rb/runtime.ts +132 -0
  444. package/src/eval/runtime-env.ts +104 -0
  445. package/src/eval/session-id.ts +8 -0
  446. package/src/eval/types.ts +48 -0
  447. package/src/exa/index.ts +2 -0
  448. package/src/exa/mcp-client.ts +370 -0
  449. package/src/exa/types.ts +69 -0
  450. package/src/exec/bash-executor.ts +627 -0
  451. package/src/exec/direnv.ts +145 -0
  452. package/src/exec/exec.ts +53 -0
  453. package/src/exec/non-interactive-env.ts +118 -0
  454. package/src/export/custom-share.ts +65 -0
  455. package/src/export/html/args.ts +20 -0
  456. package/src/export/html/index.ts +320 -0
  457. package/src/export/html/share-loader.js +102 -0
  458. package/src/export/html/template.css +1355 -0
  459. package/src/export/html/template.html +55 -0
  460. package/src/export/html/template.js +1653 -0
  461. package/src/export/html/tool-views.generated.js +35 -0
  462. package/src/export/html/vendor/highlight.min.js +1213 -0
  463. package/src/export/html/vendor/marked.min.js +6 -0
  464. package/src/export/html/web-palette.ts +126 -0
  465. package/src/export/share.ts +686 -0
  466. package/src/export/ttsr.ts +590 -0
  467. package/src/extensibility/custom-commands/bundled/ci-green/index.ts +54 -0
  468. package/src/extensibility/custom-commands/bundled/review/index.ts +698 -0
  469. package/src/extensibility/custom-commands/index.ts +2 -0
  470. package/src/extensibility/custom-commands/loader.ts +242 -0
  471. package/src/extensibility/custom-commands/types.ts +119 -0
  472. package/src/extensibility/custom-tools/index.ts +7 -0
  473. package/src/extensibility/custom-tools/loader.ts +301 -0
  474. package/src/extensibility/custom-tools/types.ts +287 -0
  475. package/src/extensibility/custom-tools/wrapper.ts +50 -0
  476. package/src/extensibility/extensions/compact-handler.ts +40 -0
  477. package/src/extensibility/extensions/get-commands-handler.ts +78 -0
  478. package/src/extensibility/extensions/index.ts +16 -0
  479. package/src/extensibility/extensions/load-errors.ts +13 -0
  480. package/src/extensibility/extensions/loader.ts +663 -0
  481. package/src/extensibility/extensions/managed-timers.ts +83 -0
  482. package/src/extensibility/extensions/model-api.ts +39 -0
  483. package/src/extensibility/extensions/runner.ts +1396 -0
  484. package/src/extensibility/extensions/types.ts +1603 -0
  485. package/src/extensibility/extensions/wrapper.ts +395 -0
  486. package/src/extensibility/hooks/index.ts +6 -0
  487. package/src/extensibility/hooks/loader.ts +243 -0
  488. package/src/extensibility/hooks/runner.ts +425 -0
  489. package/src/extensibility/hooks/tool-wrapper.ts +124 -0
  490. package/src/extensibility/hooks/types.ts +612 -0
  491. package/src/extensibility/legacy-pi-ai-shim.ts +161 -0
  492. package/src/extensibility/legacy-pi-coding-agent-shim.ts +1460 -0
  493. package/src/extensibility/legacy-pi-tui-shim.ts +43 -0
  494. package/src/extensibility/legacy-typebox.ts +101 -0
  495. package/src/extensibility/plugins/bun-git-cache.ts +91 -0
  496. package/src/extensibility/plugins/doctor.ts +65 -0
  497. package/src/extensibility/plugins/git-url.ts +367 -0
  498. package/src/extensibility/plugins/index.ts +9 -0
  499. package/src/extensibility/plugins/installer.ts +201 -0
  500. package/src/extensibility/plugins/legacy-pi-compat.ts +2643 -0
  501. package/src/extensibility/plugins/legacy-pi-virtual-modules.d.ts +4 -0
  502. package/src/extensibility/plugins/loader.ts +535 -0
  503. package/src/extensibility/plugins/manager.ts +1142 -0
  504. package/src/extensibility/plugins/marketplace/cache.ts +136 -0
  505. package/src/extensibility/plugins/marketplace/fetcher.ts +316 -0
  506. package/src/extensibility/plugins/marketplace/index.ts +6 -0
  507. package/src/extensibility/plugins/marketplace/manager.ts +927 -0
  508. package/src/extensibility/plugins/marketplace/registry.ts +192 -0
  509. package/src/extensibility/plugins/marketplace/source-resolver.ts +147 -0
  510. package/src/extensibility/plugins/marketplace/types.ts +192 -0
  511. package/src/extensibility/plugins/marketplace-auto-update.ts +49 -0
  512. package/src/extensibility/plugins/parser.ts +107 -0
  513. package/src/extensibility/plugins/runtime-config.ts +9 -0
  514. package/src/extensibility/plugins/types.ts +194 -0
  515. package/src/extensibility/session-handler-types.ts +21 -0
  516. package/src/extensibility/shared-events.ts +401 -0
  517. package/src/extensibility/skills.ts +531 -0
  518. package/src/extensibility/slash-commands.ts +131 -0
  519. package/src/extensibility/tool-event-input.ts +80 -0
  520. package/src/extensibility/tool-proxy.ts +28 -0
  521. package/src/extensibility/utils.ts +192 -0
  522. package/src/goals/index.ts +3 -0
  523. package/src/goals/runtime.ts +521 -0
  524. package/src/goals/state.ts +37 -0
  525. package/src/goals/tools/goal-tool.ts +251 -0
  526. package/src/hindsight/backend.ts +354 -0
  527. package/src/hindsight/bank.ts +156 -0
  528. package/src/hindsight/client.ts +680 -0
  529. package/src/hindsight/config.ts +193 -0
  530. package/src/hindsight/content.ts +266 -0
  531. package/src/hindsight/index.ts +8 -0
  532. package/src/hindsight/mental-models.ts +429 -0
  533. package/src/hindsight/seeds.json +32 -0
  534. package/src/hindsight/state.ts +530 -0
  535. package/src/hindsight/transcript.ts +71 -0
  536. package/src/index.ts +66 -0
  537. package/src/internal-urls/agent-protocol.ts +180 -0
  538. package/src/internal-urls/artifact-protocol.ts +151 -0
  539. package/src/internal-urls/docs-index.ts +102 -0
  540. package/src/internal-urls/filesystem-resource.ts +34 -0
  541. package/src/internal-urls/history-protocol.ts +198 -0
  542. package/src/internal-urls/index.ts +28 -0
  543. package/src/internal-urls/issue-pr-protocol.ts +594 -0
  544. package/src/internal-urls/json-query.ts +126 -0
  545. package/src/internal-urls/local-protocol.ts +471 -0
  546. package/src/internal-urls/mcp-protocol.ts +168 -0
  547. package/src/internal-urls/memory-protocol.ts +380 -0
  548. package/src/internal-urls/omp-protocol.ts +94 -0
  549. package/src/internal-urls/parse.ts +103 -0
  550. package/src/internal-urls/registry-helpers.ts +132 -0
  551. package/src/internal-urls/router.ts +153 -0
  552. package/src/internal-urls/rule-protocol.ts +45 -0
  553. package/src/internal-urls/security-protocol.ts +261 -0
  554. package/src/internal-urls/skill-protocol.ts +131 -0
  555. package/src/internal-urls/ssh-protocol.ts +368 -0
  556. package/src/internal-urls/types.ts +196 -0
  557. package/src/internal-urls/vault-protocol.ts +940 -0
  558. package/src/internal-urls/xd-protocol.ts +46 -0
  559. package/src/irc/bus.ts +380 -0
  560. package/src/jsonrpc/message-framing.ts +142 -0
  561. package/src/launch/broker.ts +1368 -0
  562. package/src/launch/client.ts +521 -0
  563. package/src/launch/ensure.ts +73 -0
  564. package/src/launch/paths.ts +14 -0
  565. package/src/launch/presence.ts +82 -0
  566. package/src/launch/protocol.ts +448 -0
  567. package/src/launch/spawn-options.ts +17 -0
  568. package/src/launch/terminal-output-worker-client.ts +53 -0
  569. package/src/launch/terminal-output-worker-protocol.ts +11 -0
  570. package/src/launch/terminal-output-worker.ts +23 -0
  571. package/src/launch/terminal-output.ts +46 -0
  572. package/src/lib/xai-http.ts +150 -0
  573. package/src/live/attestation.ts +91 -0
  574. package/src/live/controller.ts +517 -0
  575. package/src/live/prompts/agent-final-message.md +3 -0
  576. package/src/live/prompts/live-instructions.md +23 -0
  577. package/src/live/protocol.ts +233 -0
  578. package/src/live/transport.ts +422 -0
  579. package/src/live/visualizer.ts +221 -0
  580. package/src/live/voices.ts +18 -0
  581. package/src/lsp/client.ts +1465 -0
  582. package/src/lsp/clients/biome-client.ts +263 -0
  583. package/src/lsp/clients/index.ts +50 -0
  584. package/src/lsp/clients/lsp-linter-client.ts +85 -0
  585. package/src/lsp/clients/swiftlint-client.ts +120 -0
  586. package/src/lsp/config.ts +549 -0
  587. package/src/lsp/defaults.json +499 -0
  588. package/src/lsp/deferred-diagnostics.ts +66 -0
  589. package/src/lsp/diagnostics-ledger.ts +51 -0
  590. package/src/lsp/edits.ts +288 -0
  591. package/src/lsp/format-options.ts +119 -0
  592. package/src/lsp/index.ts +2821 -0
  593. package/src/lsp/lspmux.ts +233 -0
  594. package/src/lsp/mux/daemon.ts +348 -0
  595. package/src/lsp/mux/protocol.ts +96 -0
  596. package/src/lsp/mux/server.ts +797 -0
  597. package/src/lsp/render.ts +668 -0
  598. package/src/lsp/startup-events.ts +13 -0
  599. package/src/lsp/types.ts +479 -0
  600. package/src/lsp/utils.ts +747 -0
  601. package/src/main.ts +1799 -0
  602. package/src/markit/NOTICE +32 -0
  603. package/src/markit/converters/docx.ts +56 -0
  604. package/src/markit/converters/epub.ts +136 -0
  605. package/src/markit/converters/pdf/columns.ts +103 -0
  606. package/src/markit/converters/pdf/extract.ts +598 -0
  607. package/src/markit/converters/pdf/grid.ts +780 -0
  608. package/src/markit/converters/pdf/headers.ts +106 -0
  609. package/src/markit/converters/pdf/index.ts +146 -0
  610. package/src/markit/converters/pdf/render.ts +501 -0
  611. package/src/markit/converters/pdf/types.ts +84 -0
  612. package/src/markit/converters/pptx.ts +325 -0
  613. package/src/markit/converters/xlsx.ts +173 -0
  614. package/src/markit/index.ts +2 -0
  615. package/src/markit/registry.ts +59 -0
  616. package/src/markit/types.ts +35 -0
  617. package/src/mcp/client.ts +511 -0
  618. package/src/mcp/config-writer.ts +377 -0
  619. package/src/mcp/config.ts +385 -0
  620. package/src/mcp/index.ts +29 -0
  621. package/src/mcp/json-rpc.ts +122 -0
  622. package/src/mcp/loader.ts +125 -0
  623. package/src/mcp/manager.ts +1524 -0
  624. package/src/mcp/oauth-credentials.ts +104 -0
  625. package/src/mcp/oauth-discovery.ts +587 -0
  626. package/src/mcp/oauth-flow.ts +830 -0
  627. package/src/mcp/render.ts +214 -0
  628. package/src/mcp/request-id.ts +24 -0
  629. package/src/mcp/smithery-auth.ts +108 -0
  630. package/src/mcp/smithery-connect.ts +154 -0
  631. package/src/mcp/smithery-registry.ts +500 -0
  632. package/src/mcp/startup-events.ts +116 -0
  633. package/src/mcp/timeout.ts +59 -0
  634. package/src/mcp/tool-bridge.ts +691 -0
  635. package/src/mcp/tool-cache.ts +117 -0
  636. package/src/mcp/transports/header-policy.ts +95 -0
  637. package/src/mcp/transports/http.ts +508 -0
  638. package/src/mcp/transports/index.ts +7 -0
  639. package/src/mcp/transports/sse.ts +372 -0
  640. package/src/mcp/transports/stdio.ts +905 -0
  641. package/src/mcp/types.ts +467 -0
  642. package/src/memories/index.ts +1434 -0
  643. package/src/memories/storage.ts +578 -0
  644. package/src/memory-backend/index.ts +19 -0
  645. package/src/memory-backend/local-backend.ts +47 -0
  646. package/src/memory-backend/messages.ts +19 -0
  647. package/src/memory-backend/off-backend.ts +25 -0
  648. package/src/memory-backend/resolve.ts +25 -0
  649. package/src/memory-backend/runtime.ts +66 -0
  650. package/src/memory-backend/tool-names.ts +2 -0
  651. package/src/memory-backend/types.ts +166 -0
  652. package/src/mnemopi/backend.ts +629 -0
  653. package/src/mnemopi/config.ts +267 -0
  654. package/src/mnemopi/embed-client.ts +293 -0
  655. package/src/mnemopi/embed-protocol.ts +35 -0
  656. package/src/mnemopi/embed-worker.ts +114 -0
  657. package/src/mnemopi/index.ts +3 -0
  658. package/src/mnemopi/state.ts +940 -0
  659. package/src/modes/acp/acp-agent.ts +2595 -0
  660. package/src/modes/acp/acp-client-bridge.ts +154 -0
  661. package/src/modes/acp/acp-event-mapper.ts +1084 -0
  662. package/src/modes/acp/acp-mode.ts +48 -0
  663. package/src/modes/acp/index.ts +2 -0
  664. package/src/modes/acp/terminal-auth.ts +37 -0
  665. package/src/modes/components/advisor-config.ts +635 -0
  666. package/src/modes/components/advisor-message.ts +109 -0
  667. package/src/modes/components/agent-dashboard.ts +1252 -0
  668. package/src/modes/components/agent-hub-projection.ts +248 -0
  669. package/src/modes/components/agent-hub-renderer.ts +194 -0
  670. package/src/modes/components/agent-hub.ts +1126 -0
  671. package/src/modes/components/agent-transcript-viewer.ts +647 -0
  672. package/src/modes/components/ask-dialog.ts +1017 -0
  673. package/src/modes/components/assistant-message.ts +978 -0
  674. package/src/modes/components/background-tan-message.ts +36 -0
  675. package/src/modes/components/bash-execution.ts +233 -0
  676. package/src/modes/components/bordered-loader.ts +41 -0
  677. package/src/modes/components/btw-panel.ts +161 -0
  678. package/src/modes/components/cache-invalidation-marker.ts +110 -0
  679. package/src/modes/components/chat-block.ts +111 -0
  680. package/src/modes/components/chat-transcript-builder.ts +518 -0
  681. package/src/modes/components/codex-reset-fireworks.ts +369 -0
  682. package/src/modes/components/collab-prompt-message.ts +32 -0
  683. package/src/modes/components/compaction-summary-message.ts +221 -0
  684. package/src/modes/components/copy-selector.ts +218 -0
  685. package/src/modes/components/countdown-timer.ts +75 -0
  686. package/src/modes/components/custom-editor.ts +1036 -0
  687. package/src/modes/components/custom-message.ts +70 -0
  688. package/src/modes/components/diff.ts +254 -0
  689. package/src/modes/components/dynamic-border.ts +37 -0
  690. package/src/modes/components/error-banner.ts +33 -0
  691. package/src/modes/components/eval-execution.ts +169 -0
  692. package/src/modes/components/execution-shared.ts +101 -0
  693. package/src/modes/components/extensions/extension-dashboard.ts +492 -0
  694. package/src/modes/components/extensions/extension-list.ts +507 -0
  695. package/src/modes/components/extensions/index.ts +9 -0
  696. package/src/modes/components/extensions/inspector-panel.ts +326 -0
  697. package/src/modes/components/extensions/state-manager.ts +648 -0
  698. package/src/modes/components/extensions/types.ts +186 -0
  699. package/src/modes/components/footer.ts +274 -0
  700. package/src/modes/components/history-search.ts +268 -0
  701. package/src/modes/components/hook-editor.ts +213 -0
  702. package/src/modes/components/hook-input.ts +87 -0
  703. package/src/modes/components/hook-message.ts +67 -0
  704. package/src/modes/components/hook-selector.ts +691 -0
  705. package/src/modes/components/index.ts +42 -0
  706. package/src/modes/components/keybinding-hints.ts +56 -0
  707. package/src/modes/components/late-diagnostics-message.ts +60 -0
  708. package/src/modes/components/login-dialog.ts +197 -0
  709. package/src/modes/components/logout-account-selector.ts +130 -0
  710. package/src/modes/components/mcp-add-wizard.ts +1413 -0
  711. package/src/modes/components/message-frame.ts +98 -0
  712. package/src/modes/components/model-browser.ts +888 -0
  713. package/src/modes/components/model-hub.ts +2014 -0
  714. package/src/modes/components/model-picker.ts +237 -0
  715. package/src/modes/components/move-overlay.ts +293 -0
  716. package/src/modes/components/oauth-selector.ts +474 -0
  717. package/src/modes/components/omfg-panel.ts +141 -0
  718. package/src/modes/components/overlay-box.ts +109 -0
  719. package/src/modes/components/pause-screen.ts +208 -0
  720. package/src/modes/components/plan-review-overlay.ts +1226 -0
  721. package/src/modes/components/plan-toc.ts +138 -0
  722. package/src/modes/components/plugin-selector.ts +100 -0
  723. package/src/modes/components/plugin-settings.ts +745 -0
  724. package/src/modes/components/queue-mode-selector.ts +61 -0
  725. package/src/modes/components/read-tool-group.ts +856 -0
  726. package/src/modes/components/reset-usage-selector.ts +161 -0
  727. package/src/modes/components/segment-track.ts +89 -0
  728. package/src/modes/components/select-list-mouse-routing.ts +35 -0
  729. package/src/modes/components/selector-helpers.ts +129 -0
  730. package/src/modes/components/session-account-selector.ts +62 -0
  731. package/src/modes/components/session-selector.ts +1035 -0
  732. package/src/modes/components/settings-defs.ts +267 -0
  733. package/src/modes/components/settings-selector.ts +1445 -0
  734. package/src/modes/components/show-images-selector.ts +50 -0
  735. package/src/modes/components/skill-message.ts +110 -0
  736. package/src/modes/components/snapcompact-shape-preview-doc.md +14 -0
  737. package/src/modes/components/snapcompact-shape-preview.ts +192 -0
  738. package/src/modes/components/status-line/component.ts +1843 -0
  739. package/src/modes/components/status-line/context-thresholds.ts +86 -0
  740. package/src/modes/components/status-line/git-utils.ts +42 -0
  741. package/src/modes/components/status-line/index.ts +5 -0
  742. package/src/modes/components/status-line/presets.ts +106 -0
  743. package/src/modes/components/status-line/segments.ts +710 -0
  744. package/src/modes/components/status-line/separators.ts +55 -0
  745. package/src/modes/components/status-line/types.ts +159 -0
  746. package/src/modes/components/stripped-tool-calls-placeholder.ts +35 -0
  747. package/src/modes/components/theme-selector.ts +68 -0
  748. package/src/modes/components/thinking-selector.ts +57 -0
  749. package/src/modes/components/tiny-title-download-progress.ts +90 -0
  750. package/src/modes/components/tips.txt +26 -0
  751. package/src/modes/components/todo-reminder.ts +43 -0
  752. package/src/modes/components/tool-execution.ts +1467 -0
  753. package/src/modes/components/transcript-container.ts +527 -0
  754. package/src/modes/components/tree-selector.ts +1006 -0
  755. package/src/modes/components/ttsr-notification.ts +123 -0
  756. package/src/modes/components/usage-row.ts +52 -0
  757. package/src/modes/components/user-message-selector.ts +227 -0
  758. package/src/modes/components/user-message.ts +167 -0
  759. package/src/modes/components/visual-truncate.ts +63 -0
  760. package/src/modes/components/welcome.ts +578 -0
  761. package/src/modes/controllers/btw-controller.ts +246 -0
  762. package/src/modes/controllers/command-controller-shared.ts +109 -0
  763. package/src/modes/controllers/command-controller.ts +2024 -0
  764. package/src/modes/controllers/event-controller.ts +2173 -0
  765. package/src/modes/controllers/extension-ui-controller.ts +1243 -0
  766. package/src/modes/controllers/input-controller.ts +2037 -0
  767. package/src/modes/controllers/live-command-controller.ts +261 -0
  768. package/src/modes/controllers/mcp-command-controller.ts +2552 -0
  769. package/src/modes/controllers/omfg-controller.ts +287 -0
  770. package/src/modes/controllers/omfg-rule.ts +647 -0
  771. package/src/modes/controllers/selector-controller.ts +2058 -0
  772. package/src/modes/controllers/session-focus-controller.ts +117 -0
  773. package/src/modes/controllers/ssh-command-controller.ts +385 -0
  774. package/src/modes/controllers/streaming-reveal.ts +399 -0
  775. package/src/modes/controllers/tan-command-controller.ts +243 -0
  776. package/src/modes/controllers/todo-command-controller.ts +487 -0
  777. package/src/modes/controllers/tool-args-reveal.ts +591 -0
  778. package/src/modes/data/emojis.json +1 -0
  779. package/src/modes/emoji-autocomplete.ts +285 -0
  780. package/src/modes/github-ref-autocomplete.ts +75 -0
  781. package/src/modes/gradient-highlight.ts +99 -0
  782. package/src/modes/image-references.ts +137 -0
  783. package/src/modes/index.ts +10 -0
  784. package/src/modes/interactive-mode.ts +5055 -0
  785. package/src/modes/internal-url-autocomplete.ts +158 -0
  786. package/src/modes/loop-limit.ts +192 -0
  787. package/src/modes/magic-keyword-boundary.ts +23 -0
  788. package/src/modes/magic-keywords.ts +42 -0
  789. package/src/modes/markdown-prose.ts +247 -0
  790. package/src/modes/oauth-manual-input.ts +69 -0
  791. package/src/modes/orchestrate.ts +43 -0
  792. package/src/modes/print-mode.ts +282 -0
  793. package/src/modes/prompt-action-autocomplete.ts +322 -0
  794. package/src/modes/queue-input.ts +132 -0
  795. package/src/modes/rpc/host-tools.ts +204 -0
  796. package/src/modes/rpc/host-uris.ts +241 -0
  797. package/src/modes/rpc/rpc-client.ts +1213 -0
  798. package/src/modes/rpc/rpc-frame.ts +316 -0
  799. package/src/modes/rpc/rpc-input.ts +38 -0
  800. package/src/modes/rpc/rpc-messages.ts +127 -0
  801. package/src/modes/rpc/rpc-mode.ts +1519 -0
  802. package/src/modes/rpc/rpc-subagents.ts +265 -0
  803. package/src/modes/rpc/rpc-types.ts +544 -0
  804. package/src/modes/running-subagent-badge.ts +13 -0
  805. package/src/modes/runtime-init.ts +144 -0
  806. package/src/modes/session-observer-registry.ts +223 -0
  807. package/src/modes/session-teardown.ts +82 -0
  808. package/src/modes/setup-version.ts +11 -0
  809. package/src/modes/setup-wizard/index.ts +103 -0
  810. package/src/modes/setup-wizard/lazy.ts +16 -0
  811. package/src/modes/setup-wizard/scenes/glyph.ts +103 -0
  812. package/src/modes/setup-wizard/scenes/model.ts +132 -0
  813. package/src/modes/setup-wizard/scenes/outro.ts +35 -0
  814. package/src/modes/setup-wizard/scenes/providers.ts +105 -0
  815. package/src/modes/setup-wizard/scenes/sign-in.ts +312 -0
  816. package/src/modes/setup-wizard/scenes/splash.ts +201 -0
  817. package/src/modes/setup-wizard/scenes/theme.ts +330 -0
  818. package/src/modes/setup-wizard/scenes/types.ts +65 -0
  819. package/src/modes/setup-wizard/scenes/web-search.ts +153 -0
  820. package/src/modes/setup-wizard/startup-splash.ts +107 -0
  821. package/src/modes/setup-wizard/wizard-overlay.ts +335 -0
  822. package/src/modes/shared.ts +49 -0
  823. package/src/modes/skill-command.ts +91 -0
  824. package/src/modes/theme/dark.json +95 -0
  825. package/src/modes/theme/defaults/alabaster.json +93 -0
  826. package/src/modes/theme/defaults/amethyst.json +96 -0
  827. package/src/modes/theme/defaults/anthracite.json +93 -0
  828. package/src/modes/theme/defaults/basalt.json +91 -0
  829. package/src/modes/theme/defaults/birch.json +95 -0
  830. package/src/modes/theme/defaults/dark-abyss.json +91 -0
  831. package/src/modes/theme/defaults/dark-arctic.json +104 -0
  832. package/src/modes/theme/defaults/dark-aurora.json +95 -0
  833. package/src/modes/theme/defaults/dark-catppuccin.json +107 -0
  834. package/src/modes/theme/defaults/dark-cavern.json +91 -0
  835. package/src/modes/theme/defaults/dark-copper.json +95 -0
  836. package/src/modes/theme/defaults/dark-cosmos.json +90 -0
  837. package/src/modes/theme/defaults/dark-cyberpunk.json +102 -0
  838. package/src/modes/theme/defaults/dark-dracula.json +98 -0
  839. package/src/modes/theme/defaults/dark-eclipse.json +91 -0
  840. package/src/modes/theme/defaults/dark-ember.json +95 -0
  841. package/src/modes/theme/defaults/dark-equinox.json +90 -0
  842. package/src/modes/theme/defaults/dark-forest.json +96 -0
  843. package/src/modes/theme/defaults/dark-github.json +105 -0
  844. package/src/modes/theme/defaults/dark-gruvbox.json +112 -0
  845. package/src/modes/theme/defaults/dark-lavender.json +95 -0
  846. package/src/modes/theme/defaults/dark-lunar.json +89 -0
  847. package/src/modes/theme/defaults/dark-midnight.json +95 -0
  848. package/src/modes/theme/defaults/dark-monochrome.json +94 -0
  849. package/src/modes/theme/defaults/dark-monokai.json +98 -0
  850. package/src/modes/theme/defaults/dark-nebula.json +90 -0
  851. package/src/modes/theme/defaults/dark-nord.json +97 -0
  852. package/src/modes/theme/defaults/dark-ocean.json +101 -0
  853. package/src/modes/theme/defaults/dark-one.json +100 -0
  854. package/src/modes/theme/defaults/dark-poimandres.json +143 -0
  855. package/src/modes/theme/defaults/dark-rainforest.json +91 -0
  856. package/src/modes/theme/defaults/dark-reef.json +91 -0
  857. package/src/modes/theme/defaults/dark-retro.json +92 -0
  858. package/src/modes/theme/defaults/dark-rose-pine.json +96 -0
  859. package/src/modes/theme/defaults/dark-sakura.json +95 -0
  860. package/src/modes/theme/defaults/dark-slate.json +95 -0
  861. package/src/modes/theme/defaults/dark-solarized.json +97 -0
  862. package/src/modes/theme/defaults/dark-solstice.json +90 -0
  863. package/src/modes/theme/defaults/dark-starfall.json +91 -0
  864. package/src/modes/theme/defaults/dark-sunset.json +99 -0
  865. package/src/modes/theme/defaults/dark-swamp.json +90 -0
  866. package/src/modes/theme/defaults/dark-synthwave.json +103 -0
  867. package/src/modes/theme/defaults/dark-taiga.json +91 -0
  868. package/src/modes/theme/defaults/dark-terminal.json +95 -0
  869. package/src/modes/theme/defaults/dark-tokyo-night.json +101 -0
  870. package/src/modes/theme/defaults/dark-tundra.json +91 -0
  871. package/src/modes/theme/defaults/dark-twilight.json +91 -0
  872. package/src/modes/theme/defaults/dark-volcanic.json +91 -0
  873. package/src/modes/theme/defaults/graphite.json +92 -0
  874. package/src/modes/theme/defaults/index.ts +199 -0
  875. package/src/modes/theme/defaults/light-arctic.json +107 -0
  876. package/src/modes/theme/defaults/light-aurora-day.json +91 -0
  877. package/src/modes/theme/defaults/light-canyon.json +91 -0
  878. package/src/modes/theme/defaults/light-catppuccin.json +106 -0
  879. package/src/modes/theme/defaults/light-cirrus.json +90 -0
  880. package/src/modes/theme/defaults/light-coral.json +95 -0
  881. package/src/modes/theme/defaults/light-cyberpunk.json +96 -0
  882. package/src/modes/theme/defaults/light-dawn.json +90 -0
  883. package/src/modes/theme/defaults/light-dunes.json +91 -0
  884. package/src/modes/theme/defaults/light-eucalyptus.json +95 -0
  885. package/src/modes/theme/defaults/light-forest.json +100 -0
  886. package/src/modes/theme/defaults/light-frost.json +95 -0
  887. package/src/modes/theme/defaults/light-github.json +115 -0
  888. package/src/modes/theme/defaults/light-glacier.json +91 -0
  889. package/src/modes/theme/defaults/light-gruvbox.json +108 -0
  890. package/src/modes/theme/defaults/light-haze.json +90 -0
  891. package/src/modes/theme/defaults/light-honeycomb.json +95 -0
  892. package/src/modes/theme/defaults/light-lagoon.json +91 -0
  893. package/src/modes/theme/defaults/light-lavender.json +95 -0
  894. package/src/modes/theme/defaults/light-meadow.json +91 -0
  895. package/src/modes/theme/defaults/light-mint.json +95 -0
  896. package/src/modes/theme/defaults/light-monochrome.json +101 -0
  897. package/src/modes/theme/defaults/light-ocean.json +99 -0
  898. package/src/modes/theme/defaults/light-one.json +99 -0
  899. package/src/modes/theme/defaults/light-opal.json +91 -0
  900. package/src/modes/theme/defaults/light-orchard.json +91 -0
  901. package/src/modes/theme/defaults/light-paper.json +95 -0
  902. package/src/modes/theme/defaults/light-poimandres.json +143 -0
  903. package/src/modes/theme/defaults/light-prism.json +90 -0
  904. package/src/modes/theme/defaults/light-retro.json +98 -0
  905. package/src/modes/theme/defaults/light-sand.json +95 -0
  906. package/src/modes/theme/defaults/light-savanna.json +91 -0
  907. package/src/modes/theme/defaults/light-solarized.json +102 -0
  908. package/src/modes/theme/defaults/light-soleil.json +90 -0
  909. package/src/modes/theme/defaults/light-sunset.json +99 -0
  910. package/src/modes/theme/defaults/light-synthwave.json +98 -0
  911. package/src/modes/theme/defaults/light-tokyo-night.json +111 -0
  912. package/src/modes/theme/defaults/light-wetland.json +91 -0
  913. package/src/modes/theme/defaults/light-zenith.json +89 -0
  914. package/src/modes/theme/defaults/limestone.json +94 -0
  915. package/src/modes/theme/defaults/mahogany.json +97 -0
  916. package/src/modes/theme/defaults/marble.json +93 -0
  917. package/src/modes/theme/defaults/obsidian.json +91 -0
  918. package/src/modes/theme/defaults/onyx.json +91 -0
  919. package/src/modes/theme/defaults/pearl.json +93 -0
  920. package/src/modes/theme/defaults/porcelain.json +91 -0
  921. package/src/modes/theme/defaults/quartz.json +96 -0
  922. package/src/modes/theme/defaults/sandstone.json +95 -0
  923. package/src/modes/theme/defaults/titanium.json +90 -0
  924. package/src/modes/theme/light.json +93 -0
  925. package/src/modes/theme/mermaid-cache.ts +92 -0
  926. package/src/modes/theme/shimmer.ts +305 -0
  927. package/src/modes/theme/theme-schema.json +463 -0
  928. package/src/modes/theme/theme.ts +3171 -0
  929. package/src/modes/turn-budget.ts +31 -0
  930. package/src/modes/types.ts +494 -0
  931. package/src/modes/ultrathink.ts +42 -0
  932. package/src/modes/utils/context-usage.ts +518 -0
  933. package/src/modes/utils/copy-targets.ts +378 -0
  934. package/src/modes/utils/hotkeys-markdown.ts +65 -0
  935. package/src/modes/utils/interactive-context-helpers.ts +31 -0
  936. package/src/modes/utils/keybinding-matchers.ts +86 -0
  937. package/src/modes/utils/tools-markdown.ts +31 -0
  938. package/src/modes/utils/transcript-render-helpers.ts +253 -0
  939. package/src/modes/utils/ui-helpers.ts +976 -0
  940. package/src/modes/warp-events.ts +232 -0
  941. package/src/modes/workflow.ts +55 -0
  942. package/src/plan-mode/approved-plan.ts +194 -0
  943. package/src/plan-mode/model-transition.ts +51 -0
  944. package/src/plan-mode/plan-files.ts +40 -0
  945. package/src/plan-mode/plan-handoff.ts +37 -0
  946. package/src/plan-mode/plan-protection.ts +31 -0
  947. package/src/plan-mode/state.ts +6 -0
  948. package/src/priority.json +60 -0
  949. package/src/prompts/advisor/active-repo-watchdog.md +6 -0
  950. package/src/prompts/advisor/advise-tool.md +3 -0
  951. package/src/prompts/advisor/context-files.md +8 -0
  952. package/src/prompts/advisor/system.md +98 -0
  953. package/src/prompts/agents/designer.md +74 -0
  954. package/src/prompts/agents/frontmatter.md +12 -0
  955. package/src/prompts/agents/init.md +33 -0
  956. package/src/prompts/agents/librarian.md +119 -0
  957. package/src/prompts/agents/reviewer.md +139 -0
  958. package/src/prompts/agents/scout.md +58 -0
  959. package/src/prompts/agents/security-reviewer.md +75 -0
  960. package/src/prompts/agents/task.md +17 -0
  961. package/src/prompts/bench/cache-prefix-chunk.md +1 -0
  962. package/src/prompts/bench/cache-prefix.md +3 -0
  963. package/src/prompts/bench/cache-suffix.md +1 -0
  964. package/src/prompts/bench.md +6 -0
  965. package/src/prompts/ci-green-request.md +36 -0
  966. package/src/prompts/dry-balance-bench.md +8 -0
  967. package/src/prompts/goals/goal-budget-limit.md +16 -0
  968. package/src/prompts/goals/goal-continuation.md +28 -0
  969. package/src/prompts/goals/goal-mode-active.md +23 -0
  970. package/src/prompts/goals/goal-mode-context.md +4 -0
  971. package/src/prompts/goals/goal-todo-context.md +12 -0
  972. package/src/prompts/goals/guided-goal-interview.md +43 -0
  973. package/src/prompts/memories/consolidation.md +30 -0
  974. package/src/prompts/memories/consolidation_system.md +4 -0
  975. package/src/prompts/memories/read-path.md +17 -0
  976. package/src/prompts/memories/stage_one_input.md +6 -0
  977. package/src/prompts/memories/stage_one_system.md +21 -0
  978. package/src/prompts/review-custom-request.md +21 -0
  979. package/src/prompts/review-headless-request.md +16 -0
  980. package/src/prompts/review-request.md +68 -0
  981. package/src/prompts/security/scan-coordinator.md +7 -0
  982. package/src/prompts/security/scan-request.md +21 -0
  983. package/src/prompts/security/validate-request.md +8 -0
  984. package/src/prompts/session/launch-completion.md +1 -0
  985. package/src/prompts/skills/autoload.md +8 -0
  986. package/src/prompts/skills/user-invocation.md +11 -0
  987. package/src/prompts/steering/parent-irc.md +5 -0
  988. package/src/prompts/steering/user-interjection.md +6 -0
  989. package/src/prompts/system/active-repo-context.md +4 -0
  990. package/src/prompts/system/agent-creation-architect.md +50 -0
  991. package/src/prompts/system/agent-creation-user.md +6 -0
  992. package/src/prompts/system/auto-continue.md +1 -0
  993. package/src/prompts/system/auto-thinking-difficulty-local.md +14 -0
  994. package/src/prompts/system/auto-thinking-difficulty.md +14 -0
  995. package/src/prompts/system/autolearn-guidance-learn.md +1 -0
  996. package/src/prompts/system/autolearn-guidance.md +7 -0
  997. package/src/prompts/system/autolearn-nudge-autocontinue.md +5 -0
  998. package/src/prompts/system/background-tan-dispatch.md +8 -0
  999. package/src/prompts/system/btw-user.md +8 -0
  1000. package/src/prompts/system/commit-message-system.md +14 -0
  1001. package/src/prompts/system/computer-safety.md +14 -0
  1002. package/src/prompts/system/custom-system-prompt.md +64 -0
  1003. package/src/prompts/system/eager-task.md +7 -0
  1004. package/src/prompts/system/eager-todo.md +18 -0
  1005. package/src/prompts/system/empty-stop-retry.md +4 -0
  1006. package/src/prompts/system/gemini-tool-call-reminder.md +9 -0
  1007. package/src/prompts/system/interrupted-thinking.md +7 -0
  1008. package/src/prompts/system/irc-autoreply.md +6 -0
  1009. package/src/prompts/system/irc-incoming.md +9 -0
  1010. package/src/prompts/system/manual-continue.md +7 -0
  1011. package/src/prompts/system/mcp-xdev-guidance.md +11 -0
  1012. package/src/prompts/system/memory-consolidation-system.md +8 -0
  1013. package/src/prompts/system/memory-extraction-system.md +26 -0
  1014. package/src/prompts/system/mid-run-todo-nudge.md +3 -0
  1015. package/src/prompts/system/omfg-user.md +50 -0
  1016. package/src/prompts/system/orchestrate-notice.md +40 -0
  1017. package/src/prompts/system/personalities/default.md +18 -0
  1018. package/src/prompts/system/personalities/friendly.md +17 -0
  1019. package/src/prompts/system/personalities/pragmatic.md +15 -0
  1020. package/src/prompts/system/plan-mode-active.md +125 -0
  1021. package/src/prompts/system/plan-mode-approved.md +22 -0
  1022. package/src/prompts/system/plan-mode-compact-instructions.md +17 -0
  1023. package/src/prompts/system/plan-mode-reference.md +10 -0
  1024. package/src/prompts/system/plan-mode-subagent.md +33 -0
  1025. package/src/prompts/system/plan-mode-tool-decision-reminder.md +9 -0
  1026. package/src/prompts/system/plan-yolo-handoff.md +5 -0
  1027. package/src/prompts/system/prewalk-checklist.md +7 -0
  1028. package/src/prompts/system/prewalk-continue.md +1 -0
  1029. package/src/prompts/system/prewalk-plan.md +13 -0
  1030. package/src/prompts/system/project-prompt.md +61 -0
  1031. package/src/prompts/system/recap-user.md +9 -0
  1032. package/src/prompts/system/resolve-device-reminder.md +3 -0
  1033. package/src/prompts/system/rewind-report.md +6 -0
  1034. package/src/prompts/system/side-channel-no-tools.md +3 -0
  1035. package/src/prompts/system/snapcompact-context-frames-note.md +1 -0
  1036. package/src/prompts/system/snapcompact-context-stub.md +1 -0
  1037. package/src/prompts/system/snapcompact-system-frames-note.md +1 -0
  1038. package/src/prompts/system/snapcompact-system-stub.md +1 -0
  1039. package/src/prompts/system/snapcompact-toolresult-note.md +1 -0
  1040. package/src/prompts/system/speech-rewrite.md +15 -0
  1041. package/src/prompts/system/subagent-async-pending.md +6 -0
  1042. package/src/prompts/system/subagent-system-prompt.md +73 -0
  1043. package/src/prompts/system/subagent-user-prompt.md +3 -0
  1044. package/src/prompts/system/subagent-yield-reminder.md +23 -0
  1045. package/src/prompts/system/system-prompt.md +263 -0
  1046. package/src/prompts/system/tan-context-switch.md +17 -0
  1047. package/src/prompts/system/task-label.md +23 -0
  1048. package/src/prompts/system/thinking-loop-redirect.md +10 -0
  1049. package/src/prompts/system/title-marker-instruction.md +1 -0
  1050. package/src/prompts/system/title-system.md +16 -0
  1051. package/src/prompts/system/tool-call-loop-redirect.md +8 -0
  1052. package/src/prompts/system/ttsr-interrupt.md +7 -0
  1053. package/src/prompts/system/ttsr-tool-reminder.md +5 -0
  1054. package/src/prompts/system/ultrathink-notice.md +3 -0
  1055. package/src/prompts/system/unexpected-stop-classifier.md +17 -0
  1056. package/src/prompts/system/unexpected-stop-retry.md +4 -0
  1057. package/src/prompts/system/vibe-mode-active.md +26 -0
  1058. package/src/prompts/system/web-search.md +25 -0
  1059. package/src/prompts/system/workflow-notice.md +112 -0
  1060. package/src/prompts/system/xdev-mount-notice.md +20 -0
  1061. package/src/prompts/tools/apply-patch.md +65 -0
  1062. package/src/prompts/tools/ask.md +22 -0
  1063. package/src/prompts/tools/ast-edit.md +11 -0
  1064. package/src/prompts/tools/ast-grep.md +19 -0
  1065. package/src/prompts/tools/async-result.md +8 -0
  1066. package/src/prompts/tools/bash.md +23 -0
  1067. package/src/prompts/tools/browser.md +29 -0
  1068. package/src/prompts/tools/checkpoint.md +15 -0
  1069. package/src/prompts/tools/computer.md +26 -0
  1070. package/src/prompts/tools/debug.md +3 -0
  1071. package/src/prompts/tools/eval.md +45 -0
  1072. package/src/prompts/tools/github.md +22 -0
  1073. package/src/prompts/tools/glob.md +16 -0
  1074. package/src/prompts/tools/goal.md +11 -0
  1075. package/src/prompts/tools/grep.md +13 -0
  1076. package/src/prompts/tools/hub.md +34 -0
  1077. package/src/prompts/tools/image-attachment-describe-system.md +8 -0
  1078. package/src/prompts/tools/image-attachment-describe.md +10 -0
  1079. package/src/prompts/tools/image-gen.md +7 -0
  1080. package/src/prompts/tools/inspect-image-system.md +20 -0
  1081. package/src/prompts/tools/inspect-image.md +22 -0
  1082. package/src/prompts/tools/learn.md +7 -0
  1083. package/src/prompts/tools/lsp-late-diagnostic.md +8 -0
  1084. package/src/prompts/tools/lsp.md +19 -0
  1085. package/src/prompts/tools/manage-skill.md +9 -0
  1086. package/src/prompts/tools/memory-edit.md +12 -0
  1087. package/src/prompts/tools/patch.md +57 -0
  1088. package/src/prompts/tools/read.md +27 -0
  1089. package/src/prompts/tools/recall.md +7 -0
  1090. package/src/prompts/tools/reflect.md +5 -0
  1091. package/src/prompts/tools/replace.md +30 -0
  1092. package/src/prompts/tools/retain.md +6 -0
  1093. package/src/prompts/tools/rewind.md +14 -0
  1094. package/src/prompts/tools/security-publish.md +1 -0
  1095. package/src/prompts/tools/security-scan.md +1 -0
  1096. package/src/prompts/tools/task-async-contract.md +1 -0
  1097. package/src/prompts/tools/task-summary.md +20 -0
  1098. package/src/prompts/tools/task.md +83 -0
  1099. package/src/prompts/tools/todo.md +42 -0
  1100. package/src/prompts/tools/vibe-kill.md +3 -0
  1101. package/src/prompts/tools/vibe-list.md +3 -0
  1102. package/src/prompts/tools/vibe-send.md +9 -0
  1103. package/src/prompts/tools/vibe-spawn.md +10 -0
  1104. package/src/prompts/tools/vibe-turn-result.md +19 -0
  1105. package/src/prompts/tools/vibe-wait.md +8 -0
  1106. package/src/prompts/tools/web-search.md +8 -0
  1107. package/src/prompts/tools/write.md +14 -0
  1108. package/src/registry/agent-lifecycle.ts +505 -0
  1109. package/src/registry/agent-registry.ts +287 -0
  1110. package/src/registry/persisted-agents.ts +423 -0
  1111. package/src/sdk.ts +3820 -0
  1112. package/src/secrets/index.ts +375 -0
  1113. package/src/secrets/obfuscator.ts +2629 -0
  1114. package/src/secrets/regex.ts +21 -0
  1115. package/src/security/auth.ts +98 -0
  1116. package/src/security/cloud.ts +686 -0
  1117. package/src/security/comparison.ts +255 -0
  1118. package/src/security/contracts/ids.ts +111 -0
  1119. package/src/security/contracts/index.ts +4 -0
  1120. package/src/security/contracts/schemas.ts +219 -0
  1121. package/src/security/contracts/types.ts +254 -0
  1122. package/src/security/contracts/validation.ts +69 -0
  1123. package/src/security/coordinator.ts +708 -0
  1124. package/src/security/importers/codex-security.ts +387 -0
  1125. package/src/security/importers/index.ts +2 -0
  1126. package/src/security/importers/sarif.ts +357 -0
  1127. package/src/security/index.ts +13 -0
  1128. package/src/security/preflight.ts +405 -0
  1129. package/src/security/provenance.ts +106 -0
  1130. package/src/security/publication.ts +326 -0
  1131. package/src/security/remediation.ts +93 -0
  1132. package/src/security/resource-output.ts +50 -0
  1133. package/src/security/sarif.ts +78 -0
  1134. package/src/security/store.ts +430 -0
  1135. package/src/session/acp-permission-gate.ts +165 -0
  1136. package/src/session/agent-session-events.ts +67 -0
  1137. package/src/session/agent-session-types.ts +407 -0
  1138. package/src/session/agent-session.ts +9000 -0
  1139. package/src/session/agent-storage.ts +807 -0
  1140. package/src/session/artifacts.ts +154 -0
  1141. package/src/session/async-job-delivery.ts +82 -0
  1142. package/src/session/auth-broker-config.ts +92 -0
  1143. package/src/session/auth-storage.ts +25 -0
  1144. package/src/session/bash-runner.ts +326 -0
  1145. package/src/session/blob-store.ts +295 -0
  1146. package/src/session/checkpoint-entries.ts +81 -0
  1147. package/src/session/claude-session-store.ts +426 -0
  1148. package/src/session/client-bridge.ts +85 -0
  1149. package/src/session/codex-auto-reset.ts +673 -0
  1150. package/src/session/codex-session-store.ts +673 -0
  1151. package/src/session/compact-modes.ts +105 -0
  1152. package/src/session/credential-pin.ts +93 -0
  1153. package/src/session/eval-runner.ts +219 -0
  1154. package/src/session/exit-diagnostics.ts +310 -0
  1155. package/src/session/foreign-session-import.ts +52 -0
  1156. package/src/session/foreign-session-jsonl.ts +29 -0
  1157. package/src/session/foreign-session-store.ts +26 -0
  1158. package/src/session/history-storage.ts +329 -0
  1159. package/src/session/indexed-session-storage.ts +553 -0
  1160. package/src/session/irc-bridge.ts +203 -0
  1161. package/src/session/launch-completion.ts +37 -0
  1162. package/src/session/messages.ts +1304 -0
  1163. package/src/session/model-controls.ts +757 -0
  1164. package/src/session/prewalk.ts +279 -0
  1165. package/src/session/provider-image-budget.ts +86 -0
  1166. package/src/session/queued-messages.ts +99 -0
  1167. package/src/session/redis-session-storage.ts +257 -0
  1168. package/src/session/retry-fallback-chains.ts +455 -0
  1169. package/src/session/role-models.ts +85 -0
  1170. package/src/session/session-advisors.ts +1896 -0
  1171. package/src/session/session-context.ts +584 -0
  1172. package/src/session/session-dump-format.ts +216 -0
  1173. package/src/session/session-entries.ts +306 -0
  1174. package/src/session/session-handoff.ts +325 -0
  1175. package/src/session/session-history-format.ts +459 -0
  1176. package/src/session/session-listing.ts +715 -0
  1177. package/src/session/session-loader.ts +362 -0
  1178. package/src/session/session-maintenance.ts +3115 -0
  1179. package/src/session/session-manager.ts +2747 -0
  1180. package/src/session/session-memory.ts +222 -0
  1181. package/src/session/session-metadata.ts +53 -0
  1182. package/src/session/session-migrations.ts +78 -0
  1183. package/src/session/session-paths.ts +280 -0
  1184. package/src/session/session-persistence.ts +293 -0
  1185. package/src/session/session-provider-boundary.ts +306 -0
  1186. package/src/session/session-stats.ts +349 -0
  1187. package/src/session/session-storage.ts +774 -0
  1188. package/src/session/session-title-slot.ts +141 -0
  1189. package/src/session/session-tools.ts +1385 -0
  1190. package/src/session/session-workspace.ts +53 -0
  1191. package/src/session/settings-stream-fn.ts +79 -0
  1192. package/src/session/shake-types.ts +43 -0
  1193. package/src/session/snapcompact-inline.ts +545 -0
  1194. package/src/session/snapcompact-savings-journal.ts +113 -0
  1195. package/src/session/sql-session-storage.ts +374 -0
  1196. package/src/session/stream-guards.ts +417 -0
  1197. package/src/session/streaming-output.ts +1459 -0
  1198. package/src/session/todo-tracker.ts +380 -0
  1199. package/src/session/tool-choice-queue.ts +305 -0
  1200. package/src/session/ttsr-coordinator.ts +496 -0
  1201. package/src/session/turn-persistence.ts +142 -0
  1202. package/src/session/turn-recovery.ts +2005 -0
  1203. package/src/session/unexpected-stop-classifier.ts +141 -0
  1204. package/src/session/yield-queue.ts +288 -0
  1205. package/src/slash-commands/acp-builtins.ts +70 -0
  1206. package/src/slash-commands/available-commands.ts +105 -0
  1207. package/src/slash-commands/builtin-registry.ts +3149 -0
  1208. package/src/slash-commands/helpers/active-oauth-account.ts +80 -0
  1209. package/src/slash-commands/helpers/collab-qrcode.ts +28 -0
  1210. package/src/slash-commands/helpers/context-report.ts +66 -0
  1211. package/src/slash-commands/helpers/format.ts +46 -0
  1212. package/src/slash-commands/helpers/logout.ts +108 -0
  1213. package/src/slash-commands/helpers/marketplace-manager.ts +25 -0
  1214. package/src/slash-commands/helpers/mcp.ts +533 -0
  1215. package/src/slash-commands/helpers/parse.ts +85 -0
  1216. package/src/slash-commands/helpers/reset-usage.ts +68 -0
  1217. package/src/slash-commands/helpers/security.ts +451 -0
  1218. package/src/slash-commands/helpers/session-pin.ts +44 -0
  1219. package/src/slash-commands/helpers/ssh.ts +196 -0
  1220. package/src/slash-commands/helpers/stats-dashboard.ts +86 -0
  1221. package/src/slash-commands/helpers/todo.ts +285 -0
  1222. package/src/slash-commands/helpers/usage-report.ts +198 -0
  1223. package/src/slash-commands/marketplace-install-parser.ts +99 -0
  1224. package/src/slash-commands/types.ts +139 -0
  1225. package/src/ssh/config-writer.ts +183 -0
  1226. package/src/ssh/connection-manager.ts +667 -0
  1227. package/src/ssh/file-transfer.ts +214 -0
  1228. package/src/ssh/sshfs-mount.ts +163 -0
  1229. package/src/ssh/utils.ts +51 -0
  1230. package/src/startup-splash.ts +19 -0
  1231. package/src/stt/asr-client.ts +401 -0
  1232. package/src/stt/asr-protocol.ts +65 -0
  1233. package/src/stt/asr-worker.ts +603 -0
  1234. package/src/stt/downloader.ts +142 -0
  1235. package/src/stt/endpointer.ts +259 -0
  1236. package/src/stt/index.ts +6 -0
  1237. package/src/stt/models.ts +150 -0
  1238. package/src/stt/sherpa-runtime.ts +71 -0
  1239. package/src/stt/stt-controller.ts +320 -0
  1240. package/src/stt/submit-trigger.ts +74 -0
  1241. package/src/subprocess/worker-client.ts +463 -0
  1242. package/src/subprocess/worker-runtime.ts +494 -0
  1243. package/src/system-prompt.ts +921 -0
  1244. package/src/task/agents.ts +170 -0
  1245. package/src/task/commands.ts +132 -0
  1246. package/src/task/discovery.ts +145 -0
  1247. package/src/task/executor.ts +3431 -0
  1248. package/src/task/index.ts +1515 -0
  1249. package/src/task/isolation-ownership.ts +106 -0
  1250. package/src/task/isolation-runner.ts +444 -0
  1251. package/src/task/label.ts +40 -0
  1252. package/src/task/name-generator.ts +1577 -0
  1253. package/src/task/omp-command.ts +26 -0
  1254. package/src/task/output-manager.ts +115 -0
  1255. package/src/task/parallel.ts +221 -0
  1256. package/src/task/persisted-revive.ts +173 -0
  1257. package/src/task/prewalk.ts +6 -0
  1258. package/src/task/prompt-policy.ts +8 -0
  1259. package/src/task/provider-concurrency.ts +100 -0
  1260. package/src/task/read-only-policy.ts +27 -0
  1261. package/src/task/render.ts +1830 -0
  1262. package/src/task/renderer.ts +14 -0
  1263. package/src/task/repair-args.ts +118 -0
  1264. package/src/task/spawn-policy.ts +72 -0
  1265. package/src/task/structured-subagent.ts +676 -0
  1266. package/src/task/subprocess-tool-registry.ts +88 -0
  1267. package/src/task/types.ts +555 -0
  1268. package/src/task/worktree.ts +967 -0
  1269. package/src/task/yield-assembly.ts +198 -0
  1270. package/src/telemetry-export.ts +504 -0
  1271. package/src/thinking.ts +377 -0
  1272. package/src/tiny/device.ts +111 -0
  1273. package/src/tiny/dtype.ts +101 -0
  1274. package/src/tiny/message-preproc.ts +155 -0
  1275. package/src/tiny/models.ts +268 -0
  1276. package/src/tiny/text.ts +290 -0
  1277. package/src/tiny/title-client.ts +460 -0
  1278. package/src/tiny/title-protocol.ts +56 -0
  1279. package/src/tiny/worker.ts +354 -0
  1280. package/src/tools/acp-bridge.ts +125 -0
  1281. package/src/tools/approval.ts +245 -0
  1282. package/src/tools/ask.ts +1459 -0
  1283. package/src/tools/ast-edit.ts +718 -0
  1284. package/src/tools/ast-grep.ts +526 -0
  1285. package/src/tools/auto-generated-guard.ts +335 -0
  1286. package/src/tools/bash-interactive.ts +435 -0
  1287. package/src/tools/bash-interceptor.ts +148 -0
  1288. package/src/tools/bash-pty-selection.ts +14 -0
  1289. package/src/tools/bash-skill-urls.ts +350 -0
  1290. package/src/tools/bash.ts +1826 -0
  1291. package/src/tools/browser/aria/aria-snapshot.bundle.txt +7 -0
  1292. package/src/tools/browser/aria/aria-snapshot.ts +131 -0
  1293. package/src/tools/browser/attach.ts +219 -0
  1294. package/src/tools/browser/cmux/cmux-tab.ts +1531 -0
  1295. package/src/tools/browser/cmux/rpc.ts +200 -0
  1296. package/src/tools/browser/cmux/socket-client.ts +445 -0
  1297. package/src/tools/browser/launch.ts +939 -0
  1298. package/src/tools/browser/readable.ts +112 -0
  1299. package/src/tools/browser/registry.ts +447 -0
  1300. package/src/tools/browser/relay/bridge.ts +945 -0
  1301. package/src/tools/browser/relay/daemon.ts +117 -0
  1302. package/src/tools/browser/relay/extension-assets/background.js.txt +242 -0
  1303. package/src/tools/browser/relay/extension-assets/manifest.json.txt +14 -0
  1304. package/src/tools/browser/relay/extension-assets/options.html.txt +53 -0
  1305. package/src/tools/browser/relay/extension-assets/options.js.txt +23 -0
  1306. package/src/tools/browser/relay/kind.ts +41 -0
  1307. package/src/tools/browser/relay/protocol.ts +54 -0
  1308. package/src/tools/browser/relay/server.ts +141 -0
  1309. package/src/tools/browser/render.ts +229 -0
  1310. package/src/tools/browser/run-output.ts +76 -0
  1311. package/src/tools/browser/shared-daemon.ts +139 -0
  1312. package/src/tools/browser/tab-protocol.ts +123 -0
  1313. package/src/tools/browser/tab-supervisor.ts +1077 -0
  1314. package/src/tools/browser/tab-worker-entry.ts +29 -0
  1315. package/src/tools/browser/tab-worker.ts +1982 -0
  1316. package/src/tools/browser.ts +487 -0
  1317. package/src/tools/builtin-names.ts +67 -0
  1318. package/src/tools/checkpoint.ts +137 -0
  1319. package/src/tools/computer/exposure.ts +14 -0
  1320. package/src/tools/computer/protocol.ts +69 -0
  1321. package/src/tools/computer/supervisor.ts +409 -0
  1322. package/src/tools/computer/worker-entry.ts +39 -0
  1323. package/src/tools/computer/worker.ts +745 -0
  1324. package/src/tools/computer-renderer.ts +147 -0
  1325. package/src/tools/computer.ts +222 -0
  1326. package/src/tools/conflict-detect.ts +815 -0
  1327. package/src/tools/context.ts +49 -0
  1328. package/src/tools/debug.ts +1121 -0
  1329. package/src/tools/default-renderer.ts +154 -0
  1330. package/src/tools/essential-tools.ts +46 -0
  1331. package/src/tools/eval-backends.ts +34 -0
  1332. package/src/tools/eval-format/index.ts +24 -0
  1333. package/src/tools/eval-format/javascript.ts +952 -0
  1334. package/src/tools/eval-format/julia.ts +446 -0
  1335. package/src/tools/eval-format/python.ts +544 -0
  1336. package/src/tools/eval-format/ruby.ts +380 -0
  1337. package/src/tools/eval-render.ts +784 -0
  1338. package/src/tools/eval.ts +774 -0
  1339. package/src/tools/fetch.ts +1889 -0
  1340. package/src/tools/file-recorder.ts +35 -0
  1341. package/src/tools/fs-cache-invalidation.ts +28 -0
  1342. package/src/tools/gh-cache-invalidation.ts +175 -0
  1343. package/src/tools/gh-format.ts +12 -0
  1344. package/src/tools/gh-renderer.ts +484 -0
  1345. package/src/tools/gh.ts +3958 -0
  1346. package/src/tools/github-cache.ts +663 -0
  1347. package/src/tools/glob.ts +691 -0
  1348. package/src/tools/grep.ts +1920 -0
  1349. package/src/tools/grouped-file-output.ts +210 -0
  1350. package/src/tools/hub/index.ts +579 -0
  1351. package/src/tools/hub/jobs.ts +714 -0
  1352. package/src/tools/hub/launch.ts +690 -0
  1353. package/src/tools/hub/messaging.ts +735 -0
  1354. package/src/tools/hub/types.ts +117 -0
  1355. package/src/tools/image-gen.ts +1689 -0
  1356. package/src/tools/image-providers.ts +50 -0
  1357. package/src/tools/index.ts +736 -0
  1358. package/src/tools/inspect-image-renderer.ts +133 -0
  1359. package/src/tools/inspect-image.ts +316 -0
  1360. package/src/tools/json-tree.ts +260 -0
  1361. package/src/tools/jtd-to-json-schema.ts +219 -0
  1362. package/src/tools/jtd-to-typescript.ts +136 -0
  1363. package/src/tools/jtd-utils.ts +102 -0
  1364. package/src/tools/learn.ts +141 -0
  1365. package/src/tools/list-limit.ts +40 -0
  1366. package/src/tools/manage-skill.ts +102 -0
  1367. package/src/tools/match-line-format.ts +20 -0
  1368. package/src/tools/memory-edit.ts +61 -0
  1369. package/src/tools/memory-recall.ts +102 -0
  1370. package/src/tools/memory-reflect.ts +88 -0
  1371. package/src/tools/memory-render.ts +211 -0
  1372. package/src/tools/memory-retain.ts +89 -0
  1373. package/src/tools/output-meta.ts +860 -0
  1374. package/src/tools/output-schema-validator.ts +307 -0
  1375. package/src/tools/path-utils.ts +1489 -0
  1376. package/src/tools/plan-mode-guard.ts +155 -0
  1377. package/src/tools/puppeteer/00_stealth_tampering.txt +44 -0
  1378. package/src/tools/puppeteer/01_stealth_activity.txt +80 -0
  1379. package/src/tools/puppeteer/02_stealth_hairline.txt +57 -0
  1380. package/src/tools/puppeteer/03_stealth_botd.txt +380 -0
  1381. package/src/tools/puppeteer/04_stealth_iframe.txt +174 -0
  1382. package/src/tools/puppeteer/05_stealth_webgl.txt +233 -0
  1383. package/src/tools/puppeteer/06_stealth_screen.txt +260 -0
  1384. package/src/tools/puppeteer/07_stealth_fonts.txt +99 -0
  1385. package/src/tools/puppeteer/08_stealth_audio.txt +63 -0
  1386. package/src/tools/puppeteer/09_stealth_locale.txt +51 -0
  1387. package/src/tools/puppeteer/10_stealth_plugins.txt +212 -0
  1388. package/src/tools/puppeteer/11_stealth_hardware.txt +59 -0
  1389. package/src/tools/puppeteer/12_stealth_codecs.txt +42 -0
  1390. package/src/tools/puppeteer/13_stealth_worker.txt +235 -0
  1391. package/src/tools/read.ts +3762 -0
  1392. package/src/tools/render-utils.ts +926 -0
  1393. package/src/tools/renderers.ts +133 -0
  1394. package/src/tools/report-tool-issue.ts +568 -0
  1395. package/src/tools/resolve.ts +423 -0
  1396. package/src/tools/review.ts +103 -0
  1397. package/src/tools/run-scope.ts +417 -0
  1398. package/src/tools/security-scan.ts +287 -0
  1399. package/src/tools/shell-tokenize.ts +213 -0
  1400. package/src/tools/sqlite-reader.ts +884 -0
  1401. package/src/tools/terminal-output.ts +141 -0
  1402. package/src/tools/todo.ts +1226 -0
  1403. package/src/tools/tool-errors.ts +62 -0
  1404. package/src/tools/tool-result.ts +102 -0
  1405. package/src/tools/tool-timeouts.ts +38 -0
  1406. package/src/tools/tts.ts +266 -0
  1407. package/src/tools/vibe.ts +608 -0
  1408. package/src/tools/write.ts +1646 -0
  1409. package/src/tools/xdev.ts +560 -0
  1410. package/src/tools/yield.ts +486 -0
  1411. package/src/tts/downloader.ts +64 -0
  1412. package/src/tts/index.ts +10 -0
  1413. package/src/tts/models.ts +137 -0
  1414. package/src/tts/runtime.ts +21 -0
  1415. package/src/tts/speakable.ts +392 -0
  1416. package/src/tts/speech-enhancer.ts +206 -0
  1417. package/src/tts/streaming-player.ts +120 -0
  1418. package/src/tts/tts-client.ts +475 -0
  1419. package/src/tts/tts-protocol.ts +69 -0
  1420. package/src/tts/tts-worker.ts +434 -0
  1421. package/src/tts/vocalizer.ts +419 -0
  1422. package/src/tts/wav.ts +58 -0
  1423. package/src/tui/code-cell.ts +268 -0
  1424. package/src/tui/file-list.ts +55 -0
  1425. package/src/tui/hyperlink.ts +178 -0
  1426. package/src/tui/index.ts +13 -0
  1427. package/src/tui/output-block.ts +268 -0
  1428. package/src/tui/status-line.ts +54 -0
  1429. package/src/tui/tree-list.ts +172 -0
  1430. package/src/tui/types.ts +15 -0
  1431. package/src/tui/utils.ts +103 -0
  1432. package/src/tui/width-aware-text.ts +58 -0
  1433. package/src/utils/active-repo-context.ts +143 -0
  1434. package/src/utils/block-context.ts +312 -0
  1435. package/src/utils/changelog.ts +373 -0
  1436. package/src/utils/clipboard.ts +361 -0
  1437. package/src/utils/command-args.ts +74 -0
  1438. package/src/utils/commit-message-generator.ts +148 -0
  1439. package/src/utils/cpuprofile.ts +235 -0
  1440. package/src/utils/edit-mode.ts +61 -0
  1441. package/src/utils/enhanced-paste.ts +230 -0
  1442. package/src/utils/event-bus.ts +33 -0
  1443. package/src/utils/external-editor.ts +80 -0
  1444. package/src/utils/fetch-timeout.ts +10 -0
  1445. package/src/utils/file-display-mode.ts +44 -0
  1446. package/src/utils/file-mentions.ts +293 -0
  1447. package/src/utils/git.ts +2472 -0
  1448. package/src/utils/image-loading.ts +236 -0
  1449. package/src/utils/image-resize.ts +420 -0
  1450. package/src/utils/image-vision-fallback.ts +196 -0
  1451. package/src/utils/inspect-image-mode.ts +39 -0
  1452. package/src/utils/ipc.ts +38 -0
  1453. package/src/utils/jj.ts +422 -0
  1454. package/src/utils/lang-from-path.ts +251 -0
  1455. package/src/utils/late-cleanup.ts +17 -0
  1456. package/src/utils/local-date.ts +7 -0
  1457. package/src/utils/mac-file-urls.applescript +37 -0
  1458. package/src/utils/markit-cache.ts +166 -0
  1459. package/src/utils/markit.ts +223 -0
  1460. package/src/utils/mupdf-wasm-embed.ts +12 -0
  1461. package/src/utils/open.ts +126 -0
  1462. package/src/utils/profile-tree.ts +111 -0
  1463. package/src/utils/prompt-path.ts +3 -0
  1464. package/src/utils/qrcode.ts +535 -0
  1465. package/src/utils/sample-profile.ts +437 -0
  1466. package/src/utils/session-color.ts +142 -0
  1467. package/src/utils/shell-snapshot-fn-env.sh +63 -0
  1468. package/src/utils/shell-snapshot.ts +326 -0
  1469. package/src/utils/sixel.ts +69 -0
  1470. package/src/utils/thinking-display.ts +163 -0
  1471. package/src/utils/title-generator.ts +597 -0
  1472. package/src/utils/token-rate.ts +72 -0
  1473. package/src/utils/tool-choice.ts +50 -0
  1474. package/src/utils/tools-manager.ts +411 -0
  1475. package/src/utils/turndown.ts +82 -0
  1476. package/src/utils/zip.ts +1106 -0
  1477. package/src/vibe/runtime.ts +1684 -0
  1478. package/src/vibe/state.ts +4 -0
  1479. package/src/web/kagi.ts +305 -0
  1480. package/src/web/parallel.ts +354 -0
  1481. package/src/web/scrapers/artifacthub.ts +207 -0
  1482. package/src/web/scrapers/arxiv.ts +83 -0
  1483. package/src/web/scrapers/aur.ts +162 -0
  1484. package/src/web/scrapers/biorxiv.ts +133 -0
  1485. package/src/web/scrapers/bluesky.ts +262 -0
  1486. package/src/web/scrapers/brew.ts +172 -0
  1487. package/src/web/scrapers/cheatsh.ts +68 -0
  1488. package/src/web/scrapers/chocolatey.ts +196 -0
  1489. package/src/web/scrapers/choosealicense.ts +95 -0
  1490. package/src/web/scrapers/cisa-kev.ts +87 -0
  1491. package/src/web/scrapers/clojars.ts +154 -0
  1492. package/src/web/scrapers/coingecko.ts +177 -0
  1493. package/src/web/scrapers/crates-io.ts +97 -0
  1494. package/src/web/scrapers/crossref.ts +136 -0
  1495. package/src/web/scrapers/devto.ts +147 -0
  1496. package/src/web/scrapers/discogs.ts +306 -0
  1497. package/src/web/scrapers/discourse.ts +197 -0
  1498. package/src/web/scrapers/dockerhub.ts +138 -0
  1499. package/src/web/scrapers/docs-rs.ts +663 -0
  1500. package/src/web/scrapers/fdroid.ts +134 -0
  1501. package/src/web/scrapers/firefox-addons.ts +191 -0
  1502. package/src/web/scrapers/flathub.ts +223 -0
  1503. package/src/web/scrapers/github-gist.ts +58 -0
  1504. package/src/web/scrapers/github.ts +800 -0
  1505. package/src/web/scrapers/gitlab.ts +401 -0
  1506. package/src/web/scrapers/go-pkg.ts +266 -0
  1507. package/src/web/scrapers/hackage.ts +129 -0
  1508. package/src/web/scrapers/hackernews.ts +189 -0
  1509. package/src/web/scrapers/hex.ts +105 -0
  1510. package/src/web/scrapers/huggingface.ts +321 -0
  1511. package/src/web/scrapers/iacr.ts +89 -0
  1512. package/src/web/scrapers/index.ts +252 -0
  1513. package/src/web/scrapers/jetbrains-marketplace.ts +159 -0
  1514. package/src/web/scrapers/lemmy.ts +203 -0
  1515. package/src/web/scrapers/lobsters.ts +175 -0
  1516. package/src/web/scrapers/mastodon.ts +292 -0
  1517. package/src/web/scrapers/maven.ts +138 -0
  1518. package/src/web/scrapers/mdn.ts +173 -0
  1519. package/src/web/scrapers/metacpan.ts +222 -0
  1520. package/src/web/scrapers/musicbrainz.ts +250 -0
  1521. package/src/web/scrapers/npm.ts +98 -0
  1522. package/src/web/scrapers/nuget.ts +183 -0
  1523. package/src/web/scrapers/nvd.ts +222 -0
  1524. package/src/web/scrapers/ollama.ts +239 -0
  1525. package/src/web/scrapers/open-vsx.ts +106 -0
  1526. package/src/web/scrapers/opencorporates.ts +292 -0
  1527. package/src/web/scrapers/openlibrary.ts +336 -0
  1528. package/src/web/scrapers/orcid.ts +286 -0
  1529. package/src/web/scrapers/osv.ts +176 -0
  1530. package/src/web/scrapers/packagist.ts +160 -0
  1531. package/src/web/scrapers/pub-dev.ts +143 -0
  1532. package/src/web/scrapers/pubmed.ts +211 -0
  1533. package/src/web/scrapers/pypi.ts +112 -0
  1534. package/src/web/scrapers/rawg.ts +110 -0
  1535. package/src/web/scrapers/readthedocs.ts +121 -0
  1536. package/src/web/scrapers/reddit.ts +95 -0
  1537. package/src/web/scrapers/repology.ts +251 -0
  1538. package/src/web/scrapers/rfc.ts +201 -0
  1539. package/src/web/scrapers/rubygems.ts +103 -0
  1540. package/src/web/scrapers/searchcode.ts +189 -0
  1541. package/src/web/scrapers/sec-edgar.ts +261 -0
  1542. package/src/web/scrapers/semantic-scholar.ts +171 -0
  1543. package/src/web/scrapers/snapcraft.ts +187 -0
  1544. package/src/web/scrapers/sourcegraph.ts +336 -0
  1545. package/src/web/scrapers/spdx.ts +108 -0
  1546. package/src/web/scrapers/spotify.ts +198 -0
  1547. package/src/web/scrapers/stackoverflow.ts +120 -0
  1548. package/src/web/scrapers/terraform.ts +277 -0
  1549. package/src/web/scrapers/tldr.ts +47 -0
  1550. package/src/web/scrapers/twitter.ts +94 -0
  1551. package/src/web/scrapers/types.ts +354 -0
  1552. package/src/web/scrapers/utils.ts +109 -0
  1553. package/src/web/scrapers/vimeo.ts +133 -0
  1554. package/src/web/scrapers/vscode-marketplace.ts +187 -0
  1555. package/src/web/scrapers/w3c.ts +156 -0
  1556. package/src/web/scrapers/wikidata.ts +344 -0
  1557. package/src/web/scrapers/wikipedia.ts +84 -0
  1558. package/src/web/scrapers/youtube.ts +325 -0
  1559. package/src/web/search/index.ts +393 -0
  1560. package/src/web/search/provider.ts +272 -0
  1561. package/src/web/search/providers/anthropic.ts +406 -0
  1562. package/src/web/search/providers/base.ts +112 -0
  1563. package/src/web/search/providers/brave.ts +181 -0
  1564. package/src/web/search/providers/browser-headers.ts +82 -0
  1565. package/src/web/search/providers/browser-page.ts +125 -0
  1566. package/src/web/search/providers/codex.ts +788 -0
  1567. package/src/web/search/providers/duckduckgo.ts +382 -0
  1568. package/src/web/search/providers/ecosia.ts +183 -0
  1569. package/src/web/search/providers/exa.ts +513 -0
  1570. package/src/web/search/providers/firecrawl.ts +213 -0
  1571. package/src/web/search/providers/gemini.ts +634 -0
  1572. package/src/web/search/providers/google.ts +195 -0
  1573. package/src/web/search/providers/jina.ts +144 -0
  1574. package/src/web/search/providers/kagi.ts +98 -0
  1575. package/src/web/search/providers/kimi.ts +221 -0
  1576. package/src/web/search/providers/mojeek.ts +220 -0
  1577. package/src/web/search/providers/parallel.ts +186 -0
  1578. package/src/web/search/providers/perplexity-auth.ts +142 -0
  1579. package/src/web/search/providers/perplexity.ts +997 -0
  1580. package/src/web/search/providers/public.ts +199 -0
  1581. package/src/web/search/providers/searxng.ts +467 -0
  1582. package/src/web/search/providers/startpage.ts +225 -0
  1583. package/src/web/search/providers/synthetic.ts +126 -0
  1584. package/src/web/search/providers/tavily.ts +244 -0
  1585. package/src/web/search/providers/tinyfish.ts +166 -0
  1586. package/src/web/search/providers/utils.ts +130 -0
  1587. package/src/web/search/providers/xai.ts +372 -0
  1588. package/src/web/search/providers/zai.ts +452 -0
  1589. package/src/web/search/query.ts +850 -0
  1590. package/src/web/search/render.ts +262 -0
  1591. package/src/web/search/types.ts +518 -0
  1592. package/src/web/search/utils.ts +17 -0
  1593. package/src/workspace-tree.ts +326 -0
@@ -0,0 +1,2643 @@
1
+ /// <reference path="./legacy-pi-virtual-modules.d.ts" />
2
+
3
+ import * as fs from "node:fs";
4
+ import { createRequire, isBuiltin } from "node:module";
5
+ import * as path from "node:path";
6
+ import * as url from "node:url";
7
+ import type { ParseResult, ParserPlugin } from "@babel/parser";
8
+ import { parse as parseBabel } from "@babel/parser";
9
+ import { isCompiledBinary, stripWindowsExtendedLengthPathPrefix } from "@oh-my-pi/pi-utils";
10
+ import { registerPluginCacheInvalidator } from "../../discovery/helpers";
11
+
12
+ const IS_COMPILED_BINARY = isCompiledBinary();
13
+
14
+ // === Bundled host modules (issue #3423) ===
15
+ //
16
+ // Bun 1.3.14 stopped exposing `--compile` extras through any filesystem-style
17
+ // API: `fs.existsSync`, `Bun.file().exists()`, `Bun.resolveSync`, and even
18
+ // `import("/$bunfs/...")` / `import("file:///$bunfs/...")` all fail for the
19
+ // embedded entries. Bun.plugin `onResolve` also no longer fires for transitive
20
+ // imports inside runtime-loaded extensions.
21
+ //
22
+ // Compiled builds retain lazy loaders for host packages and serve requested
23
+ // surfaces through `omp-legacy-pi-bundled:<key>` synthetic modules.
24
+ // `scripts/legacy-pi-virtual-module.ts` derives literal dynamic-import edges
25
+ // from current package exports inside a Bun build plugin: no generated source
26
+ // or duplicate key list exists on disk. Deferring each host module evaluation
27
+ // avoids cycles with an extension-loading command that is itself in the
28
+ // retained package graph.
29
+ const BUNDLED_VIRTUAL_SCHEME = "omp-legacy-pi-bundled:";
30
+ const BUNDLED_VIRTUAL_NAMESPACE = "omp-legacy-pi-bundled";
31
+ const BUNDLED_MODULES_GLOBAL = "__ompLegacyPiBundledModules";
32
+ const TYPEBOX_BUNDLED_MODULE_KEY = "typebox";
33
+
34
+ type BundledModule = Readonly<Record<string, unknown>>;
35
+ type BundledModules = Readonly<Record<string, BundledModule>>;
36
+ type BundledModuleLoaders = Readonly<Record<string, () => Promise<BundledModule>>>;
37
+
38
+ interface LegacyPiResolveResult {
39
+ path: string;
40
+ namespace?: string;
41
+ }
42
+
43
+ interface BundledVirtualResolveResult {
44
+ path: string;
45
+ namespace: typeof BUNDLED_VIRTUAL_NAMESPACE;
46
+ }
47
+
48
+ interface ExtensionSpecifierReference {
49
+ readonly kind: "import" | "require";
50
+ readonly specifier: string;
51
+ readonly start: number;
52
+ readonly end: number;
53
+ }
54
+
55
+ function parseExtensionSource(source: string, importerPath: string): ParseResult {
56
+ const extension = path.extname(importerPath).toLowerCase();
57
+ const plugins: ParserPlugin[] = ["decorators-legacy", "explicitResourceManagement"];
58
+ if (extension === ".ts" || extension === ".mts" || extension === ".cts" || extension === ".tsx") {
59
+ plugins.push("typescript");
60
+ }
61
+ if (extension === ".jsx" || extension === ".tsx") {
62
+ plugins.push("jsx");
63
+ }
64
+
65
+ try {
66
+ return parseBabel(source, {
67
+ sourceType: "unambiguous",
68
+ allowAwaitOutsideFunction: true,
69
+ allowReturnOutsideFunction: true,
70
+ allowImportExportEverywhere: true,
71
+ allowNewTargetOutsideFunction: true,
72
+ allowSuperOutsideMethod: true,
73
+ allowUndeclaredExports: true,
74
+ errorRecovery: true,
75
+ plugins,
76
+ });
77
+ } catch (error) {
78
+ throw new Error(
79
+ `Failed to parse extension source for dependency rewriting: ${importerPath}: ${error instanceof Error ? error.message : String(error)}`,
80
+ { cause: error },
81
+ );
82
+ }
83
+ }
84
+
85
+ const REQUIRE_BINDING = 1 << 0;
86
+ const OBJECT_BINDING = 1 << 1;
87
+ const EXPORTS_BINDING = 1 << 2;
88
+ const MODULE_BINDING = 1 << 3;
89
+
90
+ interface StructuralAstNode {
91
+ readonly type: string;
92
+ readonly [key: string]: unknown;
93
+ }
94
+
95
+ interface BindingScope {
96
+ readonly parent: BindingScope | null;
97
+ readonly ownsVarBindings: boolean;
98
+ bindings: number;
99
+ }
100
+
101
+ interface ScopedAstNode {
102
+ readonly node: StructuralAstNode;
103
+ readonly scope: BindingScope;
104
+ readonly order: number;
105
+ }
106
+
107
+ interface ScopeWalkItem {
108
+ readonly node: StructuralAstNode;
109
+ readonly scope: BindingScope | null;
110
+ readonly parent: StructuralAstNode | null;
111
+ readonly parentKey: string | null;
112
+ }
113
+
114
+ function asAstNode(value: unknown): StructuralAstNode | null {
115
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
116
+ const candidate = value as { readonly type?: unknown };
117
+ return typeof candidate.type === "string" ? (candidate as StructuralAstNode) : null;
118
+ }
119
+
120
+ function nodeArray(node: StructuralAstNode, key: string): readonly unknown[] | null {
121
+ const value = node[key];
122
+ return Array.isArray(value) ? value : null;
123
+ }
124
+
125
+ function nodeArgument(node: StructuralAstNode | null, index: number): StructuralAstNode | null {
126
+ if (!node) return null;
127
+ const values = nodeArray(node, "arguments");
128
+ return values ? asAstNode(values[index]) : null;
129
+ }
130
+
131
+ function isIdentifier(node: StructuralAstNode | null, name: string): boolean {
132
+ return node?.type === "Identifier" && node.name === name;
133
+ }
134
+
135
+ function trackedBinding(name: unknown): number {
136
+ switch (name) {
137
+ case "require":
138
+ return REQUIRE_BINDING;
139
+ case "Object":
140
+ return OBJECT_BINDING;
141
+ case "exports":
142
+ return EXPORTS_BINDING;
143
+ case "module":
144
+ return MODULE_BINDING;
145
+ default:
146
+ return 0;
147
+ }
148
+ }
149
+
150
+ function addPatternBindings(scope: BindingScope, pattern: unknown): void {
151
+ const stack: unknown[] = [pattern];
152
+ while (stack.length > 0) {
153
+ const node = asAstNode(stack.pop());
154
+ if (!node) continue;
155
+ switch (node.type) {
156
+ case "Identifier":
157
+ scope.bindings |= trackedBinding(node.name);
158
+ break;
159
+ case "AssignmentPattern":
160
+ stack.push(node.left);
161
+ break;
162
+ case "RestElement":
163
+ stack.push(node.argument);
164
+ break;
165
+ case "ArrayPattern": {
166
+ const elements = nodeArray(node, "elements");
167
+ if (elements) stack.push(...elements);
168
+ break;
169
+ }
170
+ case "ObjectPattern": {
171
+ const properties = nodeArray(node, "properties");
172
+ if (!properties) break;
173
+ for (const value of properties) {
174
+ const property = asAstNode(value);
175
+ if (!property) continue;
176
+ stack.push(property.type === "RestElement" ? property.argument : property.value);
177
+ }
178
+ break;
179
+ }
180
+ case "TSParameterProperty":
181
+ stack.push(node.parameter);
182
+ break;
183
+ }
184
+ }
185
+ }
186
+
187
+ function isFunctionScopeNode(node: StructuralAstNode): boolean {
188
+ switch (node.type) {
189
+ case "FunctionDeclaration":
190
+ case "FunctionExpression":
191
+ case "ArrowFunctionExpression":
192
+ case "ObjectMethod":
193
+ case "ClassMethod":
194
+ case "ClassPrivateMethod":
195
+ case "TSDeclareFunction":
196
+ case "TSDeclareMethod":
197
+ case "DeclareFunction":
198
+ return true;
199
+ default:
200
+ return false;
201
+ }
202
+ }
203
+
204
+ function isFunctionDeclarationNode(node: StructuralAstNode): boolean {
205
+ return node.type === "FunctionDeclaration" || node.type === "TSDeclareFunction" || node.type === "DeclareFunction";
206
+ }
207
+
208
+ function isClassScopeNode(node: StructuralAstNode): boolean {
209
+ return node.type === "ClassDeclaration" || node.type === "ClassExpression";
210
+ }
211
+
212
+ function scopeKind(node: StructuralAstNode, parent: StructuralAstNode | null, parentKey: string | null): 0 | 1 | 2 {
213
+ if (
214
+ node.type === "Program" ||
215
+ isFunctionScopeNode(node) ||
216
+ node.type === "StaticBlock" ||
217
+ node.type === "TSModuleBlock"
218
+ ) {
219
+ return 2;
220
+ }
221
+ if (
222
+ isClassScopeNode(node) ||
223
+ node.type === "CatchClause" ||
224
+ node.type === "ForStatement" ||
225
+ node.type === "ForInStatement" ||
226
+ node.type === "ForOfStatement" ||
227
+ node.type === "SwitchStatement"
228
+ ) {
229
+ return 1;
230
+ }
231
+ if (node.type === "BlockStatement" && !(parent && isFunctionScopeNode(parent) && parentKey === "body")) {
232
+ return 1;
233
+ }
234
+ return 0;
235
+ }
236
+
237
+ function nearestVarScope(scope: BindingScope): BindingScope {
238
+ let current = scope;
239
+ while (!current.ownsVarBindings && current.parent) current = current.parent;
240
+ return current;
241
+ }
242
+
243
+ function registerOuterDeclaration(node: StructuralAstNode, scope: BindingScope | null): void {
244
+ if (!scope) return;
245
+ if (
246
+ (isFunctionDeclarationNode(node) && node.type !== "TSDeclareFunction" && node.type !== "DeclareFunction") ||
247
+ (node.type === "ClassDeclaration" && node.declare !== true)
248
+ ) {
249
+ addPatternBindings(scope, node.id);
250
+ }
251
+ }
252
+
253
+ function registerScopeBindings(node: StructuralAstNode, scope: BindingScope): void {
254
+ if (isFunctionScopeNode(node)) {
255
+ addPatternBindings(scope, node.id);
256
+ const parameters = nodeArray(node, "params");
257
+ if (parameters) {
258
+ for (const parameter of parameters) addPatternBindings(scope, parameter);
259
+ }
260
+ }
261
+ if (isClassScopeNode(node)) addPatternBindings(scope, node.id);
262
+ if (node.type === "CatchClause") addPatternBindings(scope, node.param);
263
+
264
+ if (node.type === "ImportDeclaration") {
265
+ const specifiers = nodeArray(node, "specifiers");
266
+ if (specifiers) {
267
+ for (const value of specifiers) {
268
+ const specifier = asAstNode(value);
269
+ if (specifier) addPatternBindings(scope, specifier.local);
270
+ }
271
+ }
272
+ } else if (node.type === "TSImportEqualsDeclaration") {
273
+ addPatternBindings(scope, node.id);
274
+ } else if (node.type === "VariableDeclaration") {
275
+ const target = node.kind === "var" ? nearestVarScope(scope) : scope;
276
+ const declarations = nodeArray(node, "declarations");
277
+ if (declarations) {
278
+ for (const value of declarations) {
279
+ const declaration = asAstNode(value);
280
+ if (declaration) addPatternBindings(target, declaration.id);
281
+ }
282
+ }
283
+ }
284
+ }
285
+
286
+ function isAstMetadataKey(key: string): boolean {
287
+ switch (key) {
288
+ case "loc":
289
+ case "extra":
290
+ case "range":
291
+ case "comments":
292
+ case "tokens":
293
+ case "errors":
294
+ case "leadingComments":
295
+ case "trailingComments":
296
+ case "innerComments":
297
+ case "parent":
298
+ case "parentPath":
299
+ case "scope":
300
+ case "hub":
301
+ return true;
302
+ default:
303
+ return false;
304
+ }
305
+ }
306
+
307
+ function scopeForChild(
308
+ node: StructuralAstNode,
309
+ key: string,
310
+ outerScope: BindingScope | null,
311
+ nodeScope: BindingScope,
312
+ ): BindingScope {
313
+ if (node.type === "SwitchStatement" && key === "discriminant") {
314
+ return outerScope ?? nodeScope;
315
+ }
316
+ if (isFunctionScopeNode(node) && (key === "key" || key === "decorators")) {
317
+ return outerScope ?? nodeScope;
318
+ }
319
+ if (isClassScopeNode(node) && key === "decorators") {
320
+ return outerScope ?? nodeScope;
321
+ }
322
+ return nodeScope;
323
+ }
324
+
325
+ /**
326
+ * Builds only the lexical information needed by legacy extension rewriting.
327
+ * Scope frames are fully populated before selected nodes are returned, so
328
+ * hoisted and TDZ bindings behave independently of textual declaration order.
329
+ */
330
+ function collectScopedAstNodes(root: unknown, select: (node: StructuralAstNode) => boolean): ScopedAstNode[] {
331
+ const rootNode = asAstNode(root);
332
+ if (!rootNode) return [];
333
+
334
+ const selected: ScopedAstNode[] = [];
335
+ const stack: ScopeWalkItem[] = [{ node: rootNode, scope: null, parent: null, parentKey: null }];
336
+ const seen = new WeakSet<object>();
337
+ let order = 0;
338
+ while (stack.length > 0) {
339
+ const item = stack.pop();
340
+ if (!item || seen.has(item.node)) continue;
341
+ seen.add(item.node);
342
+
343
+ registerOuterDeclaration(item.node, item.scope);
344
+ const kind = scopeKind(item.node, item.parent, item.parentKey);
345
+ const activeScope: BindingScope | null =
346
+ kind === 0
347
+ ? item.scope
348
+ : {
349
+ parent: item.scope,
350
+ ownsVarBindings: kind === 2,
351
+ bindings: 0,
352
+ };
353
+ if (activeScope) {
354
+ registerScopeBindings(item.node, activeScope);
355
+ if (select(item.node)) selected.push({ node: item.node, scope: activeScope, order });
356
+ }
357
+ order++;
358
+
359
+ for (const key in item.node) {
360
+ if (isAstMetadataKey(key)) continue;
361
+ const childScope = activeScope ? scopeForChild(item.node, key, item.scope, activeScope) : null;
362
+ const value = item.node[key];
363
+ if (Array.isArray(value)) {
364
+ for (const element of value) {
365
+ const child = asAstNode(element);
366
+ if (child) stack.push({ node: child, scope: childScope, parent: item.node, parentKey: key });
367
+ }
368
+ } else {
369
+ const child = asAstNode(value);
370
+ if (child) stack.push({ node: child, scope: childScope, parent: item.node, parentKey: key });
371
+ }
372
+ }
373
+ }
374
+
375
+ selected.sort((left, right) => {
376
+ const leftStart = typeof left.node.start === "number" ? left.node.start : Number.MAX_SAFE_INTEGER;
377
+ const rightStart = typeof right.node.start === "number" ? right.node.start : Number.MAX_SAFE_INTEGER;
378
+ return leftStart - rightStart || left.order - right.order;
379
+ });
380
+ return selected;
381
+ }
382
+
383
+ function scopeHasBinding(scope: BindingScope, binding: number): boolean {
384
+ let current: BindingScope | null = scope;
385
+ while (current) {
386
+ if ((current.bindings & binding) !== 0) return true;
387
+ current = current.parent;
388
+ }
389
+ return false;
390
+ }
391
+
392
+ function isSpecifierReferenceNode(node: StructuralAstNode): boolean {
393
+ switch (node.type) {
394
+ case "ImportDeclaration":
395
+ case "ExportNamedDeclaration":
396
+ case "ExportAllDeclaration":
397
+ case "ImportExpression":
398
+ case "TSImportEqualsDeclaration":
399
+ case "CallExpression":
400
+ return true;
401
+ default:
402
+ return false;
403
+ }
404
+ }
405
+
406
+ function isUncomputedMember(node: StructuralAstNode | null, objectName: string, propertyName: string): boolean {
407
+ if (node?.type !== "MemberExpression" || node.computed === true) return false;
408
+ return isIdentifier(asAstNode(node.object), objectName) && isIdentifier(asAstNode(node.property), propertyName);
409
+ }
410
+
411
+ function isUnshadowedExportsTarget(node: StructuralAstNode | null, scope: BindingScope): boolean {
412
+ return (
413
+ (isIdentifier(node, "exports") && !scopeHasBinding(scope, EXPORTS_BINDING)) ||
414
+ (isUncomputedMember(node, "module", "exports") && !scopeHasBinding(scope, MODULE_BINDING))
415
+ );
416
+ }
417
+
418
+ function isGlobalRequireCall(node: StructuralAstNode | null, scope: BindingScope): boolean {
419
+ return (
420
+ node?.type === "CallExpression" &&
421
+ isIdentifier(asAstNode(node.callee), "require") &&
422
+ !scopeHasBinding(scope, REQUIRE_BINDING)
423
+ );
424
+ }
425
+
426
+ /**
427
+ * Whether `node` is a `createRequire(...)` factory call imported from
428
+ * `node:module` (or its `module` alias).
429
+ */
430
+ function isCreateRequireInvocation(
431
+ node: StructuralAstNode | null,
432
+ createRequireBindings: ReadonlySet<string>,
433
+ moduleNamespaceBindings: ReadonlySet<string>,
434
+ ): boolean {
435
+ if (node?.type !== "CallExpression") return false;
436
+ const callee = asAstNode(node.callee);
437
+ if (callee?.type === "Identifier" && typeof callee.name === "string") {
438
+ return createRequireBindings.has(callee.name);
439
+ }
440
+ if (callee?.type !== "MemberExpression" || staticMemberPropertyName(callee) !== "createRequire") return false;
441
+ const object = asAstNode(callee.object);
442
+ return object?.type === "Identifier" && typeof object.name === "string" && moduleNamespaceBindings.has(object.name);
443
+ }
444
+
445
+ function staticMemberPropertyName(node: StructuralAstNode): string | null {
446
+ const property = asAstNode(node.property);
447
+ if (node.computed !== true && property?.type === "Identifier" && typeof property.name === "string") {
448
+ return property.name;
449
+ }
450
+ if (node.computed === true && property?.type === "StringLiteral" && typeof property.value === "string") {
451
+ return property.value;
452
+ }
453
+ return null;
454
+ }
455
+
456
+ function staticObjectPropertyName(node: StructuralAstNode): string | null {
457
+ if (node.computed === true) return null;
458
+ const key = asAstNode(node.key);
459
+ if (key?.type === "Identifier" && typeof key.name === "string") return key.name;
460
+ return key?.type === "StringLiteral" && typeof key.value === "string" ? key.value : null;
461
+ }
462
+
463
+ function collectExtensionSpecifierReferences(
464
+ source: string,
465
+ importerPath: string,
466
+ ast: ParseResult = parseExtensionSource(source, importerPath),
467
+ ): ExtensionSpecifierReference[] {
468
+ const references: ExtensionSpecifierReference[] = [];
469
+ const record = (kind: ExtensionSpecifierReference["kind"], literal: unknown): void => {
470
+ const node = asAstNode(literal);
471
+ if (
472
+ node?.type === "StringLiteral" &&
473
+ typeof node.value === "string" &&
474
+ typeof node.start === "number" &&
475
+ typeof node.end === "number"
476
+ ) {
477
+ references.push({ kind, specifier: node.value, start: node.start, end: node.end });
478
+ }
479
+ };
480
+ const createRequireBindings = new Set<string>();
481
+ const moduleNamespaceBindings = new Set<string>();
482
+ for (const { node } of collectScopedAstNodes(ast, candidate => candidate.type === "ImportDeclaration")) {
483
+ const source = asAstNode(node.source);
484
+ if (source?.type !== "StringLiteral" || (source.value !== "node:module" && source.value !== "module")) continue;
485
+ for (const value of Array.isArray(node.specifiers) ? node.specifiers : []) {
486
+ const specifier = asAstNode(value);
487
+ const local = asAstNode(specifier?.local);
488
+ if (local?.type !== "Identifier" || typeof local.name !== "string") continue;
489
+ if (specifier?.type === "ImportNamespaceSpecifier") {
490
+ moduleNamespaceBindings.add(local.name);
491
+ } else if (specifier?.type === "ImportSpecifier") {
492
+ const imported = asAstNode(specifier.imported);
493
+ if (
494
+ (imported?.type === "Identifier" && imported.name === "createRequire") ||
495
+ (imported?.type === "StringLiteral" && imported.value === "createRequire")
496
+ ) {
497
+ createRequireBindings.add(local.name);
498
+ }
499
+ }
500
+ }
501
+ }
502
+ for (const { node, scope } of collectScopedAstNodes(ast, isSpecifierReferenceNode)) {
503
+ if (
504
+ node.type === "ImportDeclaration" ||
505
+ node.type === "ExportNamedDeclaration" ||
506
+ node.type === "ExportAllDeclaration"
507
+ ) {
508
+ record("import", node.source);
509
+ } else if (node.type === "ImportExpression") {
510
+ record("import", node.source);
511
+ } else if (node.type === "TSImportEqualsDeclaration") {
512
+ const moduleReference = asAstNode(node.moduleReference);
513
+ if (moduleReference?.type === "TSExternalModuleReference") {
514
+ record("require", moduleReference.expression);
515
+ }
516
+ } else if (node.type === "CallExpression") {
517
+ const callee = asAstNode(node.callee);
518
+ if (callee?.type === "Import") {
519
+ record("import", nodeArgument(node, 0));
520
+ } else if (isIdentifier(callee, "require") && !scopeHasBinding(scope, REQUIRE_BINDING)) {
521
+ record("require", nodeArgument(node, 0));
522
+ } else if (isCreateRequireInvocation(callee, createRequireBindings, moduleNamespaceBindings)) {
523
+ // `createRequire(base)(spec)` — pin the invoked bare dependency so it
524
+ // loads without a runtime `node_modules` lookup. Relative specifiers
525
+ // resolve against `base`, which is not rewritten, so restrict to bare.
526
+ const argument = nodeArgument(node, 0);
527
+ if (
528
+ argument?.type === "StringLiteral" &&
529
+ typeof argument.value === "string" &&
530
+ isBareExtensionDependencySpecifier(argument.value)
531
+ ) {
532
+ record("require", argument);
533
+ }
534
+ }
535
+ }
536
+ }
537
+ return references;
538
+ }
539
+
540
+ function applySpecifierReplacements(
541
+ source: string,
542
+ replacements: ReadonlyArray<ExtensionSpecifierReference & { readonly replacement: string }>,
543
+ ): string {
544
+ let rewritten = source;
545
+ for (const reference of [...replacements].sort((left, right) => right.start - left.start)) {
546
+ rewritten = `${rewritten.slice(0, reference.start)}${JSON.stringify(reference.replacement)}${rewritten.slice(reference.end)}`;
547
+ }
548
+ return rewritten;
549
+ }
550
+
551
+ const loadedBundledModules: Record<string, BundledModule> = {};
552
+ let bundledModuleLoadersPromise: Promise<BundledModuleLoaders> | null = null;
553
+
554
+ /**
555
+ * Load the build-supplied module registry without evaluating its host modules.
556
+ *
557
+ * `globalThis` bridges the synthetic ES modules, which cannot close over this
558
+ * file's lexical scope. Dev/test runs never execute the conditional import;
559
+ * binary builds resolve it through the in-memory build plugin.
560
+ */
561
+ function ensureBundledModuleLoadersLoaded(): Promise<BundledModuleLoaders> {
562
+ if (!IS_COMPILED_BINARY) {
563
+ return Promise.reject(new Error("omp:legacy-pi-shim: bundled modules are only available in compiled mode"));
564
+ }
565
+ if (!bundledModuleLoadersPromise) {
566
+ bundledModuleLoadersPromise = import("omp-legacy-pi-modules").then(module => {
567
+ Reflect.set(globalThis, BUNDLED_MODULES_GLOBAL, loadedBundledModules);
568
+ return module.BUNDLED_PI_MODULE_LOADERS;
569
+ });
570
+ }
571
+ return bundledModuleLoadersPromise;
572
+ }
573
+
574
+ async function loadBundledModule(moduleKey: string): Promise<void> {
575
+ const loaders = await ensureBundledModuleLoadersLoaded();
576
+ const loader = loaders[moduleKey];
577
+ if (!loader) {
578
+ throw new Error(`omp:legacy-pi-shim: no bundled module registered for ${moduleKey}`);
579
+ }
580
+ loadedBundledModules[moduleKey] = await loader();
581
+ }
582
+
583
+ function bundledModuleVirtualSpecifier(moduleKey: string): string {
584
+ return `${BUNDLED_VIRTUAL_SCHEME}${moduleKey}`;
585
+ }
586
+
587
+ function isBundledVirtualSpecifier(value: string): boolean {
588
+ return value.startsWith(BUNDLED_VIRTUAL_SCHEME);
589
+ }
590
+
591
+ function toLegacyPiResolveResult(resolvedPath: string): LegacyPiResolveResult {
592
+ if (isBundledVirtualSpecifier(resolvedPath)) {
593
+ const registryKey = resolvedPath.slice(BUNDLED_VIRTUAL_SCHEME.length);
594
+ return { path: registryKey, namespace: BUNDLED_VIRTUAL_NAMESPACE };
595
+ }
596
+ return { path: resolvedPath };
597
+ }
598
+
599
+ /** Maps a bundled virtual specifier or registry key to Bun's plugin namespace shape. */
600
+ export function resolveBundledVirtualSpecifier(specifier: string): BundledVirtualResolveResult {
601
+ const registryKey = isBundledVirtualSpecifier(specifier)
602
+ ? specifier.slice(BUNDLED_VIRTUAL_SCHEME.length)
603
+ : specifier;
604
+ if (!registryKey) {
605
+ throw new Error("omp:legacy-pi-shim: bundled virtual specifier has no registry key");
606
+ }
607
+ return { path: registryKey, namespace: BUNDLED_VIRTUAL_NAMESPACE };
608
+ }
609
+
610
+ /**
611
+ * Build a synthetic ES module for one live bundled namespace. Every export
612
+ * reads through the global bridge; no bunfs path or copied package is involved.
613
+ */
614
+ function synthesizeBundledModuleSourceFromModules(moduleKey: string, modules: BundledModules): string {
615
+ const mod = modules[moduleKey];
616
+ if (!mod) {
617
+ throw new Error(`omp:legacy-pi-shim: no bundled module registered for ${moduleKey}`);
618
+ }
619
+ const lines: string[] = [
620
+ `const __omp_bundled = globalThis[${JSON.stringify(BUNDLED_MODULES_GLOBAL)}][${JSON.stringify(moduleKey)}];`,
621
+ ];
622
+ let hasDefault = false;
623
+ for (const exportName in mod) {
624
+ if (exportName === "default") {
625
+ hasDefault = true;
626
+ continue;
627
+ }
628
+ lines.push(`export const ${exportName} = __omp_bundled[${JSON.stringify(exportName)}];`);
629
+ }
630
+ if (hasDefault) {
631
+ lines.push("export default __omp_bundled.default;");
632
+ }
633
+ lines.push("");
634
+ return lines.join("\n");
635
+ }
636
+
637
+ /**
638
+ * Build the synthetic source served for one
639
+ * `omp-legacy-pi-bundled:<key>` import.
640
+ */
641
+ async function synthesizeBundledModuleSource(moduleKey: string): Promise<string> {
642
+ await loadBundledModule(moduleKey);
643
+ return synthesizeBundledModuleSourceFromModules(moduleKey, loadedBundledModules);
644
+ }
645
+
646
+ /** Test seam for the virtual module's named/default export forwarding. */
647
+ export function __synthesizeLegacyPiBundledSourceWithModules(
648
+ moduleKey: string,
649
+ modules: Readonly<Record<string, Readonly<Record<string, unknown>>>>,
650
+ ): string {
651
+ return synthesizeBundledModuleSourceFromModules(moduleKey, modules);
652
+ }
653
+
654
+ /** Test seam for the global bridge key shared with synthetic module source. */
655
+ export function __getLegacyPiBundledModulesGlobal(): string {
656
+ return BUNDLED_MODULES_GLOBAL;
657
+ }
658
+
659
+ // Canonical scope for in-process pi packages. Plugins published against any of
660
+ // the aliased scopes below (mariozechner's original publish, earendil-works'
661
+ // fork, or the canonical @oh-my-pi scope itself) are remapped to this scope and
662
+ // resolved against the bundled copy that ships inside the omp binary. This
663
+ // keeps plugins running against the exact runtime state of the host (single
664
+ // module registry, single tool registry, etc.) regardless of which historical
665
+ // scope name they happened to declare in their peerDependencies.
666
+ const CANONICAL_PI_SCOPE = "@oh-my-pi";
667
+
668
+ // Scopes that have historically been used to publish (or alias) the same set
669
+ // of internal pi-* packages. `@oh-my-pi` is intentionally included so direct
670
+ // canonical imports still pass through the same host-bundled package resolution
671
+ // path instead of pulling a duplicate copy from plugin node_modules.
672
+ const PI_SCOPE_ALIASES = ["oh-my-pi", "mariozechner", "earendil-works"] as const;
673
+
674
+ // Internal pi-* package basenames bundled inside the omp binary.
675
+ const PI_PACKAGE_NAMES = ["pi-agent-core", "pi-ai", "pi-coding-agent", "pi-natives", "pi-tui", "pi-utils"] as const;
676
+
677
+ const PI_SCOPE_ALTERNATION = PI_SCOPE_ALIASES.join("|");
678
+ const PI_PACKAGE_ALTERNATION = PI_PACKAGE_NAMES.join("|");
679
+
680
+ // Upstream `@mariozechner/*` packages exposed a few subpaths at the package
681
+ // root that we relocated under a different folder. Each entry rewrites
682
+ // `<pkg>/<from>` → `<pkg>/<to>` after the scope has been canonicalised, so
683
+ // plugins importing the upstream layout still resolve to a real file in our
684
+ // bundled copy. Entries ending in `/` rewrite the whole subtree; add new
685
+ // `pkg/from -> pkg/to` pairs whenever an upstream-only subpath breaks resolution.
686
+ const PI_SUBPATH_REMAPS: ReadonlyMap<string, string> = new Map<string, string>([
687
+ ["pi-ai/utils/oauth", "pi-ai/oauth"],
688
+ ["pi-ai/utils/oauth/", "pi-ai/oauth/"],
689
+ ["pi-ai/compat", "pi-ai"],
690
+ ]);
691
+
692
+ function remapLegacyPiSubpath(rest: string): string {
693
+ const exact = PI_SUBPATH_REMAPS.get(rest);
694
+ if (exact) {
695
+ return exact;
696
+ }
697
+
698
+ for (const [from, to] of PI_SUBPATH_REMAPS) {
699
+ if (from.endsWith("/") && rest.startsWith(from)) {
700
+ return `${to}${rest.slice(from.length)}`;
701
+ }
702
+ }
703
+
704
+ return rest;
705
+ }
706
+
707
+ const LEGACY_PI_SPECIFIER_FILTER = new RegExp(`^@(?:${PI_SCOPE_ALTERNATION})/(?:${PI_PACKAGE_ALTERNATION})(?:/.*)?$`);
708
+ const resolvedSpecifierFallbacks = new Map<string, string>();
709
+ const SOURCE_MODULE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"] as const;
710
+ const SUPPORTED_PACKAGE_IMPORT_CONDITIONS = new Set(["bun", "node", "import", "default"]);
711
+ const SUPPORTED_PACKAGE_REQUIRE_CONDITIONS = new Set(["bun", "node", "require", "default"]);
712
+ const packageRootCache = new Map<string, string | null>();
713
+ const packageImportsCache = new Map<string, Record<string, unknown> | null>();
714
+ const nodePackageRootCache = new Map<string, Promise<string | null>>();
715
+ const packageManifestCache = new Map<string, Promise<Record<string, unknown> | null>>();
716
+ const bareDependencyResolutionCache = new Map<string, Promise<string | null>>();
717
+ const bareRequireResolutionCache = new Map<string, Promise<string | null>>();
718
+ const realpathCache = new Map<string, Promise<string>>();
719
+ const nativeAddonResolutionCache = new Map<string, Promise<string | null>>();
720
+ const nativeAddonRequireScanCache = new Map<string, Promise<boolean>>();
721
+
722
+ function clearLegacyPiResolutionCaches(): void {
723
+ resolvedSpecifierFallbacks.clear();
724
+ packageRootCache.clear();
725
+ packageImportsCache.clear();
726
+ nodePackageRootCache.clear();
727
+ packageManifestCache.clear();
728
+ bareDependencyResolutionCache.clear();
729
+ bareRequireResolutionCache.clear();
730
+ nativeAddonResolutionCache.clear();
731
+ nativeAddonRequireScanCache.clear();
732
+ realpathCache.clear();
733
+ }
734
+
735
+ registerPluginCacheInvalidator(clearLegacyPiResolutionCaches);
736
+ const PACKAGE_IMPORT_EXCLUDED = Symbol("packageImportExcluded");
737
+
738
+ // Extensions importing TypeBox directly are redirected to omptype's TypeBox
739
+ // facade, keeping legacy builders while producing callable omptype schemas at
740
+ // the tool wire boundary. Submodules such as `@sinclair/typebox/compiler` are
741
+ // intentionally not remapped: plugins relying on those TypeBox-only APIs must
742
+ // vendor TypeBox directly.
743
+ const TYPEBOX_SPECIFIER_FILTER = /^(?:@sinclair\/typebox|typebox)$/;
744
+
745
+ // Compat-shim path resolution. In compiled-binary mode every bundled surface
746
+ // is served through the `omp-legacy-pi-bundled:` virtual namespace (see the
747
+ // bundled-module block above) — bunfs paths are unreachable on Bun 1.3.14+, so the
748
+ // pre-#3423 helpers that derived `/$bunfs/root/...` paths from
749
+ // `import.meta.dir` are gone. Dev / source-link / installed-package modes
750
+ // still need a real filesystem path for the source shims, which
751
+ // `sourceShimPath` computes either from the npm prebuilt `dist/cli.js`
752
+ // bundle (`PI_BUNDLED=true`) or directly from the monorepo source tree.
753
+
754
+ /**
755
+ * Compute the package root for the npm prebuilt `dist/cli.js` bundle.
756
+ *
757
+ * `bundle-dist.ts` defines `process.env.PI_BUNDLED="true"`; after bundling,
758
+ * `import.meta.dir` points at `<package>/dist`. Do not resolve the package via
759
+ * bare `@oh-my-pi/pi-coding-agent` here: from a global install Bun can pick an
760
+ * older cache entry, recreating mixed-runtime plugin loading.
761
+ */
762
+ export function __computeBundledSelfPackageRoot(metaDir: string, pathImpl: typeof path = path): string {
763
+ const normalizedMetaDir = pathImpl.normalize(metaDir);
764
+ if (pathImpl.basename(normalizedMetaDir) === "dist") {
765
+ return pathImpl.resolve(metaDir, "..");
766
+ }
767
+
768
+ const pluginsDirSuffix = pathImpl.join("src", "extensibility", "plugins");
769
+ if (normalizedMetaDir.endsWith(pluginsDirSuffix)) {
770
+ return pathImpl.resolve(metaDir, "..", "..", "..");
771
+ }
772
+
773
+ return pathImpl.resolve(metaDir);
774
+ }
775
+
776
+ function resolveBundledSelfPackageRoot(): string | undefined {
777
+ if (!process.env.PI_BUNDLED) return undefined;
778
+ return __computeBundledSelfPackageRoot(import.meta.dir);
779
+ }
780
+
781
+ const BUNDLED_SELF_PACKAGE_ROOT = resolveBundledSelfPackageRoot();
782
+
783
+ function sourceShimPath(file: string): string {
784
+ return BUNDLED_SELF_PACKAGE_ROOT
785
+ ? path.join(BUNDLED_SELF_PACKAGE_ROOT, "src", "extensibility", file)
786
+ : path.resolve(import.meta.dir, "..", file);
787
+ }
788
+
789
+ /**
790
+ * Resolve the coding-agent compatibility surface that composes omptype's
791
+ * TypeBox facade with legacy `Type.Unsafe`, then drop the remap when that
792
+ * entrypoint is missing.
793
+ *
794
+ * In compiled-binary mode the surface is served through the
795
+ * `omp-legacy-pi-bundled:` virtual namespace (issue #3423). Dev, source-link,
796
+ * and installed-package modes use the shipped source module.
797
+ *
798
+ * Exported for tests; production callers use `TYPEBOX_SHIM_PATH`.
799
+ */
800
+ export function __resolveTypeBoxShimPath(
801
+ isCompiled: boolean,
802
+ sourcePath: string,
803
+ pathExistsSync: (p: string) => boolean = fs.existsSync,
804
+ ): string | null {
805
+ if (isCompiled) {
806
+ return bundledModuleVirtualSpecifier(TYPEBOX_BUNDLED_MODULE_KEY);
807
+ }
808
+ return pathExistsSync(sourcePath) ? sourcePath : null;
809
+ }
810
+
811
+ const TYPEBOX_SHIM_PATH = __resolveTypeBoxShimPath(IS_COMPILED_BINARY, sourceShimPath("legacy-typebox.ts"));
812
+
813
+ // Legacy extensions historically imported `Type` (and `Static`/`TSchema`) from
814
+ // the package root of `@(scope)/pi-ai`. pi-ai 15.1.0 removed the runtime `Type`
815
+ // export (see `packages/ai/CHANGELOG.md`), so the bare canonical specifier no
816
+ // longer satisfies those imports. The override below redirects only the bare
817
+ // pi-ai package root onto a sibling shim that re-exports the canonical surface
818
+ // plus the borrowed `Type` runtime from the omptype TypeBox facade. Subpath
819
+ // imports such as `@oh-my-pi/pi-ai/oauth` continue to resolve directly
820
+ // against the bundled pi-ai package.
821
+ const LEGACY_PI_AI_SHIM_PATH = IS_COMPILED_BINARY
822
+ ? bundledModuleVirtualSpecifier(`${CANONICAL_PI_SCOPE}/pi-ai`)
823
+ : sourceShimPath("legacy-pi-ai-shim.ts");
824
+
825
+ // The coding-agent's own `./src/index.ts` cannot be listed as an extra
826
+ // `bun --compile` entrypoint alongside the CLI entry without breaking binary
827
+ // startup (issue #1474 follow-up). In compiled-binary mode the legacy
828
+ // `@(scope)/pi-coding-agent` root therefore resolves through the bundled
829
+ // module shim; in dev / source-link / installed-package mode it points at the
830
+ // sibling source shim whose distinct file path avoids the #1474 collision
831
+ // while still re-exporting the canonical package surface.
832
+ const LEGACY_PI_CODING_AGENT_SHIM_PATH = IS_COMPILED_BINARY
833
+ ? bundledModuleVirtualSpecifier(`${CANONICAL_PI_SCOPE}/pi-coding-agent`)
834
+ : sourceShimPath("legacy-pi-coding-agent-shim.ts");
835
+
836
+ // Legacy pi-tui exported `decodeKittyPrintable` from its package root. The
837
+ // canonical TUI replaced it with the broader `decodePrintableKey`; route only
838
+ // legacy root imports through a sibling shim that preserves the old name.
839
+ const LEGACY_PI_TUI_SHIM_PATH = IS_COMPILED_BINARY
840
+ ? bundledModuleVirtualSpecifier(`${CANONICAL_PI_SCOPE}/pi-tui`)
841
+ : sourceShimPath("legacy-pi-tui-shim.ts");
842
+
843
+ // Package-root overrides. Shim entries (`pi-ai`, `pi-coding-agent`, `pi-tui`)
844
+ // always replace the canonical surface so legacy helpers stay reachable. The
845
+ // other bundled host packages (`pi-agent-core`, `pi-natives`, `pi-utils`) are
846
+ // added only in compiled-binary mode to route extensions onto the in-process
847
+ // module instance — in dev / source-link / installed-package mode the canonical
848
+ // specifier resolves cleanly through `Bun.resolveSync` and hardcoding a
849
+ // source-tree path would miss installs where bundled packages live at
850
+ // `node_modules/@oh-my-pi/pi-*`.
851
+ //
852
+ // Compiled-binary entries are `omp-legacy-pi-bundled:<key>` specifiers handed
853
+ // to the synthetic onLoad in `installLegacyPiSpecifierShim()` — bunfs paths
854
+ // are unusable on Bun 1.3.14+ (issue #3423). Filesystem-shaped overrides are
855
+ // still validated against on-disk presence so a missing dev-mode shim falls
856
+ // through to `getResolvedSpecifier`.
857
+
858
+ /**
859
+ * Drop overrides whose filesystem targets are missing so they can fall
860
+ * through to the canonical-resolution path. Virtual `omp-legacy-pi-bundled:`
861
+ * entries always pass — live bundled module references are the source of truth
862
+ * in compiled mode where bunfs paths are unreachable (issue #3423).
863
+ *
864
+ * `pathExistsSync` defaults to `fs.existsSync`; tests inject a stub to
865
+ * simulate the missing-entrypoint failure mode without touching the real FS.
866
+ */
867
+ export function __validateLegacyPiPackageRootOverrides(
868
+ candidates: Record<string, string>,
869
+ pathExistsSync: (p: string) => boolean = fs.existsSync,
870
+ ): Record<string, string> {
871
+ const valid: Record<string, string> = {};
872
+ for (const key in candidates) {
873
+ const candidate = candidates[key];
874
+ if (candidate && (isBundledVirtualSpecifier(candidate) || pathExistsSync(candidate))) {
875
+ valid[key] = candidate;
876
+ }
877
+ }
878
+ return valid;
879
+ }
880
+
881
+ /**
882
+ * Compute the override map keyed by every canonical specifier the host serves
883
+ * directly: the pi-ai / pi-coding-agent roots (compat shims that re-attach
884
+ * legacy helpers) plus, in compiled mode, every build-supplied module key.
885
+ * Subpath coverage stops `@(scope)/pi-ai/oauth` and friends from falling
886
+ * through to the extension's absent peer install when bunfs walks fail.
887
+ */
888
+ export function __buildLegacyPiPackageRootOverrides(
889
+ isCompiled: boolean,
890
+ bundledModuleKeys: Iterable<string> = [],
891
+ ): Record<string, string> {
892
+ const candidates: Record<string, string> = {
893
+ [`${CANONICAL_PI_SCOPE}/pi-ai`]: LEGACY_PI_AI_SHIM_PATH,
894
+ [`${CANONICAL_PI_SCOPE}/pi-coding-agent`]: LEGACY_PI_CODING_AGENT_SHIM_PATH,
895
+ [`${CANONICAL_PI_SCOPE}/pi-tui`]: LEGACY_PI_TUI_SHIM_PATH,
896
+ };
897
+ if (isCompiled) {
898
+ for (const key of bundledModuleKeys) {
899
+ // Shim-bearing roots already map to their compat surfaces; TypeBox
900
+ // has a dedicated TYPEBOX_SHIM_PATH route.
901
+ if (key in candidates || key === TYPEBOX_BUNDLED_MODULE_KEY) continue;
902
+ candidates[key] = bundledModuleVirtualSpecifier(key);
903
+ }
904
+ }
905
+ return __validateLegacyPiPackageRootOverrides(candidates);
906
+ }
907
+
908
+ // Seeded with compat roots at module init; first compiled extension load adds
909
+ // every key supplied by the in-memory build module.
910
+ let legacyPiPackageRootOverrides = __buildLegacyPiPackageRootOverrides(IS_COMPILED_BINARY);
911
+ let legacyPiOverridesReadyPromise: Promise<void> | null = null;
912
+
913
+ /** Complete compiled-mode overrides from the lazy host-module registry. */
914
+ function ensureLegacyPiOverridesReady(): Promise<void> {
915
+ if (!IS_COMPILED_BINARY) {
916
+ return Promise.resolve();
917
+ }
918
+ if (!legacyPiOverridesReadyPromise) {
919
+ legacyPiOverridesReadyPromise = ensureBundledModuleLoadersLoaded().then(loaders => {
920
+ legacyPiPackageRootOverrides = __buildLegacyPiPackageRootOverrides(true, Object.keys(loaders));
921
+ });
922
+ }
923
+ return legacyPiOverridesReadyPromise;
924
+ }
925
+
926
+ let isLegacyPiSpecifierShimInstalled = false;
927
+
928
+ function remapLegacyPiSpecifier(specifier: string): string | null {
929
+ if (!LEGACY_PI_SPECIFIER_FILTER.test(specifier)) {
930
+ return null;
931
+ }
932
+ const slashIdx = specifier.indexOf("/", 1);
933
+ // Filter guarantees a slash exists, but guard anyway to keep the type narrow.
934
+ if (slashIdx === -1) {
935
+ return null;
936
+ }
937
+ const rest = specifier.slice(slashIdx + 1);
938
+ const remappedSubpath = remapLegacyPiSubpath(rest);
939
+ return `${CANONICAL_PI_SCOPE}/${remappedSubpath}`;
940
+ }
941
+
942
+ function getResolvedSpecifier(specifier: string): string {
943
+ const cached = resolvedSpecifierFallbacks.get(specifier);
944
+ if (cached) {
945
+ return cached;
946
+ }
947
+
948
+ const resolved = Bun.resolveSync(specifier, import.meta.dir);
949
+ resolvedSpecifierFallbacks.set(specifier, resolved);
950
+ return resolved;
951
+ }
952
+
953
+ /**
954
+ * Resolve a canonical `@oh-my-pi/*` specifier to a filesystem path, preferring
955
+ * a bundled compat shim when one is registered for the package root.
956
+ *
957
+ * Falls back to `getResolvedSpecifier` (which may throw under compiled binary
958
+ * mode); callers handle that the same way they would for non-overridden
959
+ * specifiers.
960
+ */
961
+ function resolveCanonicalPiSpecifier(remappedSpecifier: string): string {
962
+ const override = legacyPiPackageRootOverrides[remappedSpecifier];
963
+ if (override) {
964
+ return override;
965
+ }
966
+ return getResolvedSpecifier(remappedSpecifier);
967
+ }
968
+
969
+ function toImportSpecifier(resolvedPath: string): string {
970
+ // Virtual `omp-legacy-pi-bundled:` specifiers are served by the synthetic
971
+ // onLoad in `installLegacyPiSpecifierShim()`; wrapping them as `file://`
972
+ // would corrupt the scheme.
973
+ if (isBundledVirtualSpecifier(resolvedPath)) {
974
+ return resolvedPath;
975
+ }
976
+ return url.pathToFileURL(stripWindowsExtendedLengthPathPrefix(resolvedPath)).href;
977
+ }
978
+
979
+ /**
980
+ * Rewrite the extension-owned specifiers OMP must host-resolve — legacy
981
+ * `@(scope)/pi-*`, bare TypeBox packages, package `imports` aliases like
982
+ * `#src/*`, and extension-local bare dependencies — to absolute `file://` URLs
983
+ * or compiled-mode virtual specifiers. Relative siblings and built-in modules
984
+ * are left untouched so Bun resolves them from the extension's real on-disk
985
+ * location.
986
+ *
987
+ * When `mtimeTag` is provided, extension-owned relative graph specifiers
988
+ * (`./`/`../`) and, by default, resolved package `#alias/*` and extension-local
989
+ * bare deps also carry a `?mtime=<tag>` cache-bust so Bun rekeys them on
990
+ * same-process reloads. `resolvedImportMtimeTag` can disable the tag for
991
+ * resolved package and bare ESM imports inside third-party dependencies, whose
992
+ * transitive ESM imports retain a query-free importer path for Bun's runtime
993
+ * `node_modules` resolution. Host package rewrites (legacy
994
+ * `@(scope)/pi-*`, TypeBox shim) always emit `file://` URLs because they resolve
995
+ * to in-process host code that never changes between reloads.
996
+ */
997
+ async function rewriteLegacyExtensionSource(
998
+ source: string,
999
+ importerPath: string,
1000
+ mtimeTag: string | null = null,
1001
+ resolvedImportMtimeTag: string | null = mtimeTag,
1002
+ ): Promise<string> {
1003
+ // Compiled mode completes the override map from the build-supplied module
1004
+ // keys on first use; every rewrite path must see the full map.
1005
+ await ensureLegacyPiOverridesReady();
1006
+ const references = collectExtensionSpecifierReferences(source, importerPath);
1007
+ const replacements: Array<ExtensionSpecifierReference & { replacement: string }> = [];
1008
+ for (const reference of references) {
1009
+ if (reference.kind !== "import") continue;
1010
+
1011
+ const specifier = reference.specifier;
1012
+ let replacement: string | null = null;
1013
+ const remappedSpecifier = remapLegacyPiSpecifier(specifier);
1014
+ if (remappedSpecifier) {
1015
+ try {
1016
+ replacement = toImportSpecifier(resolveCanonicalPiSpecifier(remappedSpecifier));
1017
+ } catch {
1018
+ // Compiled fallback may be absent from a malformed build. Continue to
1019
+ // the extension's on-disk peer dependency resolution below.
1020
+ }
1021
+ }
1022
+ if (!replacement && TYPEBOX_SHIM_PATH && (specifier === "typebox" || specifier === "@sinclair/typebox")) {
1023
+ replacement = toImportSpecifier(TYPEBOX_SHIM_PATH);
1024
+ }
1025
+ if (!replacement && specifier.startsWith("#")) {
1026
+ const resolved = await resolvePackageImportSpecifier(specifier, importerPath);
1027
+ if (resolved) replacement = toGraphImportSpecifier(resolved, resolvedImportMtimeTag);
1028
+ }
1029
+ if (!replacement && isBareExtensionDependencySpecifier(specifier)) {
1030
+ const resolved = await resolveExtensionBareDependency(specifier, importerPath);
1031
+ if (resolved) replacement = toGraphImportSpecifier(resolved, resolvedImportMtimeTag);
1032
+ }
1033
+ if (!replacement && mtimeTag && /^\.\.?\//.test(specifier) && !specifier.includes("?")) {
1034
+ replacement = `${specifier}?mtime=${mtimeTag}`;
1035
+ }
1036
+ if (replacement && replacement !== specifier) {
1037
+ replacements.push({ ...reference, replacement });
1038
+ }
1039
+ }
1040
+ const withImports = applySpecifierReplacements(source, replacements);
1041
+ return rewriteExtensionSpecifiers(withImports, importerPath);
1042
+ }
1043
+
1044
+ /** Test seam for compiled-binary legacy extension source rewriting. */
1045
+ export async function __rewriteLegacyExtensionSourceForTests(
1046
+ source: string,
1047
+ importerPath: string,
1048
+ mtimeTag: string | null = null,
1049
+ resolvedImportMtimeTag: string | null = mtimeTag,
1050
+ ): Promise<string> {
1051
+ return rewriteLegacyExtensionSource(source, importerPath, mtimeTag, resolvedImportMtimeTag);
1052
+ }
1053
+
1054
+ /**
1055
+ * Build the import specifier for a graph-resolved absolute path. POSIX
1056
+ * emits a bare filesystem path with an optional `?mtime=<tag>` (Bun keys
1057
+ * query strings for bare-path specifiers), so same-process extension
1058
+ * reloads pick up edits to package-alias (`#foo/*`) and extension-local
1059
+ * bare deps. Windows and bundled virtual specifiers keep the current
1060
+ * `file://` / virtual form — Bun ignores queries on `file://` URLs, so
1061
+ * cache-bust does not reach Windows extensions until Bun changes that.
1062
+ */
1063
+ function toGraphImportSpecifier(resolvedPath: string, mtimeTag: string | null): string {
1064
+ if (isBundledVirtualSpecifier(resolvedPath)) {
1065
+ return resolvedPath;
1066
+ }
1067
+ if (process.platform === "win32" || !mtimeTag) {
1068
+ return url.pathToFileURL(stripWindowsExtendedLengthPathPrefix(resolvedPath)).href;
1069
+ }
1070
+ return `${stripWindowsExtendedLengthPathPrefix(resolvedPath)}?mtime=${mtimeTag}`;
1071
+ }
1072
+
1073
+ function isRecord(value: unknown): value is Record<string, unknown> {
1074
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1075
+ }
1076
+
1077
+ async function pathExists(p: string): Promise<boolean> {
1078
+ try {
1079
+ await fs.promises.stat(p);
1080
+ return true;
1081
+ } catch {
1082
+ return false;
1083
+ }
1084
+ }
1085
+
1086
+ function hasSourceModuleExtension(p: string): boolean {
1087
+ const ext = path.extname(p).toLowerCase();
1088
+ return (SOURCE_MODULE_EXTENSIONS as readonly string[]).includes(ext);
1089
+ }
1090
+
1091
+ async function resolveSourceModuleFile(basePath: string): Promise<string | null> {
1092
+ try {
1093
+ const stats = await fs.promises.stat(basePath);
1094
+ if (stats.isFile()) {
1095
+ // Non-source files (JSON, WASM, text assets, etc.) bypass the on-load
1096
+ // rewrite hook so Bun's native loaders handle them; our hook would
1097
+ // otherwise pass them through `getLoader()` which falls back to `js`.
1098
+ return hasSourceModuleExtension(basePath) ? realpathOrSelf(basePath) : null;
1099
+ }
1100
+ if (stats.isDirectory()) {
1101
+ for (const extension of SOURCE_MODULE_EXTENSIONS) {
1102
+ const resolved = await resolveSourceModuleFile(path.join(basePath, `index${extension}`));
1103
+ if (resolved) return resolved;
1104
+ }
1105
+ }
1106
+ } catch {
1107
+ // Fall through to extension candidates below.
1108
+ }
1109
+
1110
+ if (path.extname(basePath)) {
1111
+ return null;
1112
+ }
1113
+
1114
+ for (const extension of SOURCE_MODULE_EXTENSIONS) {
1115
+ const resolved = await resolveSourceModuleFile(`${basePath}${extension}`);
1116
+ if (resolved) return resolved;
1117
+ }
1118
+ return null;
1119
+ }
1120
+
1121
+ async function resolveRelativeCommonJsRequire(specifier: string, importerPath: string): Promise<string | null> {
1122
+ const candidate = path.resolve(path.dirname(importerPath), specifier);
1123
+ try {
1124
+ const stats = await fs.promises.stat(candidate);
1125
+ if (stats.isDirectory()) {
1126
+ const manifest = await readPackageManifest(candidate);
1127
+ if (typeof manifest?.main === "string") {
1128
+ const main = await resolveSourceModuleFile(path.resolve(candidate, manifest.main));
1129
+ if (main) return main;
1130
+ }
1131
+ }
1132
+ } catch {
1133
+ // Missing candidates fall through to extension and index resolution.
1134
+ }
1135
+ return resolveSourceModuleFile(candidate);
1136
+ }
1137
+
1138
+ function isPathInsideRoot(rootPath: string, candidatePath: string): boolean {
1139
+ const relative = path.relative(rootPath, candidatePath);
1140
+ return relative === "" || (relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative));
1141
+ }
1142
+
1143
+ async function resolvePackageSourceTarget(packageRoot: string, targetPath: string): Promise<string | null> {
1144
+ const candidate = path.resolve(targetPath);
1145
+ if (!isPathInsideRoot(path.resolve(packageRoot), candidate)) {
1146
+ return null;
1147
+ }
1148
+ const resolved = await resolveSourceModuleFile(candidate);
1149
+ if (!resolved) {
1150
+ return null;
1151
+ }
1152
+ const realPackageRoot = await realpathOrSelf(packageRoot);
1153
+ return isPathInsideRoot(realPackageRoot, resolved) ? resolved : null;
1154
+ }
1155
+
1156
+ async function resolvePackageFileTarget(packageRoot: string, targetPath: string): Promise<string | null> {
1157
+ const candidate = path.resolve(targetPath);
1158
+ if (!isPathInsideRoot(path.resolve(packageRoot), candidate) || !(await pathExists(candidate))) {
1159
+ return null;
1160
+ }
1161
+ const [realPackageRoot, resolved] = await Promise.all([realpathOrSelf(packageRoot), realpathOrSelf(candidate)]);
1162
+ return isPathInsideRoot(realPackageRoot, resolved) ? resolved : null;
1163
+ }
1164
+
1165
+ async function findPackageRoot(importerPath: string): Promise<string | null> {
1166
+ let dir = path.dirname(importerPath);
1167
+ while (true) {
1168
+ const cached = packageRootCache.get(dir);
1169
+ if (cached !== undefined) {
1170
+ return cached;
1171
+ }
1172
+
1173
+ if (await pathExists(path.join(dir, "package.json"))) {
1174
+ packageRootCache.set(path.dirname(importerPath), dir);
1175
+ return dir;
1176
+ }
1177
+
1178
+ const parent = path.dirname(dir);
1179
+ if (parent === dir) {
1180
+ packageRootCache.set(path.dirname(importerPath), null);
1181
+ return null;
1182
+ }
1183
+ dir = parent;
1184
+ }
1185
+ }
1186
+
1187
+ async function readPackageImports(packageRoot: string): Promise<Record<string, unknown> | null> {
1188
+ const cached = packageImportsCache.get(packageRoot);
1189
+ if (cached !== undefined) {
1190
+ return cached;
1191
+ }
1192
+
1193
+ let imports: Record<string, unknown> | null = null;
1194
+ try {
1195
+ const pkg = await Bun.file(path.join(packageRoot, "package.json")).json();
1196
+ if (isRecord(pkg) && isRecord(pkg.imports)) {
1197
+ imports = pkg.imports;
1198
+ }
1199
+ } catch {
1200
+ imports = null;
1201
+ }
1202
+ packageImportsCache.set(packageRoot, imports);
1203
+ return imports;
1204
+ }
1205
+
1206
+ type PackageImportTargetSelection = string | typeof PACKAGE_IMPORT_EXCLUDED | null;
1207
+ type ResolvedPackageImportTargetSelection = string | typeof PACKAGE_IMPORT_EXCLUDED;
1208
+
1209
+ function selectPackageImportTarget(
1210
+ entry: unknown,
1211
+ conditions: ReadonlySet<string> = SUPPORTED_PACKAGE_IMPORT_CONDITIONS,
1212
+ ): PackageImportTargetSelection {
1213
+ if (entry === null) {
1214
+ return PACKAGE_IMPORT_EXCLUDED;
1215
+ }
1216
+ if (typeof entry === "string") {
1217
+ return entry;
1218
+ }
1219
+ if (Array.isArray(entry)) {
1220
+ for (const item of entry) {
1221
+ const target = selectPackageImportTarget(item, conditions);
1222
+ if (target !== null) return target;
1223
+ }
1224
+ return null;
1225
+ }
1226
+ if (!isRecord(entry)) {
1227
+ return null;
1228
+ }
1229
+ for (const [condition, value] of Object.entries(entry)) {
1230
+ if (!conditions.has(condition)) {
1231
+ continue;
1232
+ }
1233
+ const target = selectPackageImportTarget(value, conditions);
1234
+ if (target !== null) return target;
1235
+ }
1236
+ return null;
1237
+ }
1238
+
1239
+ async function resolvePackageImportTarget(
1240
+ packageRoot: string,
1241
+ target: string,
1242
+ wildcard: string | null,
1243
+ ): Promise<string | null> {
1244
+ if (!target.startsWith("./")) {
1245
+ return null;
1246
+ }
1247
+ const substituted = wildcard === null ? target : target.replaceAll("*", wildcard);
1248
+ return resolvePackageSourceTarget(packageRoot, path.resolve(packageRoot, substituted));
1249
+ }
1250
+
1251
+ async function resolvePackageImportSpecifier(specifier: string, importerPath: string): Promise<string | null> {
1252
+ if (!specifier.startsWith("#")) {
1253
+ return null;
1254
+ }
1255
+
1256
+ const packageRoot = await findPackageRoot(importerPath);
1257
+ if (!packageRoot) {
1258
+ return null;
1259
+ }
1260
+
1261
+ const imports = await readPackageImports(packageRoot);
1262
+ if (!imports) {
1263
+ return null;
1264
+ }
1265
+
1266
+ const exactTarget = selectPackageImportTarget(imports[specifier]);
1267
+ if (exactTarget === PACKAGE_IMPORT_EXCLUDED) {
1268
+ return null;
1269
+ }
1270
+ if (exactTarget !== null) {
1271
+ return resolvePackageImportTarget(packageRoot, exactTarget, null);
1272
+ }
1273
+
1274
+ let bestMatch: { keyLength: number; target: ResolvedPackageImportTargetSelection; wildcard: string } | null = null;
1275
+ for (const [key, entry] of Object.entries(imports)) {
1276
+ const starIndex = key.indexOf("*");
1277
+ if (starIndex === -1) continue;
1278
+
1279
+ const prefix = key.slice(0, starIndex);
1280
+ const suffix = key.slice(starIndex + 1);
1281
+ if (!specifier.startsWith(prefix) || !specifier.endsWith(suffix)) {
1282
+ continue;
1283
+ }
1284
+
1285
+ const target = selectPackageImportTarget(entry);
1286
+ if (target === null) {
1287
+ continue;
1288
+ }
1289
+
1290
+ if (!bestMatch || key.length > bestMatch.keyLength) {
1291
+ bestMatch = {
1292
+ keyLength: key.length,
1293
+ target,
1294
+ wildcard: specifier.slice(prefix.length, specifier.length - suffix.length),
1295
+ };
1296
+ }
1297
+ }
1298
+
1299
+ if (!bestMatch || bestMatch.target === PACKAGE_IMPORT_EXCLUDED) {
1300
+ return null;
1301
+ }
1302
+ return resolvePackageImportTarget(packageRoot, bestMatch.target, bestMatch.wildcard);
1303
+ }
1304
+
1305
+ function isBareExtensionDependencySpecifier(specifier: string): boolean {
1306
+ if (
1307
+ specifier.startsWith(".") ||
1308
+ specifier.startsWith("/") ||
1309
+ specifier.startsWith("#") ||
1310
+ specifier.startsWith("node:") ||
1311
+ specifier.startsWith("bun:") ||
1312
+ /^[a-z][a-z0-9+.-]*:/i.test(specifier)
1313
+ ) {
1314
+ return false;
1315
+ }
1316
+ const packageName = specifier.startsWith("@") ? specifier.split("/").slice(0, 2).join("/") : specifier.split("/")[0];
1317
+ return Boolean(packageName && !isBuiltin(specifier));
1318
+ }
1319
+
1320
+ interface BarePackageSpecifier {
1321
+ readonly name: string;
1322
+ readonly subpath: string | null;
1323
+ }
1324
+
1325
+ function splitBarePackageSpecifier(specifier: string): BarePackageSpecifier | null {
1326
+ const parts = specifier.split("/");
1327
+ if (specifier.startsWith("@")) {
1328
+ const [scope, name, ...rest] = parts;
1329
+ if (!scope || !name) return null;
1330
+ return { name: `${scope}/${name}`, subpath: rest.length > 0 ? rest.join("/") : null };
1331
+ }
1332
+ const [name, ...rest] = parts;
1333
+ if (!name) return null;
1334
+ return { name, subpath: rest.length > 0 ? rest.join("/") : null };
1335
+ }
1336
+
1337
+ async function findNodePackageRoot(packageName: string, importerPath: string): Promise<string | null> {
1338
+ const cacheKey = `${packageName}\0${path.resolve(path.dirname(importerPath))}`;
1339
+ const cached = nodePackageRootCache.get(cacheKey);
1340
+ if (cached) return cached;
1341
+
1342
+ const promise = findNodePackageRootUncached(packageName, importerPath);
1343
+ nodePackageRootCache.set(cacheKey, promise);
1344
+ return promise;
1345
+ }
1346
+
1347
+ async function findNodePackageRootUncached(packageName: string, importerPath: string): Promise<string | null> {
1348
+ let dir = path.dirname(importerPath);
1349
+ while (true) {
1350
+ const candidate = path.join(dir, "node_modules", packageName);
1351
+ if (await pathExists(path.join(candidate, "package.json"))) {
1352
+ return candidate;
1353
+ }
1354
+ const parent = path.dirname(dir);
1355
+ if (parent === dir) {
1356
+ return null;
1357
+ }
1358
+ dir = parent;
1359
+ }
1360
+ }
1361
+
1362
+ async function readPackageManifest(packageRoot: string): Promise<Record<string, unknown> | null> {
1363
+ const cached = packageManifestCache.get(packageRoot);
1364
+ if (cached) return cached;
1365
+
1366
+ const promise = readPackageManifestUncached(packageRoot);
1367
+ packageManifestCache.set(packageRoot, promise);
1368
+ return promise;
1369
+ }
1370
+
1371
+ async function readPackageManifestUncached(packageRoot: string): Promise<Record<string, unknown> | null> {
1372
+ try {
1373
+ const manifest = await Bun.file(path.join(packageRoot, "package.json")).json();
1374
+ return isRecord(manifest) ? manifest : null;
1375
+ } catch {
1376
+ return null;
1377
+ }
1378
+ }
1379
+
1380
+ type ExtensionModuleKind = "commonjs" | "esm";
1381
+
1382
+ async function isCommonJsModulePath(
1383
+ modulePath: string,
1384
+ sourceType?: "script" | "module",
1385
+ inheritedKind?: ExtensionModuleKind,
1386
+ ): Promise<boolean> {
1387
+ const extension = path.extname(modulePath).toLowerCase();
1388
+ if (extension === ".cjs" || extension === ".cts") {
1389
+ return true;
1390
+ }
1391
+ if (extension !== ".js" && extension !== ".jsx") {
1392
+ return false;
1393
+ }
1394
+
1395
+ const packageRoot = await findPackageRoot(modulePath);
1396
+ const manifest = packageRoot ? await readPackageManifest(packageRoot) : null;
1397
+ if (manifest?.type === "module") {
1398
+ return false;
1399
+ }
1400
+ if (manifest?.type === "commonjs") {
1401
+ return true;
1402
+ }
1403
+ const parsedSourceType =
1404
+ sourceType ?? parseExtensionSource(await Bun.file(modulePath).text(), modulePath).program.sourceType;
1405
+ if (parsedSourceType === "module") {
1406
+ return false;
1407
+ }
1408
+ if (inheritedKind) {
1409
+ return inheritedKind === "commonjs";
1410
+ }
1411
+ const declaredModuleEntry =
1412
+ packageRoot && typeof manifest?.module === "string"
1413
+ ? await resolvePackageSourceTarget(packageRoot, path.resolve(packageRoot, manifest.module))
1414
+ : null;
1415
+ return !declaredModuleEntry || path.resolve(modulePath) !== path.resolve(declaredModuleEntry);
1416
+ }
1417
+
1418
+ async function isGraphOwnedCommonJsModule(
1419
+ modulePath: string,
1420
+ entryRealPath: string,
1421
+ sourceType?: "script" | "module",
1422
+ inheritedKind?: ExtensionModuleKind,
1423
+ ): Promise<boolean> {
1424
+ const extension = path.extname(modulePath).toLowerCase();
1425
+ if (modulePath === entryRealPath && extension !== ".cjs" && extension !== ".cts") {
1426
+ return false;
1427
+ }
1428
+ return isCommonJsModulePath(modulePath, sourceType, inheritedKind);
1429
+ }
1430
+
1431
+ async function resolvePackageExportTarget(
1432
+ packageRoot: string,
1433
+ target: string,
1434
+ wildcard: string | null,
1435
+ ): Promise<string | null> {
1436
+ if (!target.startsWith("./")) {
1437
+ return null;
1438
+ }
1439
+ const substituted = wildcard === null ? target : target.replaceAll("*", wildcard);
1440
+ return resolvePackageSourceTarget(packageRoot, path.resolve(packageRoot, substituted));
1441
+ }
1442
+
1443
+ async function resolveNodePackageExport(
1444
+ packageRoot: string,
1445
+ subpath: string | null,
1446
+ manifest: Record<string, unknown>,
1447
+ conditions: ReadonlySet<string> = SUPPORTED_PACKAGE_IMPORT_CONDITIONS,
1448
+ ): Promise<string | null> {
1449
+ const exportsField = manifest.exports;
1450
+ const rootTarget = subpath === null ? selectPackageImportTarget(exportsField, conditions) : null;
1451
+ if (rootTarget !== null && rootTarget !== PACKAGE_IMPORT_EXCLUDED) {
1452
+ return resolvePackageExportTarget(packageRoot, rootTarget, null);
1453
+ }
1454
+ if (!isRecord(exportsField)) {
1455
+ return null;
1456
+ }
1457
+
1458
+ const exactKey = subpath === null ? "." : `./${subpath}`;
1459
+ if (Object.hasOwn(exportsField, exactKey)) {
1460
+ const exactTarget = selectPackageImportTarget(exportsField[exactKey], conditions);
1461
+ return exactTarget !== null && exactTarget !== PACKAGE_IMPORT_EXCLUDED
1462
+ ? resolvePackageExportTarget(packageRoot, exactTarget, null)
1463
+ : null;
1464
+ }
1465
+
1466
+ let bestMatch: {
1467
+ keyLength: number;
1468
+ prefixLength: number;
1469
+ target: PackageImportTargetSelection;
1470
+ wildcard: string;
1471
+ } | null = null;
1472
+ for (const [key, entry] of Object.entries(exportsField)) {
1473
+ const starIndex = key.indexOf("*");
1474
+ if (starIndex === -1 || subpath === null || !key.startsWith("./")) continue;
1475
+ const prefix = key.slice(2, starIndex);
1476
+ const suffix = key.slice(starIndex + 1);
1477
+ if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix)) continue;
1478
+ if (
1479
+ !bestMatch ||
1480
+ prefix.length > bestMatch.prefixLength ||
1481
+ (prefix.length === bestMatch.prefixLength && key.length > bestMatch.keyLength)
1482
+ ) {
1483
+ bestMatch = {
1484
+ keyLength: key.length,
1485
+ prefixLength: prefix.length,
1486
+ target: selectPackageImportTarget(entry, conditions),
1487
+ wildcard: subpath.slice(prefix.length, subpath.length - suffix.length),
1488
+ };
1489
+ }
1490
+ }
1491
+ return bestMatch?.target && bestMatch.target !== PACKAGE_IMPORT_EXCLUDED
1492
+ ? resolvePackageExportTarget(packageRoot, bestMatch.target, bestMatch.wildcard)
1493
+ : null;
1494
+ }
1495
+
1496
+ async function resolveNodePackageFallback(
1497
+ packageRoot: string,
1498
+ subpath: string | null,
1499
+ manifest: Record<string, unknown>,
1500
+ ): Promise<string | null> {
1501
+ if (subpath) {
1502
+ return resolvePackageSourceTarget(packageRoot, path.join(packageRoot, subpath));
1503
+ }
1504
+ for (const field of ["module", "main"]) {
1505
+ const target = manifest[field];
1506
+ if (typeof target === "string") {
1507
+ const resolved = await resolvePackageSourceTarget(packageRoot, path.resolve(packageRoot, target));
1508
+ if (resolved) return resolved;
1509
+ }
1510
+ }
1511
+ return resolvePackageSourceTarget(packageRoot, path.join(packageRoot, "index"));
1512
+ }
1513
+
1514
+ async function resolveNodePackageDependency(specifier: string, importerPath: string): Promise<string | null> {
1515
+ const parsed = splitBarePackageSpecifier(specifier);
1516
+ if (!parsed) return null;
1517
+ const packageRoot = await findNodePackageRoot(parsed.name, importerPath);
1518
+ if (!packageRoot) return null;
1519
+ const manifest = await readPackageManifest(packageRoot);
1520
+ if (!manifest) return null;
1521
+ return Object.hasOwn(manifest, "exports")
1522
+ ? resolveNodePackageExport(packageRoot, parsed.subpath, manifest)
1523
+ : resolveNodePackageFallback(packageRoot, parsed.subpath, manifest);
1524
+ }
1525
+
1526
+ async function resolveNodePackageRequire(specifier: string, importerPath: string): Promise<string | null> {
1527
+ const parsed = splitBarePackageSpecifier(specifier);
1528
+ if (!parsed) return null;
1529
+ const packageRoot = await findNodePackageRoot(parsed.name, importerPath);
1530
+ if (!packageRoot) return null;
1531
+ const manifest = await readPackageManifest(packageRoot);
1532
+ if (!manifest) return null;
1533
+
1534
+ if (Object.hasOwn(manifest, "exports")) {
1535
+ return resolveNodePackageExport(packageRoot, parsed.subpath, manifest, SUPPORTED_PACKAGE_REQUIRE_CONDITIONS);
1536
+ }
1537
+ if (parsed.subpath) {
1538
+ return resolvePackageSourceTarget(packageRoot, path.join(packageRoot, parsed.subpath));
1539
+ }
1540
+ const main = manifest.main;
1541
+ return typeof main === "string"
1542
+ ? await resolvePackageSourceTarget(packageRoot, path.resolve(packageRoot, main))
1543
+ : await resolvePackageSourceTarget(packageRoot, path.join(packageRoot, "index"));
1544
+ }
1545
+
1546
+ async function validateResolvedBarePackagePath(
1547
+ specifier: string,
1548
+ importerPath: string,
1549
+ resolvedPath: string,
1550
+ ): Promise<string | null> {
1551
+ const parsed = splitBarePackageSpecifier(specifier);
1552
+ const packageRoot = parsed ? await findNodePackageRoot(parsed.name, importerPath) : null;
1553
+ return packageRoot ? resolvePackageFileTarget(packageRoot, resolvedPath) : null;
1554
+ }
1555
+
1556
+ async function isSelectedNoTypeEsmPackageBranch(
1557
+ specifier: string,
1558
+ importerPath: string,
1559
+ resolvedPath: string,
1560
+ ): Promise<boolean> {
1561
+ const parsed = splitBarePackageSpecifier(specifier);
1562
+ const packageRoot = parsed ? await findNodePackageRoot(parsed.name, importerPath) : null;
1563
+ const manifest = packageRoot ? await readPackageManifest(packageRoot) : null;
1564
+ if (!packageRoot || !manifest || manifest.type !== undefined) {
1565
+ return false;
1566
+ }
1567
+ if (parsed?.subpath === null && typeof manifest.module === "string") {
1568
+ const moduleEntry = await resolvePackageSourceTarget(packageRoot, path.resolve(packageRoot, manifest.module));
1569
+ if (moduleEntry && path.resolve(moduleEntry) === path.resolve(resolvedPath)) {
1570
+ return true;
1571
+ }
1572
+ }
1573
+ if (!Object.hasOwn(manifest, "exports")) {
1574
+ return false;
1575
+ }
1576
+ const importTarget = await resolveNodePackageExport(packageRoot, parsed?.subpath ?? null, manifest);
1577
+ const requireTarget = await resolveNodePackageExport(
1578
+ packageRoot,
1579
+ parsed?.subpath ?? null,
1580
+ manifest,
1581
+ SUPPORTED_PACKAGE_REQUIRE_CONDITIONS,
1582
+ );
1583
+ return Boolean(
1584
+ importTarget &&
1585
+ path.resolve(importTarget) === path.resolve(resolvedPath) &&
1586
+ (!requireTarget || path.resolve(requireTarget) !== path.resolve(importTarget)),
1587
+ );
1588
+ }
1589
+
1590
+ async function resolveExtensionBareDependency(specifier: string, importerPath: string): Promise<string | null> {
1591
+ if (!isBareExtensionDependencySpecifier(specifier)) {
1592
+ return null;
1593
+ }
1594
+
1595
+ const cacheKey = `${specifier}\0${path.resolve(path.dirname(importerPath))}`;
1596
+ const cached = bareDependencyResolutionCache.get(cacheKey);
1597
+ if (cached) return cached;
1598
+
1599
+ const promise = resolveExtensionBareDependencyUncached(specifier, importerPath);
1600
+ bareDependencyResolutionCache.set(cacheKey, promise);
1601
+ return promise;
1602
+ }
1603
+
1604
+ async function resolveExtensionBareDependencyUncached(specifier: string, importerPath: string): Promise<string | null> {
1605
+ // Resolve against the runtime package manifest first. Besides working in a
1606
+ // compiled binary, this preserves the package's ESM `import` condition when
1607
+ // the absolute target is later loaded outside normal package resolution.
1608
+ const packageResolved = await resolveNodePackageDependency(specifier, importerPath);
1609
+ if (packageResolved) {
1610
+ return packageResolved;
1611
+ }
1612
+ try {
1613
+ const resolved = Bun.resolveSync(specifier, path.dirname(importerPath));
1614
+ if (resolved && resolved !== specifier && !resolved.startsWith("node:") && !resolved.startsWith("bun:")) {
1615
+ return validateResolvedBarePackagePath(specifier, importerPath, resolved);
1616
+ }
1617
+ } catch {
1618
+ // Compiled binaries do not reliably resolve runtime extension node_modules.
1619
+ }
1620
+ return null;
1621
+ }
1622
+
1623
+ const NATIVE_ADDON_EXTENSION = ".node";
1624
+
1625
+ /**
1626
+ * Resolve a bare specifier whose target is a native `.node` addon — either a
1627
+ * package subpath ending in `.node`, or a package whose `main` points at an
1628
+ * addon (the napi-rs per-platform package convention, e.g.
1629
+ * `@yuuang/ffi-rs-darwin-arm64` → `ffi-rs.darwin-arm64.node`). Returns the
1630
+ * addon's absolute realpath, or null when the specifier is not a native addon.
1631
+ */
1632
+ async function resolveExtensionNativeAddon(specifier: string, importerPath: string): Promise<string | null> {
1633
+ if (!isBareExtensionDependencySpecifier(specifier)) {
1634
+ return null;
1635
+ }
1636
+
1637
+ const cacheKey = `${specifier}\0${path.resolve(path.dirname(importerPath))}`;
1638
+ const cached = nativeAddonResolutionCache.get(cacheKey);
1639
+ if (cached) return cached;
1640
+
1641
+ const promise = resolveExtensionNativeAddonUncached(specifier, importerPath);
1642
+ nativeAddonResolutionCache.set(cacheKey, promise);
1643
+ return promise;
1644
+ }
1645
+
1646
+ async function resolveExtensionNativeAddonUncached(specifier: string, importerPath: string): Promise<string | null> {
1647
+ const parsed = splitBarePackageSpecifier(specifier);
1648
+ if (!parsed) return null;
1649
+ const packageRoot = await findNodePackageRoot(parsed.name, importerPath);
1650
+ if (!packageRoot) return null;
1651
+
1652
+ let target: string | null = null;
1653
+ if (parsed.subpath !== null) {
1654
+ target = parsed.subpath.endsWith(NATIVE_ADDON_EXTENSION) ? path.join(packageRoot, parsed.subpath) : null;
1655
+ } else {
1656
+ const manifest = await readPackageManifest(packageRoot);
1657
+ const main = manifest?.main;
1658
+ target =
1659
+ typeof main === "string" && main.endsWith(NATIVE_ADDON_EXTENSION) ? path.resolve(packageRoot, main) : null;
1660
+ }
1661
+ if (!target) {
1662
+ return null;
1663
+ }
1664
+ return resolvePackageFileTarget(packageRoot, target);
1665
+ }
1666
+
1667
+ async function resolveExtensionBareRequire(specifier: string, importerPath: string): Promise<string | null> {
1668
+ if (!isBareExtensionDependencySpecifier(specifier)) {
1669
+ return null;
1670
+ }
1671
+
1672
+ const cacheKey = `${specifier}\0${path.resolve(path.dirname(importerPath))}`;
1673
+ const cached = bareRequireResolutionCache.get(cacheKey);
1674
+ if (cached) return cached;
1675
+
1676
+ const resolution = (async () => {
1677
+ const nativeAddon = await resolveExtensionNativeAddon(specifier, importerPath);
1678
+ if (nativeAddon) {
1679
+ return nativeAddon;
1680
+ }
1681
+ const packageResolved = await resolveNodePackageRequire(specifier, importerPath);
1682
+ if (packageResolved) {
1683
+ return realpathOrSelf(packageResolved);
1684
+ }
1685
+ try {
1686
+ const resolved = createRequire(importerPath).resolve(specifier);
1687
+ return resolved === specifier || resolved.startsWith("node:") || resolved.startsWith("bun:")
1688
+ ? null
1689
+ : await validateResolvedBarePackagePath(specifier, importerPath, resolved);
1690
+ } catch {
1691
+ return null;
1692
+ }
1693
+ })();
1694
+ bareRequireResolutionCache.set(cacheKey, resolution);
1695
+ return resolution;
1696
+ }
1697
+
1698
+ async function resolveExtensionCommonJsRequire(specifier: string, importerPath: string): Promise<string | null> {
1699
+ if (specifier.startsWith(".")) {
1700
+ return resolveRelativeCommonJsRequire(specifier, importerPath);
1701
+ }
1702
+ const remappedSpecifier = remapLegacyPiSpecifier(specifier);
1703
+ if (remappedSpecifier) {
1704
+ try {
1705
+ const resolved = resolveCanonicalPiSpecifier(remappedSpecifier);
1706
+ if (isBundledVirtualSpecifier(resolved)) {
1707
+ const moduleKey = resolved.slice(BUNDLED_VIRTUAL_SCHEME.length);
1708
+ if (!(moduleKey in loadedBundledModules)) {
1709
+ await loadBundledModule(moduleKey);
1710
+ }
1711
+ }
1712
+ return resolved;
1713
+ } catch {
1714
+ // A malformed compiled registry can still fall through to an
1715
+ // extension-installed legacy peer dependency.
1716
+ }
1717
+ }
1718
+ return resolveExtensionBareRequire(specifier, importerPath);
1719
+ }
1720
+
1721
+ /**
1722
+ * Rewrite CommonJS graph specifiers that cannot resolve from the bridge's
1723
+ * generated function: bare `require()` calls and, for graph-owned CommonJS
1724
+ * sources, import specifiers. Resolved targets are retained for synchronous
1725
+ * lazy hydration after load-time source caches clear.
1726
+ */
1727
+ async function rewriteExtensionSpecifiers(
1728
+ source: string,
1729
+ importerPath: string,
1730
+ rewriteImports = false,
1731
+ ): Promise<string> {
1732
+ const references = collectExtensionSpecifierReferences(source, importerPath);
1733
+ const resolvedSpecifierTargets = new Map<string, string>();
1734
+ const replacements: Array<ExtensionSpecifierReference & { replacement: string }> = [];
1735
+ for (const reference of references) {
1736
+ let resolved: string | null = null;
1737
+ if (reference.kind === "require") {
1738
+ resolved = await resolveExtensionCommonJsRequire(reference.specifier, importerPath);
1739
+ } else if (rewriteImports) {
1740
+ if (reference.specifier.startsWith(".")) {
1741
+ const candidate = Bun.resolveSync(reference.specifier, path.dirname(importerPath));
1742
+ resolved = hasSourceModuleExtension(candidate) ? await realpathOrSelf(candidate) : null;
1743
+ } else if (reference.specifier.startsWith("#")) {
1744
+ resolved = await resolvePackageImportSpecifier(reference.specifier, importerPath);
1745
+ } else {
1746
+ resolved = await resolveExtensionBareDependency(reference.specifier, importerPath);
1747
+ }
1748
+ }
1749
+ if (!resolved) continue;
1750
+ const replacement = stripWindowsExtendedLengthPathPrefix(resolved).replaceAll("\\", "/");
1751
+ resolvedSpecifierTargets.set(`${reference.kind}\0${reference.specifier}`, replacement);
1752
+ replacements.push({ ...reference, replacement });
1753
+ }
1754
+ extensionSynchronousSpecifierTargets.set(importerPath, resolvedSpecifierTargets);
1755
+ return applySpecifierReplacements(source, replacements);
1756
+ }
1757
+
1758
+ function rewriteExtensionSpecifiersFromCache(source: string, importerPath: string): string {
1759
+ const resolvedSpecifierTargets = extensionSynchronousSpecifierTargets.get(importerPath);
1760
+ if (!resolvedSpecifierTargets || resolvedSpecifierTargets.size === 0) {
1761
+ return source;
1762
+ }
1763
+ const replacements: Array<ExtensionSpecifierReference & { replacement: string }> = [];
1764
+ for (const reference of collectExtensionSpecifierReferences(source, importerPath)) {
1765
+ const replacement = resolvedSpecifierTargets.get(`${reference.kind}\0${reference.specifier}`);
1766
+ if (replacement) {
1767
+ replacements.push({ ...reference, replacement });
1768
+ }
1769
+ }
1770
+ return applySpecifierReplacements(source, replacements);
1771
+ }
1772
+
1773
+ /**
1774
+ * Whether a module's source contains a bare require that resolves to a native
1775
+ * `.node` addon — i.e. a napi-rs style loader that must be hooked into the
1776
+ * extension graph so {@link rewriteExtensionSpecifiers} can pin its
1777
+ * platform-package requires to absolute paths.
1778
+ */
1779
+ async function moduleRequiresNativeAddon(modulePath: string): Promise<boolean> {
1780
+ const cached = nativeAddonRequireScanCache.get(modulePath);
1781
+ if (cached) return cached;
1782
+
1783
+ const promise = moduleRequiresNativeAddonUncached(modulePath);
1784
+ nativeAddonRequireScanCache.set(modulePath, promise);
1785
+ return promise;
1786
+ }
1787
+
1788
+ async function moduleRequiresNativeAddonUncached(modulePath: string): Promise<boolean> {
1789
+ let source: string;
1790
+ try {
1791
+ source = await Bun.file(modulePath).text();
1792
+ } catch {
1793
+ return false;
1794
+ }
1795
+ for (const reference of collectExtensionSpecifierReferences(source, modulePath)) {
1796
+ if (reference.kind === "require" && (await resolveExtensionNativeAddon(reference.specifier, modulePath))) {
1797
+ return true;
1798
+ }
1799
+ }
1800
+ return false;
1801
+ }
1802
+
1803
+ function escapeRegExp(value: string): string {
1804
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1805
+ }
1806
+
1807
+ // Source modules in an extension graph are discovered from parsed static,
1808
+ // dynamic, re-export, and direct CommonJS require specifiers. Parsing keeps
1809
+ // import-looking text in strings, templates, regex literals, and comments out
1810
+ // of dependency resolution.
1811
+
1812
+ // Extension source realpaths already covered by an installed load-time hook for
1813
+ // each entry. `Bun.plugin()` registrations are process-global and permanent, so
1814
+ // reloads install supplemental hooks only for modules added to the graph since
1815
+ // the previous load.
1816
+ const extensionGraphHookModules = new Map<string, Set<string>>();
1817
+ const extensionGraphCacheBustResolvedImportModules = new Map<string, Set<string>>();
1818
+ const commonJsModuleSources = new Map<string, string>();
1819
+ const commonJsFallbackModulePaths = new Map<string, string>();
1820
+ const extensionSynchronousSpecifierTargets = new Map<string, Map<string, string>>();
1821
+ const synchronousModuleSources = new Map<string, string>();
1822
+ const commonJsGraphModulePaths = new Set<string>();
1823
+ const COMMONJS_REQUIRE_GLOBAL = "__ompLegacyPiRequireGraphModule";
1824
+ const commonJsModuleDefinitions = new Map<string, { source: string; filename: string; dirname: string }>();
1825
+ const commonJsModuleCache = new Map<
1826
+ string,
1827
+ {
1828
+ exports: unknown;
1829
+ filename: string;
1830
+ id: string;
1831
+ path: string;
1832
+ require: NodeJS.Require;
1833
+ loaded: boolean;
1834
+ }
1835
+ >();
1836
+ const commonJsTypeScriptTranspiler = new Bun.Transpiler({ loader: "ts" });
1837
+
1838
+ function evaluateGraphCommonJs(modulePath: string): unknown {
1839
+ const cached = commonJsModuleCache.get(modulePath);
1840
+ if (cached) {
1841
+ return cached.exports;
1842
+ }
1843
+ let definition = commonJsModuleDefinitions.get(modulePath);
1844
+ if (!definition && commonJsGraphModulePaths.has(modulePath)) {
1845
+ const targetPath = commonJsFallbackModulePaths.get(modulePath) ?? modulePath;
1846
+ const source = rewriteExtensionSpecifiersFromCache(fs.readFileSync(targetPath, "utf8"), modulePath);
1847
+ synthesizeCommonJsDefaultModule(modulePath, source, targetPath);
1848
+ definition = commonJsModuleDefinitions.get(modulePath);
1849
+ }
1850
+ if (!definition) {
1851
+ throw new Error(`Missing graph-owned CommonJS definition: ${modulePath}`);
1852
+ }
1853
+
1854
+ const nativeRequire = createRequire(definition.filename);
1855
+ const module = {
1856
+ exports: {},
1857
+ filename: definition.filename,
1858
+ id: definition.filename,
1859
+ path: definition.dirname,
1860
+ require: nativeRequire,
1861
+ loaded: false,
1862
+ };
1863
+ commonJsModuleCache.set(modulePath, module);
1864
+ const graphRequire: NodeJS.Require = Object.assign(
1865
+ (specifier: string) => {
1866
+ if (isBundledVirtualSpecifier(specifier)) {
1867
+ const moduleKey = specifier.slice(BUNDLED_VIRTUAL_SCHEME.length);
1868
+ const bundledModule = loadedBundledModules[moduleKey];
1869
+ if (!bundledModule) {
1870
+ throw new Error(`Missing bundled CommonJS host module: ${moduleKey}`);
1871
+ }
1872
+ return bundledModule;
1873
+ }
1874
+ const resolved = nativeRequire.resolve(specifier);
1875
+ let graphPath = resolved;
1876
+ try {
1877
+ graphPath = fs.realpathSync(resolved);
1878
+ } catch {
1879
+ // Builtins and virtual modules have no filesystem realpath.
1880
+ }
1881
+ return commonJsGraphModulePaths.has(graphPath) ? evaluateGraphCommonJs(graphPath) : nativeRequire(specifier);
1882
+ },
1883
+ {
1884
+ resolve: nativeRequire.resolve,
1885
+ cache: nativeRequire.cache,
1886
+ extensions: nativeRequire.extensions,
1887
+ main: nativeRequire.main,
1888
+ },
1889
+ );
1890
+ module.require = graphRequire;
1891
+ const execute = new Function("exports", "require", "module", "__filename", "__dirname", definition.source);
1892
+ try {
1893
+ execute.call(module.exports, module.exports, graphRequire, module, definition.filename, definition.dirname);
1894
+ module.loaded = true;
1895
+ return module.exports;
1896
+ } catch (error) {
1897
+ commonJsModuleCache.delete(modulePath);
1898
+ throw error;
1899
+ }
1900
+ }
1901
+
1902
+ /**
1903
+ * Register {@link evaluateGraphCommonJs} as the graph-owned CommonJS require
1904
+ * bridge on `globalThis`, first-wins.
1905
+ *
1906
+ * On source-link installs the `@(scope)/pi-coding-agent` root shim is served
1907
+ * from `src/`, so an extension import can evaluate a second instance of this
1908
+ * module with empty graph state. An unconditional set would let that empty
1909
+ * instance clobber the host bundle's populated bridge and break transitive
1910
+ * CommonJS resolution (#6449); guarding preserves the first (host-owned)
1911
+ * registration. Idempotent: a subsequent call with a value already present is a
1912
+ * no-op.
1913
+ */
1914
+ export function ensureGraphCommonJsRequireRegistered(): void {
1915
+ if (!Reflect.get(globalThis, COMMONJS_REQUIRE_GLOBAL)) {
1916
+ Reflect.set(globalThis, COMMONJS_REQUIRE_GLOBAL, evaluateGraphCommonJs);
1917
+ }
1918
+ }
1919
+
1920
+ ensureGraphCommonJsRequireRegistered();
1921
+
1922
+ let legacyPiLoadTag = 0;
1923
+
1924
+ function nextLegacyPiLoadTag(): string {
1925
+ legacyPiLoadTag = Math.max(legacyPiLoadTag + 1, Date.now());
1926
+ return String(legacyPiLoadTag);
1927
+ }
1928
+
1929
+ /** Resolve symlinks in a path, falling back to the input if realpath fails. */
1930
+ async function realpathOrSelf(p: string): Promise<string> {
1931
+ const cached = realpathCache.get(p);
1932
+ if (cached) return cached;
1933
+
1934
+ const promise = realpathOrSelfUncached(p);
1935
+ realpathCache.set(p, promise);
1936
+ return promise;
1937
+ }
1938
+
1939
+ async function realpathOrSelfUncached(p: string): Promise<string> {
1940
+ try {
1941
+ return await fs.promises.realpath(p);
1942
+ } catch {
1943
+ return p;
1944
+ }
1945
+ }
1946
+
1947
+ interface ExtensionModuleGraph {
1948
+ readonly modules: Map<string, string>;
1949
+ readonly cacheBustResolvedImportModules: Set<string>;
1950
+ readonly commonJsPaths: Set<string>;
1951
+ readonly synchronousSourcePaths: Set<string>;
1952
+ }
1953
+
1954
+ /**
1955
+ * Walk the extension's import graph starting at `entryRealPath`, returning the
1956
+ * realpath of every reachable source module OMP must rewrite at load time.
1957
+ * Relative imports, package `imports` aliases, and ESM bare dependencies are
1958
+ * graph-owned recursively because compiled Bun cannot resolve runtime
1959
+ * `node_modules` from those modules. Graph-owned CommonJS modules also own
1960
+ * their relative and bare CommonJS descendants, which are evaluated by the
1961
+ * synchronous bridge. Resolved ESM imports inside third-party dependencies
1962
+ * omit the reload tag so their importer paths stay query-free.
1963
+ */
1964
+ async function collectExtensionModules(entryRealPath: string): Promise<ExtensionModuleGraph> {
1965
+ const modules = new Map<string, string>();
1966
+ const commonJsPaths = new Set<string>();
1967
+ const synchronousSourcePaths = new Set<string>();
1968
+ const queuedCacheBustResolvedImports = new Map<string, boolean>([[entryRealPath, true]]);
1969
+ const queuedModuleKinds = new Map<string, ExtensionModuleKind>([[entryRealPath, "esm"]]);
1970
+ const queuedEsmBranchPaths = new Set<string>();
1971
+ const queue: Array<{
1972
+ file: string;
1973
+ cacheBustResolvedImports: boolean;
1974
+ moduleKind?: ExtensionModuleKind;
1975
+ esmBranch?: boolean;
1976
+ }> = [{ file: entryRealPath, cacheBustResolvedImports: true, moduleKind: "esm" }];
1977
+ while (queue.length > 0) {
1978
+ const item = queue.pop();
1979
+ if (!item) {
1980
+ continue;
1981
+ }
1982
+ const file = item.file;
1983
+ const cacheBustResolvedImports = queuedCacheBustResolvedImports.get(file) ?? item.cacheBustResolvedImports;
1984
+ const inheritedModuleKind = queuedModuleKinds.get(file) ?? item.moduleKind;
1985
+ const esmBranch = queuedEsmBranchPaths.has(file) || item.esmBranch === true;
1986
+ if (modules.has(file)) {
1987
+ continue;
1988
+ }
1989
+ let source: string;
1990
+ try {
1991
+ source = await Bun.file(file).text();
1992
+ } catch {
1993
+ continue;
1994
+ }
1995
+ modules.set(file, source);
1996
+ const ast = parseExtensionSource(source, file);
1997
+ const sourceIsCommonJs = await isGraphOwnedCommonJsModule(
1998
+ file,
1999
+ entryRealPath,
2000
+ ast.program.sourceType,
2001
+ inheritedModuleKind,
2002
+ );
2003
+ if (sourceIsCommonJs) {
2004
+ commonJsPaths.add(file);
2005
+ }
2006
+ const dir = path.dirname(file);
2007
+ const references = collectExtensionSpecifierReferences(source, file, ast);
2008
+ for (const reference of references) {
2009
+ const specifier = reference.specifier;
2010
+ try {
2011
+ let resolved: string | null = null;
2012
+ let nextCacheBustResolvedImports = cacheBustResolvedImports;
2013
+ let resolvedModuleKind: ExtensionModuleKind | undefined;
2014
+ let resolvedEsmBranch = false;
2015
+ let requiresNativeAddonRewrite = false;
2016
+ let requiresSynchronousSourceHook = false;
2017
+ let synchronousSourceUpgraded = false;
2018
+ const isRequired = reference.kind === "require";
2019
+ if (specifier.startsWith(".")) {
2020
+ const candidate = isRequired
2021
+ ? await resolveRelativeCommonJsRequire(specifier, file)
2022
+ : Bun.resolveSync(specifier, dir);
2023
+ if (candidate && hasSourceModuleExtension(candidate)) {
2024
+ const inheritedTargetKind = isRequired
2025
+ ? sourceIsCommonJs
2026
+ ? "commonjs"
2027
+ : undefined
2028
+ : sourceIsCommonJs
2029
+ ? "commonjs"
2030
+ : esmBranch
2031
+ ? "esm"
2032
+ : undefined;
2033
+ const targetIsCommonJs = await isCommonJsModulePath(candidate, undefined, inheritedTargetKind);
2034
+ const isCommonJsDescendant = isRequired && sourceIsCommonJs && targetIsCommonJs;
2035
+ requiresNativeAddonRewrite =
2036
+ isRequired && !isCommonJsDescendant && (await moduleRequiresNativeAddon(candidate));
2037
+ if (!isRequired || isCommonJsDescendant || requiresNativeAddonRewrite || !targetIsCommonJs) {
2038
+ resolved = await realpathOrSelf(candidate);
2039
+ resolvedModuleKind = targetIsCommonJs ? "commonjs" : "esm";
2040
+ resolvedEsmBranch = !targetIsCommonJs && esmBranch;
2041
+ requiresSynchronousSourceHook = isRequired && !targetIsCommonJs;
2042
+ }
2043
+ }
2044
+ } else if (specifier.startsWith("#")) {
2045
+ const candidate = await resolvePackageImportSpecifier(specifier, file);
2046
+ if (candidate) {
2047
+ const inheritedTargetKind = isRequired
2048
+ ? sourceIsCommonJs
2049
+ ? "commonjs"
2050
+ : undefined
2051
+ : sourceIsCommonJs
2052
+ ? "commonjs"
2053
+ : esmBranch
2054
+ ? "esm"
2055
+ : undefined;
2056
+ const targetIsCommonJs = await isCommonJsModulePath(candidate, undefined, inheritedTargetKind);
2057
+ const isCommonJsDescendant = isRequired && sourceIsCommonJs && targetIsCommonJs;
2058
+ requiresNativeAddonRewrite =
2059
+ isRequired && !isCommonJsDescendant && (await moduleRequiresNativeAddon(candidate));
2060
+ if (!isRequired || isCommonJsDescendant || requiresNativeAddonRewrite || !targetIsCommonJs) {
2061
+ resolved = candidate;
2062
+ resolvedModuleKind = targetIsCommonJs ? "commonjs" : "esm";
2063
+ resolvedEsmBranch = !targetIsCommonJs && esmBranch;
2064
+ requiresSynchronousSourceHook = isRequired && !targetIsCommonJs;
2065
+ }
2066
+ }
2067
+ } else if (
2068
+ isBareExtensionDependencySpecifier(specifier) &&
2069
+ !remapLegacyPiSpecifier(specifier) &&
2070
+ specifier !== "typebox" &&
2071
+ specifier !== "@sinclair/typebox"
2072
+ ) {
2073
+ const dependencyEntry = isRequired
2074
+ ? await resolveExtensionBareRequire(specifier, file)
2075
+ : await resolveExtensionBareDependency(specifier, file);
2076
+ const isHookableEntry = Boolean(dependencyEntry && hasSourceModuleExtension(dependencyEntry));
2077
+ const selectedEsmBranch =
2078
+ !isRequired &&
2079
+ isHookableEntry &&
2080
+ dependencyEntry !== null &&
2081
+ (await isSelectedNoTypeEsmPackageBranch(specifier, file, dependencyEntry));
2082
+ const inheritedTargetKind = isRequired
2083
+ ? sourceIsCommonJs
2084
+ ? "commonjs"
2085
+ : undefined
2086
+ : selectedEsmBranch
2087
+ ? "esm"
2088
+ : undefined;
2089
+ const isCommonJsEntry =
2090
+ isHookableEntry && dependencyEntry
2091
+ ? await isCommonJsModulePath(dependencyEntry, undefined, inheritedTargetKind)
2092
+ : false;
2093
+ if (isHookableEntry && dependencyEntry && (!isRequired || (sourceIsCommonJs && isCommonJsEntry))) {
2094
+ resolved = await realpathOrSelf(dependencyEntry);
2095
+ } else if (isHookableEntry && dependencyEntry && isRequired && !isCommonJsEntry) {
2096
+ resolved = await realpathOrSelf(dependencyEntry);
2097
+ requiresSynchronousSourceHook = true;
2098
+ } else if (isHookableEntry && dependencyEntry && isRequired) {
2099
+ requiresNativeAddonRewrite = await moduleRequiresNativeAddon(dependencyEntry);
2100
+ if (requiresNativeAddonRewrite) {
2101
+ resolved = await realpathOrSelf(dependencyEntry);
2102
+ }
2103
+ }
2104
+ if (resolved) {
2105
+ resolvedModuleKind = isCommonJsEntry ? "commonjs" : "esm";
2106
+ resolvedEsmBranch = selectedEsmBranch && !isCommonJsEntry;
2107
+ }
2108
+ nextCacheBustResolvedImports = false;
2109
+ }
2110
+ if (
2111
+ resolved &&
2112
+ (requiresNativeAddonRewrite ||
2113
+ requiresSynchronousSourceHook ||
2114
+ (synchronousSourcePaths.has(file) && resolvedModuleKind === "esm"))
2115
+ ) {
2116
+ synchronousSourceUpgraded = !synchronousSourcePaths.has(resolved);
2117
+ synchronousSourcePaths.add(resolved);
2118
+ }
2119
+ if (resolved) {
2120
+ const queuedCacheBust = queuedCacheBustResolvedImports.get(resolved) ?? false;
2121
+ const mergedCacheBust = queuedCacheBust || nextCacheBustResolvedImports;
2122
+ queuedCacheBustResolvedImports.set(resolved, mergedCacheBust);
2123
+ const queuedModuleKind = queuedModuleKinds.get(resolved);
2124
+ const mergedEsmBranch = queuedEsmBranchPaths.has(resolved) || resolvedEsmBranch;
2125
+ const mergedModuleKind =
2126
+ queuedModuleKind && resolvedModuleKind && queuedModuleKind !== resolvedModuleKind
2127
+ ? mergedEsmBranch
2128
+ ? "esm"
2129
+ : "commonjs"
2130
+ : (queuedModuleKind ?? resolvedModuleKind);
2131
+ if (mergedModuleKind) {
2132
+ queuedModuleKinds.set(resolved, mergedModuleKind);
2133
+ }
2134
+ if (mergedEsmBranch) {
2135
+ queuedEsmBranchPaths.add(resolved);
2136
+ }
2137
+ if (modules.has(resolved) && (queuedModuleKind !== mergedModuleKind || synchronousSourceUpgraded)) {
2138
+ modules.delete(resolved);
2139
+ commonJsPaths.delete(resolved);
2140
+ }
2141
+ if (!modules.has(resolved)) {
2142
+ queue.push({
2143
+ file: resolved,
2144
+ cacheBustResolvedImports: mergedCacheBust,
2145
+ moduleKind: mergedModuleKind,
2146
+ esmBranch: resolvedEsmBranch,
2147
+ });
2148
+ }
2149
+ }
2150
+ } catch {
2151
+ // Unresolvable import (e.g. a type-only path); skip it.
2152
+ }
2153
+ }
2154
+ }
2155
+ for (const [modulePath, source] of modules) {
2156
+ if (commonJsPaths.has(modulePath)) {
2157
+ modules.set(modulePath, await rewriteExtensionSpecifiers(source, modulePath, true));
2158
+ } else if (synchronousSourcePaths.has(modulePath)) {
2159
+ modules.set(modulePath, await rewriteLegacyExtensionSource(source, modulePath));
2160
+ }
2161
+ }
2162
+ return {
2163
+ modules,
2164
+ commonJsPaths,
2165
+ synchronousSourcePaths,
2166
+ cacheBustResolvedImportModules: new Set(
2167
+ [...queuedCacheBustResolvedImports]
2168
+ .filter(([modulePath, enabled]) => enabled && modules.has(modulePath))
2169
+ .map(([modulePath]) => modulePath),
2170
+ ),
2171
+ };
2172
+ }
2173
+
2174
+ /** Test seam for compiled-binary dependency graph discovery and rewriting. */
2175
+ export async function __collectLegacyPiExtensionSourcesForTests(
2176
+ entryPath: string,
2177
+ ): Promise<ReadonlyMap<string, string>> {
2178
+ const entryRealPath = await realpathOrSelf(path.resolve(entryPath));
2179
+ const graph = await collectExtensionModules(entryRealPath);
2180
+ return graph.modules;
2181
+ }
2182
+
2183
+ /**
2184
+ * Discovers CommonJS export names Bun normally exposes to ESM importers. The
2185
+ * bridge must declare them statically because its default export is synthetic.
2186
+ */
2187
+ const COMMONJS_NAMED_EXPORT_IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
2188
+
2189
+ function collectCommonJsNamedExports(source: string, modulePath: string, visited = new Set<string>()): string[] {
2190
+ let realModulePath = modulePath;
2191
+ try {
2192
+ realModulePath = fs.realpathSync(modulePath);
2193
+ } catch {
2194
+ // The caller's path remains the stable cycle key when realpath fails.
2195
+ }
2196
+ if (visited.has(realModulePath)) {
2197
+ return [];
2198
+ }
2199
+ visited.add(realModulePath);
2200
+
2201
+ const names = new Set<string>();
2202
+
2203
+ const reexportSpecifiers = new Set<string>();
2204
+ const ast = parseExtensionSource(source, modulePath);
2205
+ for (const { node, scope } of collectScopedAstNodes(
2206
+ ast,
2207
+ candidate => candidate.type === "CallExpression" || candidate.type === "AssignmentExpression",
2208
+ )) {
2209
+ if (node.type === "CallExpression") {
2210
+ const callee = asAstNode(node.callee);
2211
+ if (isUncomputedMember(callee, "Object", "defineProperty") && !scopeHasBinding(scope, OBJECT_BINDING)) {
2212
+ const target = nodeArgument(node, 0);
2213
+ const property = nodeArgument(node, 1);
2214
+ if (
2215
+ isUnshadowedExportsTarget(target, scope) &&
2216
+ property?.type === "StringLiteral" &&
2217
+ typeof property.value === "string" &&
2218
+ property.value !== "default" &&
2219
+ COMMONJS_NAMED_EXPORT_IDENTIFIER.test(property.value)
2220
+ ) {
2221
+ names.add(property.value);
2222
+ }
2223
+ continue;
2224
+ }
2225
+ if (isIdentifier(callee, "__exportStar")) {
2226
+ const sourceCall = nodeArgument(node, 0);
2227
+ const target = nodeArgument(node, 1);
2228
+ if (isUnshadowedExportsTarget(target, scope) && isGlobalRequireCall(sourceCall, scope)) {
2229
+ const argument = nodeArgument(sourceCall, 0);
2230
+ if (argument?.type === "StringLiteral" && typeof argument.value === "string") {
2231
+ reexportSpecifiers.add(argument.value);
2232
+ }
2233
+ }
2234
+ continue;
2235
+ }
2236
+ }
2237
+ if (node.type !== "AssignmentExpression" || node.operator !== "=") continue;
2238
+ const left = asAstNode(node.left);
2239
+ if (left?.type !== "MemberExpression") continue;
2240
+
2241
+ const propertyName = staticMemberPropertyName(left);
2242
+ const object = asAstNode(left.object);
2243
+ if (propertyName !== null && isUnshadowedExportsTarget(object, scope)) {
2244
+ if (propertyName !== "default" && COMMONJS_NAMED_EXPORT_IDENTIFIER.test(propertyName)) {
2245
+ names.add(propertyName);
2246
+ }
2247
+ continue;
2248
+ }
2249
+ if (!isUncomputedMember(left, "module", "exports") || scopeHasBinding(scope, MODULE_BINDING)) continue;
2250
+
2251
+ const right = asAstNode(node.right);
2252
+ if (right?.type === "ObjectExpression") {
2253
+ const properties = nodeArray(right, "properties");
2254
+ if (properties) {
2255
+ for (const value of properties) {
2256
+ const property = asAstNode(value);
2257
+ if (!property || (property.type !== "ObjectProperty" && property.type !== "ObjectMethod")) continue;
2258
+ const name = staticObjectPropertyName(property);
2259
+ if (name && name !== "default" && COMMONJS_NAMED_EXPORT_IDENTIFIER.test(name)) {
2260
+ names.add(name);
2261
+ }
2262
+ }
2263
+ }
2264
+ continue;
2265
+ }
2266
+ if (isGlobalRequireCall(right, scope)) {
2267
+ const argument = nodeArgument(right, 0);
2268
+ if (argument?.type === "StringLiteral" && typeof argument.value === "string") {
2269
+ reexportSpecifiers.add(argument.value);
2270
+ }
2271
+ }
2272
+ }
2273
+ const nativeRequire = createRequire(modulePath);
2274
+ for (const specifier of reexportSpecifiers) {
2275
+ try {
2276
+ const resolved = fs.realpathSync(nativeRequire.resolve(specifier));
2277
+ const reexportedSource = rewriteExtensionSpecifiersFromCache(fs.readFileSync(resolved, "utf8"), resolved);
2278
+ for (const name of collectCommonJsNamedExports(reexportedSource, resolved, visited)) {
2279
+ names.add(name);
2280
+ }
2281
+ } catch {
2282
+ // Native modules and non-source re-exports do not expose analyzable names.
2283
+ }
2284
+ }
2285
+ return [...names];
2286
+ }
2287
+
2288
+ /**
2289
+ * The shared evaluator gives ESM imports and sibling `require()` calls the
2290
+ * same `module.exports` value and cycle-aware cache.
2291
+ */
2292
+ function synthesizeCommonJsDefaultModule(modulePath: string, source: string, targetPath = modulePath): string {
2293
+ let commonJsSource = source;
2294
+ if (commonJsSource.startsWith("#!")) {
2295
+ const firstLineEnd = commonJsSource.indexOf("\n");
2296
+ commonJsSource = firstLineEnd === -1 ? "" : commonJsSource.slice(firstLineEnd + 1);
2297
+ }
2298
+
2299
+ const executableSource = targetPath.endsWith(".cts")
2300
+ ? commonJsTypeScriptTranspiler.transformSync(commonJsSource)
2301
+ : commonJsSource;
2302
+ commonJsModuleDefinitions.set(modulePath, {
2303
+ source: executableSource,
2304
+ filename: targetPath,
2305
+ dirname: path.dirname(targetPath),
2306
+ });
2307
+ commonJsModuleCache.delete(modulePath);
2308
+ const exportsBinding = "__ompLegacyPiCommonJsExports";
2309
+ const namedExports = collectCommonJsNamedExports(executableSource, targetPath)
2310
+ .map(
2311
+ (name, index) =>
2312
+ `const __ompLegacyPiCommonJsExport${index} = ${exportsBinding}[${JSON.stringify(name)}]; export { __ompLegacyPiCommonJsExport${index} as ${name} };`,
2313
+ )
2314
+ .join("\n");
2315
+ return `const ${exportsBinding} = globalThis[${JSON.stringify(COMMONJS_REQUIRE_GLOBAL)}](${JSON.stringify(modulePath)});\nexport default ${exportsBinding};\n${namedExports}\n`;
2316
+ }
2317
+
2318
+ /**
2319
+ * Linkedom's canvas bridge uses its bundled fallback because OMP does not ship
2320
+ * native canvas.
2321
+ */
2322
+ async function prepareCommonJsDefaultModule(modulePath: string, source: string): Promise<string> {
2323
+ const packageRoot = await findPackageRoot(modulePath);
2324
+ if (!packageRoot) {
2325
+ return synthesizeCommonJsDefaultModule(modulePath, source);
2326
+ }
2327
+ const manifest = await readPackageManifest(packageRoot);
2328
+ const packageRelativePath = path.relative(packageRoot, modulePath).split(path.sep).join("/");
2329
+ if (manifest?.name !== "linkedom" || packageRelativePath !== "commonjs/canvas.cjs") {
2330
+ return synthesizeCommonJsDefaultModule(modulePath, source);
2331
+ }
2332
+
2333
+ const targetPath = path.join(packageRoot, "commonjs", "canvas-shim.cjs");
2334
+ commonJsFallbackModulePaths.set(modulePath, targetPath);
2335
+ return synthesizeCommonJsDefaultModule(modulePath, await Bun.file(targetPath).text(), targetPath);
2336
+ }
2337
+
2338
+ /**
2339
+ * Install exact-path load hooks for the current extension graph. ESM/TS source
2340
+ * retains the async rewrite path. Graph-owned CommonJS modules and native-addon
2341
+ * loaders stay synchronous because Bun rejects `require()` targets backed by
2342
+ * async `onLoad` callbacks.
2343
+ */
2344
+ async function installExtensionGraphHook(
2345
+ entryRealPath: string,
2346
+ modules: Map<string, string>,
2347
+ commonJsPaths: Set<string>,
2348
+ synchronousSourcePaths: ReadonlySet<string>,
2349
+ cacheBustResolvedImportModules: ReadonlySet<string>,
2350
+ ): Promise<{ asyncModules: Map<string, string> }> {
2351
+ const asyncModules = new Map<string, string>();
2352
+ for (const [modulePath, source] of modules) {
2353
+ if (commonJsPaths.has(modulePath) || synchronousSourcePaths.has(modulePath)) {
2354
+ continue;
2355
+ }
2356
+ asyncModules.set(modulePath, source);
2357
+ }
2358
+
2359
+ if (asyncModules.size > 0) {
2360
+ const alternation = [...asyncModules.keys()].map(escapeRegExp).join("|");
2361
+ const filter = new RegExp(`^(?:${alternation})(?:\\?mtime=\\d+)?$`);
2362
+ const hookId = Bun.hash(`${entryRealPath}\0async\0${[...asyncModules.keys()].join("\0")}`).toString(36);
2363
+ Bun.plugin({
2364
+ name: `omp:legacy-pi-ext:${hookId}`,
2365
+ setup(build) {
2366
+ build.onLoad({ filter, namespace: "file" }, args => {
2367
+ const queryIndex = args.path.indexOf("?mtime=");
2368
+ const sourcePath = queryIndex >= 0 ? args.path.slice(0, queryIndex) : args.path;
2369
+ const mtimeTag = queryIndex >= 0 ? args.path.slice(queryIndex + "?mtime=".length) : null;
2370
+ // A later reload can upgrade this module to synchronous loading (a
2371
+ // new `require()` edge reaches it) without re-registering hooks:
2372
+ // this filter keeps matching and `require()` rejects async onLoad
2373
+ // results, so serve the pre-rewritten synchronous source inline.
2374
+ // `ensureExtensionGraphHook` refreshes it on every (re)load.
2375
+ const synchronousSource = synchronousModuleSources.get(sourcePath);
2376
+ if (synchronousSource !== undefined) {
2377
+ return { contents: synchronousSource, loader: getLoader(sourcePath) };
2378
+ }
2379
+ const cached = asyncModules.get(sourcePath);
2380
+ const resolvedImportMtimeTag = cacheBustResolvedImportModules.has(sourcePath) ? mtimeTag : null;
2381
+ return (async () => {
2382
+ let raw: string;
2383
+ if (cached !== undefined) {
2384
+ // consume-once: preserves ?mtime edit-pickup for re-imports
2385
+ asyncModules.delete(sourcePath);
2386
+ raw = cached;
2387
+ } else {
2388
+ raw = await Bun.file(sourcePath).text();
2389
+ }
2390
+ return {
2391
+ contents: await rewriteLegacyExtensionSource(raw, sourcePath, mtimeTag, resolvedImportMtimeTag),
2392
+ loader: getLoader(sourcePath),
2393
+ };
2394
+ })();
2395
+ });
2396
+ },
2397
+ });
2398
+ }
2399
+
2400
+ if (commonJsPaths.size > 0) {
2401
+ const alternation = [...commonJsPaths].map(escapeRegExp).join("|");
2402
+ const filter = new RegExp(`^(?:${alternation})(?:\\?mtime=\\d+)?$`);
2403
+ const hookId = Bun.hash(`${entryRealPath}\0commonjs\0${[...commonJsPaths].join("\0")}`).toString(36);
2404
+ Bun.plugin({
2405
+ name: `omp:legacy-pi-ext:${hookId}`,
2406
+ setup(build) {
2407
+ build.onLoad({ filter, namespace: "file" }, args => {
2408
+ const queryIndex = args.path.indexOf("?mtime=");
2409
+ const sourcePath = queryIndex >= 0 ? args.path.slice(0, queryIndex) : args.path;
2410
+ let source = commonJsModuleSources.get(sourcePath);
2411
+ if (source === undefined) {
2412
+ const targetPath = commonJsFallbackModulePaths.get(sourcePath) ?? sourcePath;
2413
+ const raw = rewriteExtensionSpecifiersFromCache(fs.readFileSync(targetPath, "utf8"), sourcePath);
2414
+ source = synthesizeCommonJsDefaultModule(sourcePath, raw, targetPath);
2415
+ }
2416
+ return { contents: source, loader: getLoader(sourcePath) };
2417
+ });
2418
+ },
2419
+ });
2420
+ }
2421
+
2422
+ if (synchronousSourcePaths.size > 0) {
2423
+ const alternation = [...synchronousSourcePaths].map(escapeRegExp).join("|");
2424
+ const filter = new RegExp(`^(?:${alternation})(?:\\?mtime=\\d+)?$`);
2425
+ const hookId = Bun.hash(`${entryRealPath}\0sync-source\0${[...synchronousSourcePaths].join("\0")}`).toString(36);
2426
+ Bun.plugin({
2427
+ name: `omp:legacy-pi-ext:${hookId}`,
2428
+ setup(build) {
2429
+ build.onLoad({ filter, namespace: "file" }, args => {
2430
+ const queryIndex = args.path.indexOf("?mtime=");
2431
+ const sourcePath = queryIndex >= 0 ? args.path.slice(0, queryIndex) : args.path;
2432
+ const source = synchronousModuleSources.get(sourcePath);
2433
+ if (source === undefined) {
2434
+ throw new Error(`Missing pre-rewritten synchronous extension source: ${sourcePath}`);
2435
+ }
2436
+ return { contents: source, loader: getLoader(sourcePath) };
2437
+ });
2438
+ },
2439
+ });
2440
+ }
2441
+ return { asyncModules };
2442
+ }
2443
+
2444
+ /**
2445
+ * Ensure every currently reachable extension source module has a load-time
2446
+ * rewrite hook. The entry graph can grow across reloads, so each call collects
2447
+ * the current graph and registers hooks for paths not covered by earlier loads.
2448
+ *
2449
+ * Returns a clearable handle to drop cached sources that weren't consumed
2450
+ * during the initial load; `undefined` when no new modules were discovered.
2451
+ */
2452
+ async function ensureExtensionGraphHook(entryRealPath: string): Promise<{ clear(): void } | undefined> {
2453
+ const {
2454
+ modules: currentModules,
2455
+ commonJsPaths,
2456
+ cacheBustResolvedImportModules: discoveredCacheBustModules,
2457
+ synchronousSourcePaths,
2458
+ } = await collectExtensionModules(entryRealPath);
2459
+ let cacheBustResolvedImportModules = extensionGraphCacheBustResolvedImportModules.get(entryRealPath);
2460
+ if (!cacheBustResolvedImportModules) {
2461
+ cacheBustResolvedImportModules = new Set<string>();
2462
+ extensionGraphCacheBustResolvedImportModules.set(entryRealPath, cacheBustResolvedImportModules);
2463
+ }
2464
+ for (const modulePath of discoveredCacheBustModules) {
2465
+ cacheBustResolvedImportModules.add(modulePath);
2466
+ }
2467
+ for (const [modulePath, source] of currentModules) {
2468
+ if (commonJsPaths.has(modulePath)) {
2469
+ commonJsModuleSources.set(modulePath, await prepareCommonJsDefaultModule(modulePath, source));
2470
+ commonJsGraphModulePaths.add(modulePath);
2471
+ }
2472
+ if (synchronousSourcePaths.has(modulePath)) {
2473
+ synchronousModuleSources.set(modulePath, source);
2474
+ } else if (synchronousModuleSources.has(modulePath)) {
2475
+ // The path lost its require() edges on this walk, but the permanent
2476
+ // hooks installed while it was synchronous still serve it from this
2477
+ // map — keep the pre-rewritten bytes fresh instead of serving the
2478
+ // stale snapshot from the walk that flagged it.
2479
+ synchronousModuleSources.set(modulePath, await rewriteLegacyExtensionSource(source, modulePath));
2480
+ }
2481
+ }
2482
+ let hookedModules = extensionGraphHookModules.get(entryRealPath);
2483
+ if (!hookedModules) {
2484
+ hookedModules = new Set<string>();
2485
+ extensionGraphHookModules.set(entryRealPath, hookedModules);
2486
+ }
2487
+
2488
+ const pendingModules = new Map<string, string>();
2489
+ const pendingCommonJsPaths = new Set<string>();
2490
+ const pendingSynchronousSourcePaths = new Set<string>();
2491
+ for (const [modulePath, source] of currentModules) {
2492
+ if (!hookedModules.has(modulePath)) {
2493
+ pendingModules.set(modulePath, source);
2494
+ if (commonJsPaths.has(modulePath)) {
2495
+ pendingCommonJsPaths.add(modulePath);
2496
+ }
2497
+ if (synchronousSourcePaths.has(modulePath)) {
2498
+ pendingSynchronousSourcePaths.add(modulePath);
2499
+ }
2500
+ }
2501
+ }
2502
+ if (pendingModules.size === 0 && commonJsPaths.size === 0) {
2503
+ return undefined;
2504
+ }
2505
+
2506
+ let asyncModules = new Map<string, string>();
2507
+ if (pendingModules.size > 0) {
2508
+ ({ asyncModules } = await installExtensionGraphHook(
2509
+ entryRealPath,
2510
+ pendingModules,
2511
+ pendingCommonJsPaths,
2512
+ pendingSynchronousSourcePaths,
2513
+ cacheBustResolvedImportModules,
2514
+ ));
2515
+ for (const modulePath of pendingModules.keys()) {
2516
+ hookedModules.add(modulePath);
2517
+ }
2518
+ }
2519
+ return {
2520
+ clear() {
2521
+ asyncModules.clear();
2522
+ for (const modulePath of commonJsPaths) {
2523
+ commonJsModuleSources.delete(modulePath);
2524
+ commonJsModuleDefinitions.delete(modulePath);
2525
+ commonJsModuleCache.delete(modulePath);
2526
+ }
2527
+ },
2528
+ };
2529
+ }
2530
+
2531
+ /**
2532
+ * Load a legacy Pi extension module from its real on-disk location.
2533
+ *
2534
+ * The extension runs in place, so its `import.meta.url` is the real source file
2535
+ * and `__dirname`-relative `readFileSync` asset loads (HTML/CSS bundled next to
2536
+ * the entry) resolve exactly as they do under the original Pi runtime — no
2537
+ * temp-directory mirroring and no asset copying. An `onLoad` hook scoped to the
2538
+ * entry's source graph rewrites only host-resolved compatibility imports in the
2539
+ * extension's own source; everything else resolves natively.
2540
+ */
2541
+ export async function loadLegacyPiModule(resolvedPath: string): Promise<unknown> {
2542
+ // Bun reports the realpath of a loaded module to `onLoad` and exposes it as
2543
+ // `import.meta.url`. Resolve symlinks here too (macOS `/var`→`/private/var`,
2544
+ // `bun link`/pnpm installs) so the rewrite filter matches the path Bun
2545
+ // actually hands the hook.
2546
+ const entryRealPath = await realpathOrSelf(path.resolve(resolvedPath));
2547
+ await ensureLegacyPiOverridesReady();
2548
+ const pendingSources = await ensureExtensionGraphHook(entryRealPath);
2549
+ try {
2550
+ // Dynamic import is required: legacy extension entry paths are user/plugin supplied at runtime.
2551
+ // On POSIX, use the raw filesystem path so Bun keys the `?mtime`
2552
+ // suffix as part of the module identity; Bun ignores query strings on
2553
+ // `file://` specifiers, which would serve stale edited source.
2554
+ const entrySpecifier =
2555
+ process.platform === "win32" || isBundledVirtualSpecifier(entryRealPath)
2556
+ ? toImportSpecifier(entryRealPath)
2557
+ : entryRealPath;
2558
+ return await import(`${entrySpecifier}?mtime=${nextLegacyPiLoadTag()}`);
2559
+ } finally {
2560
+ // Drop whatever the initial import didn't consume: graph modules only
2561
+ // reached by lazy dynamic imports must be read from disk at their actual
2562
+ // import time, not served from this load-time snapshot.
2563
+ pendingSources?.clear();
2564
+ }
2565
+ }
2566
+
2567
+ function getLoader(path: string): "js" | "jsx" | "ts" | "tsx" {
2568
+ if (path.endsWith(".tsx")) {
2569
+ return "tsx";
2570
+ }
2571
+ if (path.endsWith(".jsx")) {
2572
+ return "jsx";
2573
+ }
2574
+ if (path.endsWith(".ts") || path.endsWith(".mts") || path.endsWith(".cts")) {
2575
+ return "ts";
2576
+ }
2577
+ return "js";
2578
+ }
2579
+
2580
+ function resolveLegacyPiSpecifier(args: { path: string; importer: string }): LegacyPiResolveResult | undefined {
2581
+ const remappedSpecifier = remapLegacyPiSpecifier(args.path);
2582
+ if (!remappedSpecifier) {
2583
+ return undefined;
2584
+ }
2585
+
2586
+ // Primary: resolve the canonical @oh-my-pi/* specifier from the host binary
2587
+ // location. Works in dev mode and in source-link installs.
2588
+ try {
2589
+ return toLegacyPiResolveResult(resolveCanonicalPiSpecifier(remappedSpecifier));
2590
+ } catch {
2591
+ // Fallback for compiled binary mode: the bundled packages live inside
2592
+ // /$bunfs/root and aren't reachable by filesystem resolution. Prefer the
2593
+ // canonical specifier against the importing file's directory when the
2594
+ // plugin installed @oh-my-pi peer deps, then try the original legacy
2595
+ // specifier for plugins that still vendor only @mariozechner or
2596
+ // @earendil-works peer deps.
2597
+ const importerDir = path.dirname(args.importer);
2598
+ try {
2599
+ return toLegacyPiResolveResult(Bun.resolveSync(remappedSpecifier, importerDir));
2600
+ } catch {
2601
+ try {
2602
+ return toLegacyPiResolveResult(Bun.resolveSync(args.path, importerDir));
2603
+ } catch {
2604
+ return undefined;
2605
+ }
2606
+ }
2607
+ }
2608
+ }
2609
+
2610
+ function resolveTypeBoxSpecifier(): LegacyPiResolveResult | undefined {
2611
+ return TYPEBOX_SHIM_PATH ? toLegacyPiResolveResult(TYPEBOX_SHIM_PATH) : undefined;
2612
+ }
2613
+
2614
+ export function installLegacyPiSpecifierShim(): void {
2615
+ if (isLegacyPiSpecifierShimInstalled) {
2616
+ return;
2617
+ }
2618
+ isLegacyPiSpecifierShimInstalled = true;
2619
+
2620
+ Bun.plugin({
2621
+ name: "omp:legacy-pi-shim",
2622
+ setup(build) {
2623
+ build.onResolve({ filter: LEGACY_PI_SPECIFIER_FILTER, namespace: "file" }, resolveLegacyPiSpecifier);
2624
+ build.onResolve({ filter: TYPEBOX_SPECIFIER_FILTER, namespace: "file" }, resolveTypeBoxSpecifier);
2625
+ build.onResolve({ filter: /^omp-legacy-pi-bundled:.+$/, namespace: "file" }, args =>
2626
+ resolveBundledVirtualSpecifier(args.path),
2627
+ );
2628
+ build.onResolve({ filter: /.*/, namespace: BUNDLED_VIRTUAL_NAMESPACE }, args =>
2629
+ resolveBundledVirtualSpecifier(args.path),
2630
+ );
2631
+ // Compiled mode serves `omp-legacy-pi-bundled:<key>` imports from
2632
+ // live host module references. No bunfs path leaves this loader.
2633
+ build.onLoad({ filter: /.*/, namespace: BUNDLED_VIRTUAL_NAMESPACE }, async args => {
2634
+ return { contents: await synthesizeBundledModuleSource(args.path), loader: "js" };
2635
+ });
2636
+ },
2637
+ });
2638
+ }
2639
+
2640
+ /** Test seam: clears the memoized canonical specifier resolutions. */
2641
+ export function __resetLegacyPiResolutionCache(): void {
2642
+ clearLegacyPiResolutionCaches();
2643
+ }