@entelligentsia/forgecli 0.15.0 → 0.20.0

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 (1202) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/dist/CHANGELOG-pi.md +55 -0
  3. package/dist/bin/argv.d.ts +2 -0
  4. package/dist/bin/argv.js +3 -1
  5. package/dist/bin/argv.js.map +1 -1
  6. package/dist/bin/config.d.ts +5 -0
  7. package/dist/bin/config.js +34 -13
  8. package/dist/bin/config.js.map +1 -1
  9. package/dist/bin/forge.js +14 -58
  10. package/dist/bin/forge.js.map +1 -1
  11. package/dist/bin/shared-parser.d.ts +23 -0
  12. package/dist/bin/shared-parser.js +12 -0
  13. package/dist/bin/shared-parser.js.map +1 -0
  14. package/dist/bin/update-cli.js +7 -1
  15. package/dist/bin/update-cli.js.map +1 -1
  16. package/dist/extensions/forgecli/add-pipeline.js.map +1 -1
  17. package/dist/extensions/forgecli/add-task.js.map +1 -1
  18. package/dist/extensions/forgecli/approve.d.ts +4 -6
  19. package/dist/extensions/forgecli/approve.js +8 -73
  20. package/dist/extensions/forgecli/approve.js.map +1 -1
  21. package/dist/extensions/forgecli/ask-user-tool.js.map +1 -1
  22. package/dist/extensions/forgecli/audience-gate.d.ts +1 -1
  23. package/dist/extensions/forgecli/audience-gate.js.map +1 -1
  24. package/dist/extensions/forgecli/calibrate.d.ts +4 -1
  25. package/dist/extensions/forgecli/calibrate.js +10 -20
  26. package/dist/extensions/forgecli/calibrate.js.map +1 -1
  27. package/dist/extensions/forgecli/collate.d.ts +4 -6
  28. package/dist/extensions/forgecli/collate.js +8 -73
  29. package/dist/extensions/forgecli/collate.js.map +1 -1
  30. package/dist/extensions/forgecli/commit.d.ts +4 -6
  31. package/dist/extensions/forgecli/commit.js +8 -73
  32. package/dist/extensions/forgecli/commit.js.map +1 -1
  33. package/dist/extensions/forgecli/config-command.js.map +1 -1
  34. package/dist/extensions/forgecli/config-layer.js +4 -2
  35. package/dist/extensions/forgecli/config-layer.js.map +1 -1
  36. package/dist/extensions/forgecli/config-tui/component.d.ts +1 -1
  37. package/dist/extensions/forgecli/config-tui/component.js +25 -21
  38. package/dist/extensions/forgecli/config-tui/component.js.map +1 -1
  39. package/dist/extensions/forgecli/config-tui/handler.js +3 -6
  40. package/dist/extensions/forgecli/config-tui/handler.js.map +1 -1
  41. package/dist/extensions/forgecli/config-tui/keys.js.map +1 -1
  42. package/dist/extensions/forgecli/config-tui/plugin-config-reader.js.map +1 -1
  43. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.d.ts +2 -2
  44. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.js +10 -8
  45. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.js.map +1 -1
  46. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.d.ts +2 -2
  47. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.js +2 -5
  48. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.js.map +1 -1
  49. package/dist/extensions/forgecli/config-tui/screens/override-editor.d.ts +2 -2
  50. package/dist/extensions/forgecli/config-tui/screens/override-editor.js +15 -11
  51. package/dist/extensions/forgecli/config-tui/screens/override-editor.js.map +1 -1
  52. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.d.ts +2 -2
  53. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js +15 -11
  54. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js.map +1 -1
  55. package/dist/extensions/forgecli/config-tui/screens/overrides-list.d.ts +2 -2
  56. package/dist/extensions/forgecli/config-tui/screens/overrides-list.js +7 -4
  57. package/dist/extensions/forgecli/config-tui/screens/overrides-list.js.map +1 -1
  58. package/dist/extensions/forgecli/config-tui/screens/persona-editor.d.ts +2 -2
  59. package/dist/extensions/forgecli/config-tui/screens/persona-editor.js +6 -12
  60. package/dist/extensions/forgecli/config-tui/screens/persona-editor.js.map +1 -1
  61. package/dist/extensions/forgecli/config-tui/screens/persona-picker.d.ts +2 -2
  62. package/dist/extensions/forgecli/config-tui/screens/persona-picker.js +3 -6
  63. package/dist/extensions/forgecli/config-tui/screens/persona-picker.js.map +1 -1
  64. package/dist/extensions/forgecli/config-tui/screens/personas-list.d.ts +2 -2
  65. package/dist/extensions/forgecli/config-tui/screens/personas-list.js +2 -2
  66. package/dist/extensions/forgecli/config-tui/screens/personas-list.js.map +1 -1
  67. package/dist/extensions/forgecli/config-tui/screens/shared.d.ts +1 -1
  68. package/dist/extensions/forgecli/config-tui/screens/shared.js +4 -5
  69. package/dist/extensions/forgecli/config-tui/screens/shared.js.map +1 -1
  70. package/dist/extensions/forgecli/config-tui/screens/show-resolved.d.ts +2 -2
  71. package/dist/extensions/forgecli/config-tui/screens/show-resolved.js +9 -11
  72. package/dist/extensions/forgecli/config-tui/screens/show-resolved.js.map +1 -1
  73. package/dist/extensions/forgecli/config-tui/screens/tier-menu.d.ts +2 -2
  74. package/dist/extensions/forgecli/config-tui/screens/tier-menu.js +9 -2
  75. package/dist/extensions/forgecli/config-tui/screens/tier-menu.js.map +1 -1
  76. package/dist/extensions/forgecli/config-tui/screens/tier-picker.d.ts +2 -2
  77. package/dist/extensions/forgecli/config-tui/screens/tier-picker.js +12 -3
  78. package/dist/extensions/forgecli/config-tui/screens/tier-picker.js.map +1 -1
  79. package/dist/extensions/forgecli/config-tui/screens/types.d.ts +1 -1
  80. package/dist/extensions/forgecli/config-tui/screens.d.ts +10 -10
  81. package/dist/extensions/forgecli/config-tui/screens.js +16 -16
  82. package/dist/extensions/forgecli/config-tui/screens.js.map +1 -1
  83. package/dist/extensions/forgecli/config-tui/state/buffer.d.ts +2 -2
  84. package/dist/extensions/forgecli/config-tui/state/buffer.js +1 -2
  85. package/dist/extensions/forgecli/config-tui/state/buffer.js.map +1 -1
  86. package/dist/extensions/forgecli/config-tui/state/constants.js.map +1 -1
  87. package/dist/extensions/forgecli/config-tui/state/index.d.ts +3 -3
  88. package/dist/extensions/forgecli/config-tui/state/index.js +2 -2
  89. package/dist/extensions/forgecli/config-tui/state/index.js.map +1 -1
  90. package/dist/extensions/forgecli/config-tui/state/init.js +1 -0
  91. package/dist/extensions/forgecli/config-tui/state/init.js.map +1 -1
  92. package/dist/extensions/forgecli/config-tui/state/model.d.ts +4 -0
  93. package/dist/extensions/forgecli/config-tui/state/reducer.js +2 -4
  94. package/dist/extensions/forgecli/config-tui/state/reducer.js.map +1 -1
  95. package/dist/extensions/forgecli/config-tui/state/selectors.d.ts +1 -1
  96. package/dist/extensions/forgecli/config-tui/state/selectors.js +7 -6
  97. package/dist/extensions/forgecli/config-tui/state/selectors.js.map +1 -1
  98. package/dist/extensions/forgecli/config-tui/state.d.ts +3 -3
  99. package/dist/extensions/forgecli/config-tui/state.js +2 -2
  100. package/dist/extensions/forgecli/config-tui/state.js.map +1 -1
  101. package/dist/extensions/forgecli/config-tui/theme.js +1 -1
  102. package/dist/extensions/forgecli/config-tui/theme.js.map +1 -1
  103. package/dist/extensions/forgecli/config-tui/tier-meta.js.map +1 -1
  104. package/dist/extensions/forgecli/config-writer.js +4 -2
  105. package/dist/extensions/forgecli/config-writer.js.map +1 -1
  106. package/dist/extensions/forgecli/enhance.d.ts +4 -6
  107. package/dist/extensions/forgecli/enhance.js +9 -74
  108. package/dist/extensions/forgecli/enhance.js.map +1 -1
  109. package/dist/extensions/forgecli/fix-bug.d.ts +4 -1
  110. package/dist/extensions/forgecli/fix-bug.js +202 -100
  111. package/dist/extensions/forgecli/fix-bug.js.map +1 -1
  112. package/dist/extensions/forgecli/forge-artifact-tool.d.ts +9 -0
  113. package/dist/extensions/forgecli/forge-artifact-tool.js +255 -0
  114. package/dist/extensions/forgecli/forge-artifact-tool.js.map +1 -0
  115. package/dist/extensions/forgecli/forge-commands.js.map +1 -1
  116. package/dist/extensions/forgecli/forge-header.d.ts +1 -1
  117. package/dist/extensions/forgecli/forge-header.js +1 -1
  118. package/dist/extensions/forgecli/forge-header.js.map +1 -1
  119. package/dist/extensions/forgecli/forge-init/phase-descriptors.d.ts +72 -0
  120. package/dist/extensions/forgecli/forge-init/phase-descriptors.js +359 -0
  121. package/dist/extensions/forgecli/forge-init/phase-descriptors.js.map +1 -0
  122. package/dist/extensions/forgecli/forge-init/phase4-register.d.ts +20 -0
  123. package/dist/extensions/forgecli/forge-init/phase4-register.js +353 -0
  124. package/dist/extensions/forgecli/forge-init/phase4-register.js.map +1 -0
  125. package/dist/extensions/forgecli/forge-init/prompts.d.ts +10 -0
  126. package/dist/extensions/forgecli/forge-init/prompts.js +91 -0
  127. package/dist/extensions/forgecli/forge-init/prompts.js.map +1 -0
  128. package/dist/extensions/forgecli/forge-init/verifiers.d.ts +20 -0
  129. package/dist/extensions/forgecli/forge-init/verifiers.js +81 -0
  130. package/dist/extensions/forgecli/forge-init/verifiers.js.map +1 -0
  131. package/dist/extensions/forgecli/forge-init.js +107 -751
  132. package/dist/extensions/forgecli/forge-init.js.map +1 -1
  133. package/dist/extensions/forgecli/forge-root.d.ts +0 -1
  134. package/dist/extensions/forgecli/forge-root.js +1 -11
  135. package/dist/extensions/forgecli/forge-root.js.map +1 -1
  136. package/dist/extensions/forgecli/forge-subagent.d.ts +11 -1
  137. package/dist/extensions/forgecli/forge-subagent.js +9 -2
  138. package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
  139. package/dist/extensions/forgecli/forge-tools.d.ts +27 -7
  140. package/dist/extensions/forgecli/forge-tools.js +116 -71
  141. package/dist/extensions/forgecli/forge-tools.js.map +1 -1
  142. package/dist/extensions/forgecli/forge-update-command.d.ts +32 -11
  143. package/dist/extensions/forgecli/forge-update-command.js +207 -150
  144. package/dist/extensions/forgecli/forge-update-command.js.map +1 -1
  145. package/dist/extensions/forgecli/friction-emit.d.ts +4 -2
  146. package/dist/extensions/forgecli/friction-emit.js +15 -16
  147. package/dist/extensions/forgecli/friction-emit.js.map +1 -1
  148. package/dist/extensions/forgecli/health-check.js +11 -7
  149. package/dist/extensions/forgecli/health-check.js.map +1 -1
  150. package/dist/extensions/forgecli/hook-dispatcher.d.ts +1 -0
  151. package/dist/extensions/forgecli/hook-dispatcher.js +7 -2
  152. package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
  153. package/dist/extensions/forgecli/hooks/check-update.js.map +1 -1
  154. package/dist/extensions/forgecli/hooks/forge-permissions.js.map +1 -1
  155. package/dist/extensions/forgecli/hooks/post-init-hook.js +2 -2
  156. package/dist/extensions/forgecli/hooks/post-init-hook.js.map +1 -1
  157. package/dist/extensions/forgecli/hooks/post-sprint-hook.js +2 -2
  158. package/dist/extensions/forgecli/hooks/post-sprint-hook.js.map +1 -1
  159. package/dist/extensions/forgecli/hooks/write-guard.js +6 -4
  160. package/dist/extensions/forgecli/hooks/write-guard.js.map +1 -1
  161. package/dist/extensions/forgecli/implement.d.ts +4 -6
  162. package/dist/extensions/forgecli/implement.js +8 -73
  163. package/dist/extensions/forgecli/implement.js.map +1 -1
  164. package/dist/extensions/forgecli/index.js +59 -76
  165. package/dist/extensions/forgecli/index.js.map +1 -1
  166. package/dist/extensions/forgecli/input-router.js +4 -1
  167. package/dist/extensions/forgecli/input-router.js.map +1 -1
  168. package/dist/extensions/forgecli/lib/catalog-helpers.d.ts +13 -0
  169. package/dist/extensions/forgecli/lib/catalog-helpers.js +52 -0
  170. package/dist/extensions/forgecli/lib/catalog-helpers.js.map +1 -0
  171. package/dist/extensions/forgecli/lib/catalog-loader.d.ts +46 -0
  172. package/dist/extensions/forgecli/lib/catalog-loader.js +176 -0
  173. package/dist/extensions/forgecli/lib/catalog-loader.js.map +1 -0
  174. package/dist/extensions/forgecli/lib/catalog-types.d.ts +16 -0
  175. package/dist/extensions/forgecli/lib/catalog-types.js +156 -0
  176. package/dist/extensions/forgecli/lib/catalog-types.js.map +1 -0
  177. package/dist/extensions/forgecli/lib/exec-helpers.d.ts +25 -0
  178. package/dist/extensions/forgecli/lib/exec-helpers.js +52 -0
  179. package/dist/extensions/forgecli/lib/exec-helpers.js.map +1 -0
  180. package/dist/extensions/forgecli/lib/forge-config.d.ts +20 -0
  181. package/dist/extensions/forgecli/lib/forge-config.js +43 -0
  182. package/dist/extensions/forgecli/lib/forge-config.js.map +1 -0
  183. package/dist/extensions/forgecli/lib/frontmatter-parser.d.ts +13 -0
  184. package/dist/extensions/forgecli/lib/frontmatter-parser.js +56 -0
  185. package/dist/extensions/forgecli/lib/frontmatter-parser.js.map +1 -0
  186. package/dist/extensions/forgecli/lib/manifest-checker.d.ts +22 -0
  187. package/dist/extensions/forgecli/lib/manifest-checker.js +64 -0
  188. package/dist/extensions/forgecli/lib/manifest-checker.js.map +1 -0
  189. package/dist/extensions/forgecli/lib/orchestrator-preflight.d.ts +46 -0
  190. package/dist/extensions/forgecli/lib/orchestrator-preflight.js +64 -0
  191. package/dist/extensions/forgecli/lib/orchestrator-preflight.js.map +1 -0
  192. package/dist/extensions/forgecli/lib/orchestrator-types.d.ts +20 -0
  193. package/dist/extensions/forgecli/lib/orchestrator-types.js +14 -0
  194. package/dist/extensions/forgecli/lib/orchestrator-types.js.map +1 -0
  195. package/dist/extensions/forgecli/lib/parsers.d.ts +25 -0
  196. package/dist/extensions/forgecli/lib/parsers.js +164 -0
  197. package/dist/extensions/forgecli/lib/parsers.js.map +1 -0
  198. package/dist/extensions/forgecli/lib/shared-fs-utils.d.ts +12 -0
  199. package/dist/extensions/forgecli/lib/shared-fs-utils.js +37 -0
  200. package/dist/extensions/forgecli/lib/shared-fs-utils.js.map +1 -0
  201. package/dist/extensions/forgecli/lib/spawn-store-cli.d.ts +44 -0
  202. package/dist/extensions/forgecli/lib/spawn-store-cli.js +103 -0
  203. package/dist/extensions/forgecli/lib/spawn-store-cli.js.map +1 -0
  204. package/dist/extensions/forgecli/lib/state-helpers.d.ts +33 -0
  205. package/dist/extensions/forgecli/lib/state-helpers.js +69 -0
  206. package/dist/extensions/forgecli/lib/state-helpers.js.map +1 -0
  207. package/dist/extensions/forgecli/lib/store-cli-timeouts.d.ts +4 -0
  208. package/dist/extensions/forgecli/lib/store-cli-timeouts.js +10 -0
  209. package/dist/extensions/forgecli/lib/store-cli-timeouts.js.map +1 -0
  210. package/dist/extensions/forgecli/lib/versions.d.ts +56 -0
  211. package/dist/extensions/forgecli/lib/versions.js +116 -0
  212. package/dist/extensions/forgecli/lib/versions.js.map +1 -0
  213. package/dist/extensions/forgecli/loaders/persona-skill-loader.js +2 -2
  214. package/dist/extensions/forgecli/loaders/persona-skill-loader.js.map +1 -1
  215. package/dist/extensions/forgecli/materialize.js.map +1 -1
  216. package/dist/extensions/forgecli/migrate.js +1 -1
  217. package/dist/extensions/forgecli/migrate.js.map +1 -1
  218. package/dist/extensions/forgecli/migration-engine.d.ts +6 -0
  219. package/dist/extensions/forgecli/migration-engine.js +62 -45
  220. package/dist/extensions/forgecli/migration-engine.js.map +1 -1
  221. package/dist/extensions/forgecli/model-resolver.js.map +1 -1
  222. package/dist/extensions/forgecli/model-validator.js.map +1 -1
  223. package/dist/extensions/forgecli/parsers/persona-skill-loader.d.ts +45 -0
  224. package/dist/extensions/forgecli/parsers/persona-skill-loader.js +201 -0
  225. package/dist/extensions/forgecli/parsers/persona-skill-loader.js.map +1 -0
  226. package/dist/extensions/forgecli/parsers/workflow-loader.d.ts +41 -0
  227. package/dist/extensions/forgecli/parsers/workflow-loader.js +83 -0
  228. package/dist/extensions/forgecli/parsers/workflow-loader.js.map +1 -0
  229. package/dist/extensions/forgecli/paths/migrator.js +2 -7
  230. package/dist/extensions/forgecli/paths/migrator.js.map +1 -1
  231. package/dist/extensions/forgecli/plan.d.ts +4 -6
  232. package/dist/extensions/forgecli/plan.js +9 -73
  233. package/dist/extensions/forgecli/plan.js.map +1 -1
  234. package/dist/extensions/forgecli/quiz-agent.js.map +1 -1
  235. package/dist/extensions/forgecli/read-command.js +1 -1
  236. package/dist/extensions/forgecli/read-command.js.map +1 -1
  237. package/dist/extensions/forgecli/regenerate.js +1 -3
  238. package/dist/extensions/forgecli/regenerate.js.map +1 -1
  239. package/dist/extensions/forgecli/remove-command.js.map +1 -1
  240. package/dist/extensions/forgecli/report-bug.js +2 -2
  241. package/dist/extensions/forgecli/report-bug.js.map +1 -1
  242. package/dist/extensions/forgecli/retrospective.d.ts +2 -1
  243. package/dist/extensions/forgecli/retrospective.js +6 -36
  244. package/dist/extensions/forgecli/retrospective.js.map +1 -1
  245. package/dist/extensions/forgecli/review-code.d.ts +4 -6
  246. package/dist/extensions/forgecli/review-code.js +8 -73
  247. package/dist/extensions/forgecli/review-code.js.map +1 -1
  248. package/dist/extensions/forgecli/review-plan.d.ts +4 -6
  249. package/dist/extensions/forgecli/review-plan.js +8 -73
  250. package/dist/extensions/forgecli/review-plan.js.map +1 -1
  251. package/dist/extensions/forgecli/review-server.js +3 -5
  252. package/dist/extensions/forgecli/review-server.js.map +1 -1
  253. package/dist/extensions/forgecli/run-sprint.d.ts +3 -1
  254. package/dist/extensions/forgecli/run-sprint.js +74 -67
  255. package/dist/extensions/forgecli/run-sprint.js.map +1 -1
  256. package/dist/extensions/forgecli/run-task.d.ts +3 -0
  257. package/dist/extensions/forgecli/run-task.js +136 -105
  258. package/dist/extensions/forgecli/run-task.js.map +1 -1
  259. package/dist/extensions/forgecli/session-registry.js.map +1 -1
  260. package/dist/extensions/forgecli/skill-curation-flag.js +5 -5
  261. package/dist/extensions/forgecli/skill-curation-flag.js.map +1 -1
  262. package/dist/extensions/forgecli/skill-curator-subagent.js +4 -8
  263. package/dist/extensions/forgecli/skill-curator-subagent.js.map +1 -1
  264. package/dist/extensions/forgecli/skill-retriever.js +5 -5
  265. package/dist/extensions/forgecli/skill-retriever.js.map +1 -1
  266. package/dist/extensions/forgecli/skill-usage-tracker.js +5 -5
  267. package/dist/extensions/forgecli/skill-usage-tracker.js.map +1 -1
  268. package/dist/extensions/forgecli/status-command.js.map +1 -1
  269. package/dist/extensions/forgecli/store-error-remediation.d.ts +65 -0
  270. package/dist/extensions/forgecli/store-error-remediation.js +307 -0
  271. package/dist/extensions/forgecli/store-error-remediation.js.map +1 -0
  272. package/dist/extensions/forgecli/store-query.js.map +1 -1
  273. package/dist/extensions/forgecli/store-repair.js.map +1 -1
  274. package/dist/extensions/forgecli/store-resolver.js +4 -13
  275. package/dist/extensions/forgecli/store-resolver.js.map +1 -1
  276. package/dist/extensions/forgecli/store-validator.js +6 -11
  277. package/dist/extensions/forgecli/store-validator.js.map +1 -1
  278. package/dist/extensions/forgecli/subagent/agents.d.ts +4 -0
  279. package/dist/extensions/forgecli/subagent/agents.js +5 -8
  280. package/dist/extensions/forgecli/subagent/agents.js.map +1 -1
  281. package/dist/extensions/forgecli/subagent/index.js +1 -1
  282. package/dist/extensions/forgecli/subagent/index.js.map +1 -1
  283. package/dist/extensions/forgecli/test-orchestrate.js +1 -1
  284. package/dist/extensions/forgecli/test-orchestrate.js.map +1 -1
  285. package/dist/extensions/forgecli/thread-switcher.js +8 -18
  286. package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
  287. package/dist/extensions/forgecli/transition-guard.js +20 -61
  288. package/dist/extensions/forgecli/transition-guard.js.map +1 -1
  289. package/dist/extensions/forgecli/update-tools.js +1 -2
  290. package/dist/extensions/forgecli/update-tools.js.map +1 -1
  291. package/dist/extensions/forgecli/validate.d.ts +4 -6
  292. package/dist/extensions/forgecli/validate.js +8 -73
  293. package/dist/extensions/forgecli/validate.js.map +1 -1
  294. package/dist/extensions/forgecli/viewport-events.js +2 -2
  295. package/dist/extensions/forgecli/viewport-events.js.map +1 -1
  296. package/dist/extensions/forgecli/wf-engine/engine.d.ts +1 -1
  297. package/dist/extensions/forgecli/wf-engine/engine.js +52 -32
  298. package/dist/extensions/forgecli/wf-engine/engine.js.map +1 -1
  299. package/dist/extensions/forgecli/wf-engine/event-parser.js.map +1 -1
  300. package/dist/extensions/forgecli/wf-engine/id-gen.js +4 -1
  301. package/dist/extensions/forgecli/wf-engine/id-gen.js.map +1 -1
  302. package/dist/extensions/forgecli/wf-engine/loader.d.ts +1 -1
  303. package/dist/extensions/forgecli/wf-engine/loader.js +8 -8
  304. package/dist/extensions/forgecli/wf-engine/loader.js.map +1 -1
  305. package/dist/extensions/forgecli/wf-engine/predicate.js +14 -7
  306. package/dist/extensions/forgecli/wf-engine/predicate.js.map +1 -1
  307. package/dist/extensions/forgecli/wf-engine/prompt-compiler.js.map +1 -1
  308. package/dist/extensions/forgecli/wf-engine/register.js +1 -1
  309. package/dist/extensions/forgecli/wf-engine/register.js.map +1 -1
  310. package/dist/extensions/forgecli/wf-engine/remit-check.js +3 -3
  311. package/dist/extensions/forgecli/wf-engine/remit-check.js.map +1 -1
  312. package/dist/extensions/forgecli/wf-engine/state-store.js +7 -3
  313. package/dist/extensions/forgecli/wf-engine/state-store.js.map +1 -1
  314. package/dist/extensions/forgecli/wf-engine/worker.js +3 -3
  315. package/dist/extensions/forgecli/wf-engine/worker.js.map +1 -1
  316. package/dist/extensions/forgecli/whats-new-widget.js +8 -6
  317. package/dist/extensions/forgecli/whats-new-widget.js.map +1 -1
  318. package/dist/extensions/forgecli/whats-new.js +1 -2
  319. package/dist/extensions/forgecli/whats-new.js.map +1 -1
  320. package/dist/forge-payload/.base-pack/skills/architect-skills.md +1 -0
  321. package/dist/forge-payload/.base-pack/skills/bug-fixer-skills.md +1 -0
  322. package/dist/forge-payload/.base-pack/skills/collator-skills.md +1 -0
  323. package/dist/forge-payload/.base-pack/skills/engineer-skills.md +1 -0
  324. package/dist/forge-payload/.base-pack/skills/generic-skills.md +1 -0
  325. package/dist/forge-payload/.base-pack/skills/qa-engineer-skills.md +1 -0
  326. package/dist/forge-payload/.base-pack/skills/supervisor-skills.md +1 -0
  327. package/dist/forge-payload/.base-pack/workflows/_fragments/generation-instructions.md +81 -0
  328. package/dist/forge-payload/.base-pack/workflows/_fragments/iron-laws.md +72 -0
  329. package/dist/forge-payload/.base-pack/workflows/_fragments/store-cli-verbs.md +11 -1
  330. package/dist/forge-payload/.base-pack/workflows/_fragments/store-write-verification.md +11 -0
  331. package/dist/forge-payload/.base-pack/workflows/architect_approve.md +11 -12
  332. package/dist/forge-payload/.base-pack/workflows/architect_review_sprint_completion.md +4 -1
  333. package/dist/forge-payload/.base-pack/workflows/architect_sprint_intake.md +10 -1
  334. package/dist/forge-payload/.base-pack/workflows/architect_sprint_plan.md +8 -1
  335. package/dist/forge-payload/.base-pack/workflows/collator_agent.md +18 -1
  336. package/dist/forge-payload/.base-pack/workflows/commit_task.md +5 -10
  337. package/dist/forge-payload/.base-pack/workflows/enhance.md +7 -0
  338. package/dist/forge-payload/.base-pack/workflows/fix_bug.md +9 -2
  339. package/dist/forge-payload/.base-pack/workflows/implement_plan.md +22 -35
  340. package/dist/forge-payload/.base-pack/workflows/migrate_structural.md +9 -0
  341. package/dist/forge-payload/.base-pack/workflows/orchestrate_task.md +4 -0
  342. package/dist/forge-payload/.base-pack/workflows/plan_task.md +17 -21
  343. package/dist/forge-payload/.base-pack/workflows/review_code.md +13 -20
  344. package/dist/forge-payload/.base-pack/workflows/review_plan.md +10 -21
  345. package/dist/forge-payload/.base-pack/workflows/sprint_retrospective.md +10 -1
  346. package/dist/forge-payload/.base-pack/workflows/update_implementation.md +5 -10
  347. package/dist/forge-payload/.base-pack/workflows/update_plan.md +5 -10
  348. package/dist/forge-payload/.base-pack/workflows/validate_task.md +11 -12
  349. package/dist/forge-payload/.claude-plugin/plugin.json +5 -5
  350. package/dist/forge-payload/.schemas/_defs/phaseSummary.schema.json +18 -0
  351. package/dist/forge-payload/.schemas/bug.schema.json +8 -24
  352. package/dist/forge-payload/.schemas/config.schema.json +165 -33
  353. package/dist/forge-payload/.schemas/enum-catalog.json +71 -0
  354. package/dist/forge-payload/.schemas/migrations.json +371 -149
  355. package/dist/forge-payload/.schemas/task.schema.json +6 -21
  356. package/dist/forge-payload/.schemas/transitions/bug.json +31 -0
  357. package/dist/forge-payload/.schemas/transitions/sprint.json +46 -0
  358. package/dist/forge-payload/.schemas/transitions/task.json +109 -0
  359. package/dist/forge-payload/commands/health.md +3 -3
  360. package/dist/forge-payload/hooks/check-update.cjs +255 -0
  361. package/dist/forge-payload/hooks/forge-permissions.cjs +171 -0
  362. package/dist/forge-payload/hooks/forge-permissions.js +6 -0
  363. package/dist/forge-payload/hooks/post-init.cjs +120 -0
  364. package/dist/forge-payload/hooks/post-sprint.cjs +108 -0
  365. package/dist/forge-payload/hooks/triage-error.cjs +104 -0
  366. package/dist/forge-payload/hooks/triage-error.js +6 -0
  367. package/dist/forge-payload/hooks/validate-write.cjs +250 -0
  368. package/dist/forge-payload/hooks/validate-write.js +25 -11
  369. package/dist/forge-payload/integrity.json +13 -7
  370. package/dist/forge-payload/meta/workflows/_fragments/generation-instructions.md +81 -0
  371. package/dist/forge-payload/meta/workflows/_fragments/iron-laws.md +72 -0
  372. package/dist/forge-payload/meta/workflows/_fragments/store-cli-verbs.md +11 -1
  373. package/dist/forge-payload/meta/workflows/_fragments/store-write-verification.md +11 -0
  374. package/dist/forge-payload/meta/workflows/meta-approve.md +9 -11
  375. package/dist/forge-payload/meta/workflows/meta-collate.md +16 -0
  376. package/dist/forge-payload/meta/workflows/meta-commit.md +3 -9
  377. package/dist/forge-payload/meta/workflows/meta-enhance.md +16 -1
  378. package/dist/forge-payload/meta/workflows/meta-fix-bug.md +8 -2
  379. package/dist/forge-payload/meta/workflows/meta-implement.md +20 -35
  380. package/dist/forge-payload/meta/workflows/meta-migrate.md +18 -0
  381. package/dist/forge-payload/meta/workflows/meta-orchestrate.md +2 -0
  382. package/dist/forge-payload/meta/workflows/meta-plan-task.md +15 -21
  383. package/dist/forge-payload/meta/workflows/meta-quiz-agent.md +4 -1
  384. package/dist/forge-payload/meta/workflows/meta-retrospective.md +8 -0
  385. package/dist/forge-payload/meta/workflows/meta-review-implementation.md +11 -19
  386. package/dist/forge-payload/meta/workflows/meta-review-plan.md +10 -16
  387. package/dist/forge-payload/meta/workflows/meta-review-sprint-completion.md +3 -0
  388. package/dist/forge-payload/meta/workflows/meta-sprint-intake.md +8 -0
  389. package/dist/forge-payload/meta/workflows/meta-sprint-plan.md +5 -0
  390. package/dist/forge-payload/meta/workflows/meta-update-implementation.md +3 -9
  391. package/dist/forge-payload/meta/workflows/meta-update-plan.md +3 -9
  392. package/dist/forge-payload/meta/workflows/meta-validate.md +9 -11
  393. package/dist/forge-payload/schemas/structure-manifest.json +8 -6
  394. package/dist/forge-payload/tools/build-context-pack.cjs +3 -2
  395. package/dist/forge-payload/tools/friction-emit.cjs +2 -1
  396. package/dist/forge-payload/tools/lib/frontmatter.cjs +62 -0
  397. package/dist/forge-payload/tools/lib/fsutil.cjs +61 -0
  398. package/dist/forge-payload/tools/lib/json-io.cjs +43 -0
  399. package/dist/forge-payload/tools/lib/schema-loader.cjs +139 -0
  400. package/dist/forge-payload/tools/lib/slug.cjs +39 -0
  401. package/dist/forge-payload/tools/lib/store-facade.cjs +6 -5
  402. package/dist/forge-payload/tools/preflight-gate.cjs +55 -7
  403. package/dist/forge-payload/tools/seed-store.cjs +1 -13
  404. package/dist/forge-payload/tools/store-cli.cjs +55 -108
  405. package/dist/forge-payload/tools/store.cjs +26 -37
  406. package/dist/forge-payload/tools/substitute-placeholders.cjs +74 -35
  407. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts +1 -1
  408. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  409. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +23 -0
  410. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  411. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +2 -2
  412. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  413. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +1 -1
  414. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  415. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.d.ts +2 -2
  416. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
  417. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
  418. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.d.ts +5 -5
  419. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
  420. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.js.map +1 -1
  421. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts +4 -4
  422. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts.map +1 -1
  423. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js.map +1 -1
  424. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/utils.d.ts +1 -1
  425. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/utils.d.ts.map +1 -1
  426. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/utils.js.map +1 -1
  427. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -1
  428. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  429. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  430. package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.d.ts +4 -0
  431. package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.d.ts.map +1 -0
  432. package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.js +3 -0
  433. package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.js.map +1 -0
  434. package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.d.ts +2 -2
  435. package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.d.ts.map +1 -1
  436. package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.js.map +1 -1
  437. package/node_modules/@earendil-works/pi-agent-core/dist/harness/prompt-templates.d.ts +1 -1
  438. package/node_modules/@earendil-works/pi-agent-core/dist/harness/prompt-templates.d.ts.map +1 -1
  439. package/node_modules/@earendil-works/pi-agent-core/dist/harness/prompt-templates.js.map +1 -1
  440. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-repo.d.ts +1 -1
  441. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-repo.d.ts.map +1 -1
  442. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-repo.js.map +1 -1
  443. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-storage.d.ts +1 -1
  444. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-storage.d.ts.map +1 -1
  445. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-storage.js.map +1 -1
  446. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/memory-repo.d.ts +1 -1
  447. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/memory-repo.d.ts.map +1 -1
  448. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/memory-repo.js.map +1 -1
  449. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/memory-storage.d.ts +1 -1
  450. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/memory-storage.d.ts.map +1 -1
  451. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/memory-storage.js.map +1 -1
  452. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.d.ts +20 -0
  453. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.d.ts.map +1 -0
  454. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.js +92 -0
  455. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.js.map +1 -0
  456. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.d.ts +18 -0
  457. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.d.ts.map +1 -0
  458. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.js +42 -0
  459. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.js.map +1 -0
  460. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.d.ts +10 -0
  461. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.d.ts.map +1 -0
  462. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.js +31 -0
  463. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.js.map +1 -0
  464. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo-utils.d.ts +2 -2
  465. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo-utils.d.ts.map +1 -1
  466. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo-utils.js.map +1 -1
  467. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts +2 -2
  468. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts.map +1 -1
  469. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js.map +1 -1
  470. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.d.ts +30 -0
  471. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.d.ts.map +1 -0
  472. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.js +170 -0
  473. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.js.map +1 -0
  474. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.d.ts +26 -0
  475. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.d.ts.map +1 -0
  476. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.js +90 -0
  477. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.js.map +1 -0
  478. package/node_modules/@earendil-works/pi-agent-core/dist/harness/skills.d.ts +1 -1
  479. package/node_modules/@earendil-works/pi-agent-core/dist/harness/skills.d.ts.map +1 -1
  480. package/node_modules/@earendil-works/pi-agent-core/dist/harness/skills.js.map +1 -1
  481. package/node_modules/@earendil-works/pi-agent-core/dist/harness/system-prompt.d.ts +1 -1
  482. package/node_modules/@earendil-works/pi-agent-core/dist/harness/system-prompt.d.ts.map +1 -1
  483. package/node_modules/@earendil-works/pi-agent-core/dist/harness/system-prompt.js.map +1 -1
  484. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts +10 -22
  485. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  486. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js +17 -23
  487. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js.map +1 -1
  488. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.d.ts +1 -1
  489. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.d.ts.map +1 -1
  490. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.js.map +1 -1
  491. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +19 -19
  492. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
  493. package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
  494. package/node_modules/@earendil-works/pi-agent-core/dist/node.d.ts +2 -2
  495. package/node_modules/@earendil-works/pi-agent-core/dist/node.d.ts.map +1 -1
  496. package/node_modules/@earendil-works/pi-agent-core/dist/node.js.map +1 -1
  497. package/node_modules/@earendil-works/pi-agent-core/package.json +9 -10
  498. package/node_modules/@earendil-works/pi-ai/dist/api-registry.d.ts +1 -1
  499. package/node_modules/@earendil-works/pi-ai/dist/api-registry.d.ts.map +1 -1
  500. package/node_modules/@earendil-works/pi-ai/dist/api-registry.js.map +1 -1
  501. package/node_modules/@earendil-works/pi-ai/dist/bedrock-provider.d.ts +2 -2
  502. package/node_modules/@earendil-works/pi-ai/dist/bedrock-provider.d.ts.map +1 -1
  503. package/node_modules/@earendil-works/pi-ai/dist/bedrock-provider.js.map +1 -1
  504. package/node_modules/@earendil-works/pi-ai/dist/cli.d.ts.map +1 -1
  505. package/node_modules/@earendil-works/pi-ai/dist/cli.js +14 -0
  506. package/node_modules/@earendil-works/pi-ai/dist/cli.js.map +1 -1
  507. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts +1 -1
  508. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  509. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +10 -2
  510. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
  511. package/node_modules/@earendil-works/pi-ai/dist/image-models.d.ts +2 -2
  512. package/node_modules/@earendil-works/pi-ai/dist/image-models.d.ts.map +1 -1
  513. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  514. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  515. package/node_modules/@earendil-works/pi-ai/dist/image-models.js.map +1 -1
  516. package/node_modules/@earendil-works/pi-ai/dist/images-api-registry.d.ts +1 -1
  517. package/node_modules/@earendil-works/pi-ai/dist/images-api-registry.d.ts.map +1 -1
  518. package/node_modules/@earendil-works/pi-ai/dist/images-api-registry.js.map +1 -1
  519. package/node_modules/@earendil-works/pi-ai/dist/images.d.ts +2 -2
  520. package/node_modules/@earendil-works/pi-ai/dist/images.d.ts.map +1 -1
  521. package/node_modules/@earendil-works/pi-ai/dist/images.js.map +1 -1
  522. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +29 -29
  523. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  524. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  525. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +2 -2
  526. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  527. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +317 -509
  528. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  529. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +400 -620
  530. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
  531. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  532. package/node_modules/@earendil-works/pi-ai/dist/oauth.d.ts +1 -1
  533. package/node_modules/@earendil-works/pi-ai/dist/oauth.d.ts.map +1 -1
  534. package/node_modules/@earendil-works/pi-ai/dist/oauth.js.map +1 -1
  535. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts +1 -1
  536. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  537. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +5 -2
  538. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  539. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts +23 -6
  540. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  541. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +11 -23
  542. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
  543. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.d.ts +1 -1
  544. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  545. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +2 -1
  546. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  547. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare.d.ts +1 -1
  548. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare.d.ts.map +1 -1
  549. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare.js.map +1 -1
  550. package/node_modules/@earendil-works/pi-ai/dist/providers/faux.d.ts +1 -1
  551. package/node_modules/@earendil-works/pi-ai/dist/providers/faux.d.ts.map +1 -1
  552. package/node_modules/@earendil-works/pi-ai/dist/providers/faux.js.map +1 -1
  553. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot-headers.d.ts +1 -1
  554. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot-headers.d.ts.map +1 -1
  555. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot-headers.js.map +1 -1
  556. package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.d.ts +1 -1
  557. package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  558. package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.js.map +1 -1
  559. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.d.ts +2 -2
  560. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.d.ts.map +1 -1
  561. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js.map +1 -1
  562. package/node_modules/@earendil-works/pi-ai/dist/providers/google.d.ts +2 -2
  563. package/node_modules/@earendil-works/pi-ai/dist/providers/google.d.ts.map +1 -1
  564. package/node_modules/@earendil-works/pi-ai/dist/providers/google.js.map +1 -1
  565. package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.d.ts +1 -1
  566. package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.d.ts.map +1 -1
  567. package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.js.map +1 -1
  568. package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.d.ts +1 -1
  569. package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.d.ts.map +1 -1
  570. package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.js.map +1 -1
  571. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.d.ts +1 -1
  572. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.d.ts.map +1 -1
  573. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.js.map +1 -1
  574. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.d.ts +1 -1
  575. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  576. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +12 -3
  577. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  578. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts +1 -1
  579. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  580. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +2 -1
  581. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js.map +1 -1
  582. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-prompt-cache.d.ts +3 -0
  583. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-prompt-cache.d.ts.map +1 -0
  584. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-prompt-cache.js +10 -0
  585. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-prompt-cache.js.map +1 -0
  586. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.d.ts +2 -2
  587. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
  588. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
  589. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.d.ts +1 -1
  590. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  591. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +2 -1
  592. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js.map +1 -1
  593. package/node_modules/@earendil-works/pi-ai/dist/providers/register-builtins.d.ts +10 -10
  594. package/node_modules/@earendil-works/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  595. package/node_modules/@earendil-works/pi-ai/dist/providers/register-builtins.js +13 -2
  596. package/node_modules/@earendil-works/pi-ai/dist/providers/register-builtins.js.map +1 -1
  597. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts +3 -3
  598. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  599. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +6 -11
  600. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js.map +1 -1
  601. package/node_modules/@earendil-works/pi-ai/dist/providers/transform-messages.d.ts +1 -1
  602. package/node_modules/@earendil-works/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  603. package/node_modules/@earendil-works/pi-ai/dist/providers/transform-messages.js.map +1 -1
  604. package/node_modules/@earendil-works/pi-ai/dist/stream.d.ts +3 -3
  605. package/node_modules/@earendil-works/pi-ai/dist/stream.d.ts.map +1 -1
  606. package/node_modules/@earendil-works/pi-ai/dist/stream.js.map +1 -1
  607. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +13 -3
  608. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  609. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  610. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.d.ts +3 -3
  611. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.d.ts.map +1 -1
  612. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js +2 -2
  613. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js.map +1 -1
  614. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/anthropic.d.ts +1 -1
  615. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/anthropic.d.ts.map +1 -1
  616. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/anthropic.js.map +1 -1
  617. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts +19 -0
  618. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts.map +1 -0
  619. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.js +55 -0
  620. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.js.map +1 -0
  621. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.d.ts +3 -3
  622. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  623. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js +45 -69
  624. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  625. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts +6 -5
  626. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts.map +1 -1
  627. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js +1 -0
  628. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js.map +1 -1
  629. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts +1 -1
  630. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +1 -1
  631. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js +1 -1
  632. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js.map +1 -1
  633. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/types.d.ts +9 -2
  634. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/types.d.ts.map +1 -1
  635. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/types.js.map +1 -1
  636. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +1 -1
  637. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  638. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  639. package/node_modules/@earendil-works/pi-ai/dist/utils/validation.d.ts +1 -1
  640. package/node_modules/@earendil-works/pi-ai/dist/utils/validation.d.ts.map +1 -1
  641. package/node_modules/@earendil-works/pi-ai/dist/utils/validation.js.map +1 -1
  642. package/node_modules/@earendil-works/pi-ai/package.json +15 -16
  643. package/node_modules/@earendil-works/pi-coding-agent/CHANGELOG.md +55 -0
  644. package/node_modules/@earendil-works/pi-coding-agent/README.md +6 -4
  645. package/node_modules/@earendil-works/pi-coding-agent/dist/bun/cli.d.ts.map +1 -1
  646. package/node_modules/@earendil-works/pi-coding-agent/dist/bun/cli.js.map +1 -1
  647. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.d.ts +1 -1
  648. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
  649. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js.map +1 -1
  650. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/config-selector.d.ts +2 -2
  651. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/config-selector.d.ts.map +1 -1
  652. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/config-selector.js.map +1 -1
  653. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/file-processor.d.ts.map +1 -1
  654. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/file-processor.js.map +1 -1
  655. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/initial-message.d.ts +1 -1
  656. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/initial-message.d.ts.map +1 -1
  657. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/initial-message.js.map +1 -1
  658. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/list-models.d.ts +1 -1
  659. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/list-models.d.ts.map +1 -1
  660. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/list-models.js.map +1 -1
  661. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/session-picker.d.ts +1 -1
  662. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/session-picker.d.ts.map +1 -1
  663. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/session-picker.js.map +1 -1
  664. package/node_modules/@earendil-works/pi-coding-agent/dist/cli.d.ts.map +1 -1
  665. package/node_modules/@earendil-works/pi-coding-agent/dist/cli.js +4 -10
  666. package/node_modules/@earendil-works/pi-coding-agent/dist/cli.js.map +1 -1
  667. package/node_modules/@earendil-works/pi-coding-agent/dist/config.d.ts.map +1 -1
  668. package/node_modules/@earendil-works/pi-coding-agent/dist/config.js +13 -14
  669. package/node_modules/@earendil-works/pi-coding-agent/dist/config.js.map +1 -1
  670. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.d.ts +9 -9
  671. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.d.ts.map +1 -1
  672. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.js +6 -6
  673. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.js.map +1 -1
  674. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.d.ts +7 -7
  675. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.d.ts.map +1 -1
  676. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.js +3 -2
  677. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.js.map +1 -1
  678. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts +23 -21
  679. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  680. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +99 -137
  681. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  682. package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-guidance.d.ts.map +1 -1
  683. package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-guidance.js.map +1 -1
  684. package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-storage.d.ts +1 -1
  685. package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  686. package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-storage.js +3 -2
  687. package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  688. package/node_modules/@earendil-works/pi-coding-agent/dist/core/bash-executor.d.ts +1 -1
  689. package/node_modules/@earendil-works/pi-coding-agent/dist/core/bash-executor.d.ts.map +1 -1
  690. package/node_modules/@earendil-works/pi-coding-agent/dist/core/bash-executor.js.map +1 -1
  691. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts +3 -3
  692. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  693. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  694. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.d.ts +2 -2
  695. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  696. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  697. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/index.d.ts +3 -3
  698. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/index.d.ts.map +1 -1
  699. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/index.js.map +1 -1
  700. package/node_modules/@earendil-works/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
  701. package/node_modules/@earendil-works/pi-coding-agent/dist/core/exec.js.map +1 -1
  702. package/node_modules/@earendil-works/pi-coding-agent/dist/core/export-html/index.d.ts +1 -1
  703. package/node_modules/@earendil-works/pi-coding-agent/dist/core/export-html/index.d.ts.map +1 -1
  704. package/node_modules/@earendil-works/pi-coding-agent/dist/core/export-html/index.js +8 -6
  705. package/node_modules/@earendil-works/pi-coding-agent/dist/core/export-html/index.js.map +1 -1
  706. package/node_modules/@earendil-works/pi-coding-agent/dist/core/export-html/template.js +6 -3
  707. package/node_modules/@earendil-works/pi-coding-agent/dist/core/export-html/tool-renderer.d.ts +2 -2
  708. package/node_modules/@earendil-works/pi-coding-agent/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  709. package/node_modules/@earendil-works/pi-coding-agent/dist/core/export-html/tool-renderer.js.map +1 -1
  710. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/index.d.ts +8 -8
  711. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  712. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  713. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.d.ts +2 -2
  714. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  715. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js +12 -29
  716. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  717. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.d.ts +6 -6
  718. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  719. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  720. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.d.ts +19 -19
  721. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  722. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  723. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/wrapper.d.ts +2 -2
  724. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/wrapper.d.ts.map +1 -1
  725. package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/wrapper.js.map +1 -1
  726. package/node_modules/@earendil-works/pi-coding-agent/dist/core/footer-data-provider.d.ts.map +1 -1
  727. package/node_modules/@earendil-works/pi-coding-agent/dist/core/footer-data-provider.js.map +1 -1
  728. package/node_modules/@earendil-works/pi-coding-agent/dist/core/http-dispatcher.d.ts +21 -0
  729. package/node_modules/@earendil-works/pi-coding-agent/dist/core/http-dispatcher.d.ts.map +1 -0
  730. package/node_modules/@earendil-works/pi-coding-agent/dist/core/http-dispatcher.js +48 -0
  731. package/node_modules/@earendil-works/pi-coding-agent/dist/core/http-dispatcher.js.map +1 -0
  732. package/node_modules/@earendil-works/pi-coding-agent/dist/core/index.d.ts +8 -8
  733. package/node_modules/@earendil-works/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  734. package/node_modules/@earendil-works/pi-coding-agent/dist/core/index.js.map +1 -1
  735. package/node_modules/@earendil-works/pi-coding-agent/dist/core/keybindings.d.ts.map +1 -1
  736. package/node_modules/@earendil-works/pi-coding-agent/dist/core/keybindings.js.map +1 -1
  737. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.d.ts +4 -4
  738. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  739. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js +7 -3
  740. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  741. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.d.ts +1 -1
  742. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  743. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  744. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.d.ts +2 -1
  745. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  746. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js +48 -32
  747. package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  748. package/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.d.ts +1 -1
  749. package/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.d.ts.map +1 -1
  750. package/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.js +6 -20
  751. package/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.js.map +1 -1
  752. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.d.ts.map +1 -1
  753. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.js.map +1 -1
  754. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.d.ts +9 -9
  755. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  756. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js +38 -31
  757. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  758. package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.d.ts +13 -13
  759. package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  760. package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.js +9 -4
  761. package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.js.map +1 -1
  762. package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.d.ts +1 -1
  763. package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  764. package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.js +32 -24
  765. package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  766. package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  767. package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  768. package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js +26 -13
  769. package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  770. package/node_modules/@earendil-works/pi-coding-agent/dist/core/skills.d.ts +2 -2
  771. package/node_modules/@earendil-works/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  772. package/node_modules/@earendil-works/pi-coding-agent/dist/core/skills.js +8 -22
  773. package/node_modules/@earendil-works/pi-coding-agent/dist/core/skills.js.map +1 -1
  774. package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.d.ts +1 -1
  775. package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  776. package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  777. package/node_modules/@earendil-works/pi-coding-agent/dist/core/source-info.d.ts +1 -1
  778. package/node_modules/@earendil-works/pi-coding-agent/dist/core/source-info.d.ts.map +1 -1
  779. package/node_modules/@earendil-works/pi-coding-agent/dist/core/source-info.js.map +1 -1
  780. package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.d.ts +1 -1
  781. package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  782. package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js +1 -0
  783. package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  784. package/node_modules/@earendil-works/pi-coding-agent/dist/core/telemetry.d.ts +1 -1
  785. package/node_modules/@earendil-works/pi-coding-agent/dist/core/telemetry.d.ts.map +1 -1
  786. package/node_modules/@earendil-works/pi-coding-agent/dist/core/telemetry.js.map +1 -1
  787. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.d.ts +2 -2
  788. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  789. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.js +9 -3
  790. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  791. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit-diff.d.ts +3 -1
  792. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit-diff.d.ts.map +1 -1
  793. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit-diff.js +8 -1
  794. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit-diff.js.map +1 -1
  795. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.d.ts +5 -3
  796. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  797. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.js +3 -2
  798. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  799. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.d.ts +2 -2
  800. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  801. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  802. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.d.ts +2 -2
  803. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
  804. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  805. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/index.d.ts +17 -17
  806. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  807. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  808. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.d.ts +2 -2
  809. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
  810. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
  811. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/output-accumulator.d.ts +3 -1
  812. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/output-accumulator.d.ts.map +1 -1
  813. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/output-accumulator.js +9 -3
  814. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/output-accumulator.js.map +1 -1
  815. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/path-utils.d.ts.map +1 -1
  816. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/path-utils.js +3 -22
  817. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/path-utils.js.map +1 -1
  818. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.d.ts +2 -2
  819. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  820. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  821. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
  822. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
  823. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/tool-definition-wrapper.d.ts +1 -1
  824. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  825. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  826. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/truncate.d.ts.map +1 -1
  827. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/truncate.js +12 -2
  828. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/truncate.js.map +1 -1
  829. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.d.ts +1 -1
  830. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  831. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  832. package/node_modules/@earendil-works/pi-coding-agent/dist/index.d.ts +30 -29
  833. package/node_modules/@earendil-works/pi-coding-agent/dist/index.d.ts.map +1 -1
  834. package/node_modules/@earendil-works/pi-coding-agent/dist/index.js +2 -1
  835. package/node_modules/@earendil-works/pi-coding-agent/dist/index.js.map +1 -1
  836. package/node_modules/@earendil-works/pi-coding-agent/dist/main.d.ts +1 -1
  837. package/node_modules/@earendil-works/pi-coding-agent/dist/main.d.ts.map +1 -1
  838. package/node_modules/@earendil-works/pi-coding-agent/dist/main.js +7 -6
  839. package/node_modules/@earendil-works/pi-coding-agent/dist/main.js.map +1 -1
  840. package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.d.ts.map +1 -1
  841. package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.js.map +1 -1
  842. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/index.d.ts +5 -5
  843. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/index.d.ts.map +1 -1
  844. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/index.js.map +1 -1
  845. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/armin.d.ts.map +1 -1
  846. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/armin.js.map +1 -1
  847. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  848. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  849. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -1
  850. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  851. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
  852. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
  853. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  854. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  855. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
  856. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  857. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  858. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
  859. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  860. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  861. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts +2 -2
  862. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  863. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js +1 -1
  864. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
  865. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts +2 -2
  866. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  867. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js +2 -2
  868. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  869. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/custom-editor.d.ts +1 -1
  870. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  871. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/custom-editor.js.map +1 -1
  872. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/custom-message.d.ts +2 -2
  873. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  874. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/custom-message.js.map +1 -1
  875. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  876. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/daxnuts.js.map +1 -1
  877. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
  878. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
  879. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  880. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  881. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
  882. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
  883. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/extension-editor.d.ts +1 -1
  884. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  885. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/extension-editor.js.map +1 -1
  886. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  887. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
  888. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  889. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/extension-selector.js.map +1 -1
  890. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.d.ts +4 -3
  891. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  892. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.js +16 -7
  893. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  894. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/index.d.ts +31 -31
  895. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/index.d.ts.map +1 -1
  896. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/index.js.map +1 -1
  897. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  898. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  899. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +10 -2
  900. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  901. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +31 -6
  902. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  903. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +2 -2
  904. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  905. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
  906. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
  907. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  908. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  909. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  910. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  911. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
  912. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  913. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  914. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts +3 -3
  915. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  916. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
  917. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  918. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  919. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +15 -0
  920. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  921. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  922. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  923. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts +1 -1
  924. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  925. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  926. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  927. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/theme-selector.js.map +1 -1
  928. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  929. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  930. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +1 -1
  931. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  932. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  933. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tree-selector.d.ts +1 -1
  934. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  935. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tree-selector.js.map +1 -1
  936. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  937. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  938. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  939. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  940. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -3
  941. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  942. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +37 -14
  943. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  944. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  945. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  946. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js +37 -28
  947. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  948. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/print-mode.d.ts +1 -1
  949. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  950. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  951. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +5 -5
  952. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  953. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-client.js +1 -1
  954. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  955. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts +2 -2
  956. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  957. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  958. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +4 -4
  959. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  960. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  961. package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.d.ts.map +1 -1
  962. package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js +40 -1
  963. package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js.map +1 -1
  964. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.d.ts +1 -1
  965. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.d.ts.map +1 -1
  966. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js.map +1 -1
  967. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard-image.d.ts.map +1 -1
  968. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard-image.js.map +1 -1
  969. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard.d.ts.map +1 -1
  970. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard.js.map +1 -1
  971. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/exif-orientation.d.ts +1 -1
  972. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/exif-orientation.d.ts.map +1 -1
  973. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/exif-orientation.js.map +1 -1
  974. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-convert.d.ts.map +1 -1
  975. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-convert.js.map +1 -1
  976. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize.d.ts.map +1 -1
  977. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize.js.map +1 -1
  978. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/paths.d.ts +16 -1
  979. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/paths.d.ts.map +1 -1
  980. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/paths.js +49 -7
  981. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/paths.js.map +1 -1
  982. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  983. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/shell.js.map +1 -1
  984. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/syntax-highlight.d.ts.map +1 -1
  985. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/syntax-highlight.js.map +1 -1
  986. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/tools-manager.d.ts.map +1 -1
  987. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/tools-manager.js.map +1 -1
  988. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/version-check.d.ts +2 -1
  989. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/version-check.d.ts.map +1 -1
  990. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/version-check.js +9 -4
  991. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/version-check.js.map +1 -1
  992. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/windows-self-update.d.ts.map +1 -1
  993. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/windows-self-update.js.map +1 -1
  994. package/node_modules/@earendil-works/pi-coding-agent/docs/custom-provider.md +44 -12
  995. package/node_modules/@earendil-works/pi-coding-agent/docs/index.md +6 -4
  996. package/node_modules/@earendil-works/pi-coding-agent/docs/models.md +8 -2
  997. package/node_modules/@earendil-works/pi-coding-agent/docs/packages.md +5 -4
  998. package/node_modules/@earendil-works/pi-coding-agent/docs/quickstart.md +3 -1
  999. package/node_modules/@earendil-works/pi-coding-agent/docs/sdk.md +2 -0
  1000. package/node_modules/@earendil-works/pi-coding-agent/docs/termux.md +1 -1
  1001. package/node_modules/@earendil-works/pi-coding-agent/docs/usage.md +2 -2
  1002. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/package.json +2 -2
  1003. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  1004. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-gitlab-duo/test.ts +1 -1
  1005. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/doom-overlay/doom-component.ts +2 -2
  1006. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/doom-overlay/index.ts +3 -3
  1007. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/overlay-qa-tests.ts +97 -66
  1008. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/overlay-test.ts +7 -4
  1009. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/plan-mode/index.ts +1 -1
  1010. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/sandbox/package.json +2 -2
  1011. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/subagent/index.ts +1 -1
  1012. package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/with-deps/package.json +3 -3
  1013. package/node_modules/@earendil-works/pi-coding-agent/npm-shrinkwrap.json +1425 -0
  1014. package/node_modules/@earendil-works/pi-coding-agent/package.json +32 -31
  1015. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +1 -1
  1016. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +1 -1
  1017. package/node_modules/@earendil-works/pi-tui/dist/components/box.d.ts +1 -1
  1018. package/node_modules/@earendil-works/pi-tui/dist/components/box.d.ts.map +1 -1
  1019. package/node_modules/@earendil-works/pi-tui/dist/components/box.js.map +1 -1
  1020. package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.d.ts +1 -1
  1021. package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.d.ts.map +1 -1
  1022. package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.js.map +1 -1
  1023. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +3 -3
  1024. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  1025. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  1026. package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts +2 -2
  1027. package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts.map +1 -1
  1028. package/node_modules/@earendil-works/pi-tui/dist/components/image.js.map +1 -1
  1029. package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts +1 -1
  1030. package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts.map +1 -1
  1031. package/node_modules/@earendil-works/pi-tui/dist/components/input.js.map +1 -1
  1032. package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts +5 -5
  1033. package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts.map +1 -1
  1034. package/node_modules/@earendil-works/pi-tui/dist/components/loader.js +4 -4
  1035. package/node_modules/@earendil-works/pi-tui/dist/components/loader.js.map +1 -1
  1036. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +1 -1
  1037. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -1
  1038. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -1
  1039. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts +1 -1
  1040. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts.map +1 -1
  1041. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js.map +1 -1
  1042. package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts +1 -1
  1043. package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts.map +1 -1
  1044. package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js.map +1 -1
  1045. package/node_modules/@earendil-works/pi-tui/dist/components/spacer.d.ts +1 -1
  1046. package/node_modules/@earendil-works/pi-tui/dist/components/spacer.d.ts.map +1 -1
  1047. package/node_modules/@earendil-works/pi-tui/dist/components/spacer.js.map +1 -1
  1048. package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts +1 -1
  1049. package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts.map +1 -1
  1050. package/node_modules/@earendil-works/pi-tui/dist/components/text.js.map +1 -1
  1051. package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.d.ts +1 -1
  1052. package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.d.ts.map +1 -1
  1053. package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.js.map +1 -1
  1054. package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts +2 -2
  1055. package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts.map +1 -1
  1056. package/node_modules/@earendil-works/pi-tui/dist/editor-component.js.map +1 -1
  1057. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +22 -22
  1058. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  1059. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  1060. package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts +1 -1
  1061. package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts.map +1 -1
  1062. package/node_modules/@earendil-works/pi-tui/dist/keybindings.js.map +1 -1
  1063. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  1064. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +25 -15
  1065. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  1066. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +2 -2
  1067. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  1068. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  1069. package/node_modules/@earendil-works/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
  1070. package/node_modules/@earendil-works/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
  1071. package/node_modules/@earendil-works/pi-tui/package.json +8 -11
  1072. package/package.json +13 -8
  1073. package/dist/bin/forgecli.d.ts +0 -2
  1074. package/dist/bin/forgecli.js +0 -6
  1075. package/dist/bin/forgecli.js.map +0 -1
  1076. package/node_modules/koffi/CHANGELOG.md +0 -1093
  1077. package/node_modules/koffi/LICENSE.txt +0 -22
  1078. package/node_modules/koffi/README.md +0 -43
  1079. package/node_modules/koffi/build/koffi/darwin_arm64/koffi.node +0 -0
  1080. package/node_modules/koffi/build/koffi/darwin_x64/koffi.node +0 -0
  1081. package/node_modules/koffi/build/koffi/freebsd_arm64/koffi.node +0 -0
  1082. package/node_modules/koffi/build/koffi/freebsd_ia32/koffi.node +0 -0
  1083. package/node_modules/koffi/build/koffi/freebsd_x64/koffi.node +0 -0
  1084. package/node_modules/koffi/build/koffi/linux_arm64/koffi.node +0 -0
  1085. package/node_modules/koffi/build/koffi/linux_armhf/koffi.node +0 -0
  1086. package/node_modules/koffi/build/koffi/linux_ia32/koffi.node +0 -0
  1087. package/node_modules/koffi/build/koffi/linux_loong64/koffi.node +0 -0
  1088. package/node_modules/koffi/build/koffi/linux_riscv64d/koffi.node +0 -0
  1089. package/node_modules/koffi/build/koffi/linux_x64/koffi.node +0 -0
  1090. package/node_modules/koffi/build/koffi/musl_arm64/koffi.node +0 -0
  1091. package/node_modules/koffi/build/koffi/musl_x64/koffi.node +0 -0
  1092. package/node_modules/koffi/build/koffi/openbsd_ia32/koffi.node +0 -0
  1093. package/node_modules/koffi/build/koffi/openbsd_x64/koffi.node +0 -0
  1094. package/node_modules/koffi/build/koffi/win32_arm64/koffi.exp +0 -0
  1095. package/node_modules/koffi/build/koffi/win32_arm64/koffi.lib +0 -0
  1096. package/node_modules/koffi/build/koffi/win32_arm64/koffi.node +0 -0
  1097. package/node_modules/koffi/build/koffi/win32_ia32/koffi.exp +0 -0
  1098. package/node_modules/koffi/build/koffi/win32_ia32/koffi.lib +0 -0
  1099. package/node_modules/koffi/build/koffi/win32_ia32/koffi.node +0 -0
  1100. package/node_modules/koffi/build/koffi/win32_x64/koffi.exp +0 -0
  1101. package/node_modules/koffi/build/koffi/win32_x64/koffi.lib +0 -0
  1102. package/node_modules/koffi/build/koffi/win32_x64/koffi.node +0 -0
  1103. package/node_modules/koffi/doc/benchmarks.md +0 -126
  1104. package/node_modules/koffi/doc/callbacks.md +0 -210
  1105. package/node_modules/koffi/doc/contribute.md +0 -148
  1106. package/node_modules/koffi/doc/functions.md +0 -250
  1107. package/node_modules/koffi/doc/index.md +0 -61
  1108. package/node_modules/koffi/doc/input.md +0 -471
  1109. package/node_modules/koffi/doc/migration.md +0 -159
  1110. package/node_modules/koffi/doc/misc.md +0 -180
  1111. package/node_modules/koffi/doc/output.md +0 -305
  1112. package/node_modules/koffi/doc/packaging.md +0 -88
  1113. package/node_modules/koffi/doc/platforms.md +0 -36
  1114. package/node_modules/koffi/doc/pointers.md +0 -328
  1115. package/node_modules/koffi/doc/start.md +0 -118
  1116. package/node_modules/koffi/doc/unions.md +0 -186
  1117. package/node_modules/koffi/doc/variables.md +0 -102
  1118. package/node_modules/koffi/index.d.ts +0 -288
  1119. package/node_modules/koffi/index.js +0 -634
  1120. package/node_modules/koffi/indirect.js +0 -533
  1121. package/node_modules/koffi/lib/native/base/base.cc +0 -11015
  1122. package/node_modules/koffi/lib/native/base/base.hh +0 -6003
  1123. package/node_modules/koffi/lib/native/base/crc.inc +0 -2214
  1124. package/node_modules/koffi/lib/native/base/crc_gen.py +0 -72
  1125. package/node_modules/koffi/lib/native/base/mimetypes.inc +0 -1248
  1126. package/node_modules/koffi/lib/native/base/mimetypes_gen.py +0 -58
  1127. package/node_modules/koffi/lib/native/base/tower.cc +0 -821
  1128. package/node_modules/koffi/lib/native/base/tower.hh +0 -81
  1129. package/node_modules/koffi/lib/native/base/unicode.inc +0 -408
  1130. package/node_modules/koffi/lib/native/base/unicode_gen.py +0 -152
  1131. package/node_modules/koffi/package.json +0 -38
  1132. package/node_modules/koffi/src/cnoke/LICENSE.txt +0 -22
  1133. package/node_modules/koffi/src/cnoke/README.md +0 -99
  1134. package/node_modules/koffi/src/cnoke/assets/FindCNoke.cmake +0 -127
  1135. package/node_modules/koffi/src/cnoke/assets/toolchains.json +0 -126
  1136. package/node_modules/koffi/src/cnoke/assets/win_delay_hook.c +0 -36
  1137. package/node_modules/koffi/src/cnoke/cnoke.js +0 -170
  1138. package/node_modules/koffi/src/cnoke/package.json +0 -24
  1139. package/node_modules/koffi/src/cnoke/src/builder.js +0 -511
  1140. package/node_modules/koffi/src/cnoke/src/index.js +0 -10
  1141. package/node_modules/koffi/src/cnoke/src/tools.js +0 -407
  1142. package/node_modules/koffi/src/koffi/CMakeLists.txt +0 -182
  1143. package/node_modules/koffi/src/koffi/src/abi_arm32.cc +0 -1018
  1144. package/node_modules/koffi/src/koffi/src/abi_arm32_asm.S +0 -169
  1145. package/node_modules/koffi/src/koffi/src/abi_arm64.cc +0 -1295
  1146. package/node_modules/koffi/src/koffi/src/abi_arm64_asm.S +0 -195
  1147. package/node_modules/koffi/src/koffi/src/abi_arm64_asm.asm +0 -174
  1148. package/node_modules/koffi/src/koffi/src/abi_loong64.cc +0 -5
  1149. package/node_modules/koffi/src/koffi/src/abi_loong64_asm.S +0 -204
  1150. package/node_modules/koffi/src/koffi/src/abi_riscv64.cc +0 -915
  1151. package/node_modules/koffi/src/koffi/src/abi_riscv64_asm.S +0 -203
  1152. package/node_modules/koffi/src/koffi/src/abi_x64_sysv.cc +0 -939
  1153. package/node_modules/koffi/src/koffi/src/abi_x64_sysv_asm.S +0 -231
  1154. package/node_modules/koffi/src/koffi/src/abi_x64_win.cc +0 -715
  1155. package/node_modules/koffi/src/koffi/src/abi_x64_win_asm.S +0 -166
  1156. package/node_modules/koffi/src/koffi/src/abi_x64_win_asm.asm +0 -192
  1157. package/node_modules/koffi/src/koffi/src/abi_x86.cc +0 -860
  1158. package/node_modules/koffi/src/koffi/src/abi_x86_asm.S +0 -193
  1159. package/node_modules/koffi/src/koffi/src/abi_x86_asm.asm +0 -177
  1160. package/node_modules/koffi/src/koffi/src/call.cc +0 -1326
  1161. package/node_modules/koffi/src/koffi/src/call.hh +0 -179
  1162. package/node_modules/koffi/src/koffi/src/errno.inc +0 -462
  1163. package/node_modules/koffi/src/koffi/src/ffi.cc +0 -2702
  1164. package/node_modules/koffi/src/koffi/src/ffi.hh +0 -354
  1165. package/node_modules/koffi/src/koffi/src/init.js +0 -105
  1166. package/node_modules/koffi/src/koffi/src/parser.cc +0 -220
  1167. package/node_modules/koffi/src/koffi/src/parser.hh +0 -54
  1168. package/node_modules/koffi/src/koffi/src/util.cc +0 -1807
  1169. package/node_modules/koffi/src/koffi/src/util.hh +0 -221
  1170. package/node_modules/koffi/src/koffi/src/uv.cc +0 -193
  1171. package/node_modules/koffi/src/koffi/src/uv.def +0 -10
  1172. package/node_modules/koffi/src/koffi/src/uv.hh +0 -40
  1173. package/node_modules/koffi/src/koffi/src/win32.cc +0 -198
  1174. package/node_modules/koffi/src/koffi/src/win32.hh +0 -119
  1175. package/node_modules/koffi/src/koffi/tools/write_trampolines.js +0 -77
  1176. package/node_modules/koffi/vendor/node-addon-api/LICENSE.md +0 -9
  1177. package/node_modules/koffi/vendor/node-addon-api/README.md +0 -95
  1178. package/node_modules/koffi/vendor/node-addon-api/napi-inl.deprecated.h +0 -186
  1179. package/node_modules/koffi/vendor/node-addon-api/napi-inl.h +0 -7033
  1180. package/node_modules/koffi/vendor/node-addon-api/napi.h +0 -3309
  1181. package/node_modules/koffi/vendor/node-api-headers/LICENSE +0 -21
  1182. package/node_modules/koffi/vendor/node-api-headers/README.md +0 -95
  1183. package/node_modules/koffi/vendor/node-api-headers/def/js_native_api.def +0 -125
  1184. package/node_modules/koffi/vendor/node-api-headers/def/node_api.def +0 -157
  1185. package/node_modules/koffi/vendor/node-api-headers/include/js_native_api.h +0 -591
  1186. package/node_modules/koffi/vendor/node-api-headers/include/js_native_api_types.h +0 -210
  1187. package/node_modules/koffi/vendor/node-api-headers/include/node_api.h +0 -265
  1188. package/node_modules/koffi/vendor/node-api-headers/include/node_api_types.h +0 -58
  1189. package/node_modules/koffi/vendor/node-api-headers/include/uv/aix.h +0 -32
  1190. package/node_modules/koffi/vendor/node-api-headers/include/uv/bsd.h +0 -34
  1191. package/node_modules/koffi/vendor/node-api-headers/include/uv/darwin.h +0 -61
  1192. package/node_modules/koffi/vendor/node-api-headers/include/uv/errno.h +0 -483
  1193. package/node_modules/koffi/vendor/node-api-headers/include/uv/linux.h +0 -34
  1194. package/node_modules/koffi/vendor/node-api-headers/include/uv/os390.h +0 -33
  1195. package/node_modules/koffi/vendor/node-api-headers/include/uv/posix.h +0 -31
  1196. package/node_modules/koffi/vendor/node-api-headers/include/uv/sunos.h +0 -44
  1197. package/node_modules/koffi/vendor/node-api-headers/include/uv/threadpool.h +0 -37
  1198. package/node_modules/koffi/vendor/node-api-headers/include/uv/tree.h +0 -521
  1199. package/node_modules/koffi/vendor/node-api-headers/include/uv/unix.h +0 -512
  1200. package/node_modules/koffi/vendor/node-api-headers/include/uv/version.h +0 -43
  1201. package/node_modules/koffi/vendor/node-api-headers/include/uv/win.h +0 -698
  1202. package/node_modules/koffi/vendor/node-api-headers/include/uv.h +0 -1990
@@ -1,2702 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // SPDX-FileCopyrightText: 2025 Niels Martignène <niels.martignene@protonmail.com>
3
-
4
- #include "lib/native/base/base.hh"
5
- #include "ffi.hh"
6
- #include "call.hh"
7
- #include "parser.hh"
8
- #include "util.hh"
9
- #include "uv.hh"
10
- #if defined(_WIN32)
11
- #include "win32.hh"
12
- #endif
13
- #include "errno.inc"
14
-
15
- #if defined(_WIN32)
16
- #if !defined(NOMINMAX)
17
- #define NOMINMAX
18
- #endif
19
- #if !defined(WIN32_LEAN_AND_MEAN)
20
- #define WIN32_LEAN_AND_MEAN
21
- #endif
22
- #include <windows.h>
23
- #include <ntsecapi.h>
24
- #else
25
- #include <dlfcn.h>
26
- #include <unistd.h>
27
- #include <sys/mman.h>
28
- #if !defined(MAP_STACK)
29
- #define MAP_STACK 0
30
- #endif
31
- #endif
32
- #include <wchar.h>
33
-
34
- #include <napi.h>
35
-
36
- namespace K {
37
-
38
- SharedData shared;
39
-
40
- static thread_local CallData *exec_call;
41
-
42
- extern "C" napi_value SwitchAndRelay(CallData *call, Size idx, uint8_t *sp, uint8_t *saved_sp, Span<uint8_t> *new_stack);
43
-
44
- static bool ChangeSize(const char *name, Napi::Value value, Size min_size, Size max_size, Size *out_size)
45
- {
46
- Napi::Env env = value.Env();
47
-
48
- if (!value.IsNumber()) {
49
- InstanceData *instance = env.GetInstanceData<InstanceData>();
50
-
51
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for '%2', expected number", GetValueType(instance, value), name);
52
- return false;
53
- }
54
-
55
- int64_t size = value.As<Napi::Number>().Int64Value();
56
-
57
- if (size < min_size || size > max_size) {
58
- ThrowError<Napi::Error>(env, "Setting '%1' must be between %2 and %3", name, FmtMemSize(min_size), FmtMemSize(max_size));
59
- return false;
60
- }
61
-
62
- *out_size = (Size)size;
63
- return true;
64
- }
65
-
66
- static bool ChangeMemorySize(const char *name, Napi::Value value, Size *out_size)
67
- {
68
- const Size MinSize = Kibibytes(1);
69
- const Size MaxSize = Mebibytes(16);
70
-
71
- return ChangeSize(name, value, MinSize, MaxSize, out_size);
72
- }
73
-
74
- static bool ChangeAsyncLimit(const char *name, Napi::Value value, int max, int *out_limit)
75
- {
76
- Napi::Env env = value.Env();
77
-
78
- if (!value.IsNumber()) {
79
- InstanceData *instance = env.GetInstanceData<InstanceData>();
80
-
81
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for '%2', expected number", GetValueType(instance, value), name);
82
- return false;
83
- }
84
-
85
- int64_t n = value.As<Napi::Number>().Int64Value();
86
-
87
- if (n < 0 || n > max) {
88
- ThrowError<Napi::Error>(env, "Setting '%1' must be between 0 and %2", name, max);
89
- return false;
90
- }
91
-
92
- *out_limit = (int)n;
93
- return true;
94
- }
95
-
96
- static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
97
- {
98
- Napi::Env env = info.Env();
99
- InstanceData *instance = env.GetInstanceData<InstanceData>();
100
-
101
- if (info.Length()) {
102
- if (instance->memories.len) {
103
- ThrowError<Napi::Error>(env, "Cannot change Koffi configuration once a library has been loaded");
104
- return env.Null();
105
- }
106
-
107
- if (!info[0].IsObject()) {
108
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for config, expected object", GetValueType(instance, info[0]));
109
- return env.Null();
110
- }
111
-
112
- decltype(instance->config) new_config = instance->config;
113
- int max_async_calls = new_config.resident_async_pools + new_config.max_temporaries;
114
-
115
- Napi::Object obj = info[0].As<Napi::Object>();
116
- Napi::Array keys = GetOwnPropertyNames(obj);
117
-
118
- for (uint32_t i = 0; i < keys.Length(); i++) {
119
- std::string key = keys.Get(i).As<Napi::String>();
120
- Napi::Value value = obj[key];
121
-
122
- if (key == "sync_stack_size") {
123
- if (!ChangeMemorySize(key.c_str(), value, &new_config.sync_stack_size))
124
- return env.Null();
125
- } else if (key == "sync_heap_size") {
126
- if (!ChangeMemorySize(key.c_str(), value, &new_config.sync_heap_size))
127
- return env.Null();
128
- } else if (key == "async_stack_size") {
129
- if (!ChangeMemorySize(key.c_str(), value, &new_config.async_stack_size))
130
- return env.Null();
131
- } else if (key == "async_heap_size") {
132
- if (!ChangeMemorySize(key.c_str(), value, &new_config.async_heap_size))
133
- return env.Null();
134
- } else if (key == "resident_async_pools") {
135
- if (!ChangeAsyncLimit(key.c_str(), value, K_LEN(instance->memories.data) - 1, &new_config.resident_async_pools))
136
- return env.Null();
137
- } else if (key == "max_async_calls") {
138
- if (!ChangeAsyncLimit(key.c_str(), value, MaxAsyncCalls, &max_async_calls))
139
- return env.Null();
140
- } else if (key == "max_type_size") {
141
- if (!ChangeSize(key.c_str(), value, 32, Mebibytes(512), &new_config.max_type_size))
142
- return env.Null();
143
- } else {
144
- ThrowError<Napi::Error>(env, "Unexpected config member '%1'", key.c_str());
145
- return env.Null();
146
- }
147
- }
148
-
149
- if (max_async_calls < new_config.resident_async_pools) {
150
- ThrowError<Napi::Error>(env, "Setting max_async_calls must be >= to resident_async_pools");
151
- return env.Null();
152
- }
153
-
154
- new_config.max_temporaries = max_async_calls - new_config.resident_async_pools;
155
- instance->config = new_config;
156
- }
157
-
158
- Napi::Object obj = Napi::Object::New(env);
159
-
160
- obj.Set("sync_stack_size", instance->config.sync_stack_size);
161
- obj.Set("sync_heap_size", instance->config.sync_heap_size);
162
- obj.Set("async_stack_size", instance->config.async_stack_size);
163
- obj.Set("async_heap_size", instance->config.async_heap_size);
164
- obj.Set("resident_async_pools", instance->config.resident_async_pools);
165
- obj.Set("max_async_calls", instance->config.resident_async_pools + instance->config.max_temporaries);
166
- obj.Set("max_type_size", instance->config.max_type_size);
167
-
168
- return obj;
169
- }
170
-
171
- static Napi::Value GetStats(const Napi::CallbackInfo &info)
172
- {
173
- Napi::Env env = info.Env();
174
- InstanceData *instance = env.GetInstanceData<InstanceData>();
175
-
176
- Napi::Object obj = Napi::Object::New(env);
177
-
178
- obj.Set("disposed", instance->stats.disposed);
179
-
180
- return obj;
181
- }
182
-
183
- static inline bool CheckAlignment(int64_t align)
184
- {
185
- bool valid = (align > 0) && (align <= 8 && !(align & (align - 1)));
186
- return valid;
187
- }
188
-
189
- static bool IsNameValid(const char *name)
190
- {
191
- if (!IsXidStart(name[0]))
192
- return false;
193
-
194
- for (Size i = 1; name[i]; i++) {
195
- if (!IsXidContinue(name[i])) [[unlikely]]
196
- return false;
197
- }
198
-
199
- return true;
200
- }
201
-
202
- static bool MapType(Napi::Env env, InstanceData *instance, const TypeInfo *type, const char *name)
203
- {
204
- if (!IsNameValid(name)) {
205
- ThrowError<Napi::Error>(env, "Invalid type name '%1'", name);
206
- return false;
207
- }
208
-
209
- bool inserted;
210
- instance->types_map.InsertOrGet(name, type, &inserted);
211
-
212
- if (!inserted) {
213
- ThrowError<Napi::Error>(env, "Duplicate type name '%1'", name);
214
- return false;
215
- }
216
-
217
- return true;
218
- }
219
-
220
- static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
221
- {
222
- Napi::Env env = info.Env();
223
- InstanceData *instance = env.GetInstanceData<InstanceData>();
224
-
225
- if (info.Length() < 1) {
226
- ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
227
- return env.Null();
228
- }
229
-
230
- bool skip = (info.Length() > 1);
231
- bool named = skip && !IsNullOrUndefined(info[0]);
232
- bool redefine = named && CheckValueTag(info[0], &TypeInfoMarker);
233
-
234
- if (named && !info[0].IsString() && !redefine) {
235
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
236
- return env.Null();
237
- }
238
- if (!IsObject(info[skip])) {
239
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for members, expected object", GetValueType(instance, info[1]));
240
- return env.Null();
241
- }
242
-
243
- Napi::String name = info[0].As<Napi::String>();
244
- Napi::Object obj = info[skip].As<Napi::Object>();
245
- Napi::Array keys = GetOwnPropertyNames(obj);
246
-
247
- K_DEFER_NC(err_guard, count = instance->types.count) {
248
- Size start = count + !skip;
249
-
250
- for (Size i = start; i < instance->types.count; i++) {
251
- const TypeInfo *it = &instance->types[i];
252
- const TypeInfo **ptr = instance->types_map.Find(it->name);
253
-
254
- if (ptr && *ptr == it) {
255
- instance->types_map.Remove(ptr);
256
- }
257
- }
258
-
259
- instance->types.RemoveFrom(count);
260
- };
261
-
262
- TypeInfo *type = instance->types.AppendDefault();
263
- TypeInfo *replace = nullptr;
264
-
265
- if (redefine) {
266
- Napi::External<TypeInfo> external = name.As<Napi::External<TypeInfo>>();
267
- const TypeInfo *raw = external.Data();
268
-
269
- replace = (TypeInfo *)AlignDown(raw, 4);
270
- type->name = replace->name;
271
-
272
- if (replace->primitive != PrimitiveKind::Void || replace == instance->void_type) {
273
- ThrowError<Napi::TypeError>(env, "Cannot redefine non-opaque type %1", replace->name);
274
- return env.Null();
275
- }
276
- } else if (named) {
277
- type->name = DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr;
278
-
279
- if (!MapType(env, instance, type, type->name))
280
- return env.Null();
281
- } else {
282
- type->name = Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
283
- }
284
-
285
- type->primitive = PrimitiveKind::Record;
286
- type->align = 1;
287
- type->flags = (int)TypeFlag::IsIncomplete;
288
-
289
- HashSet<const char *> members;
290
- int64_t size = 0;
291
-
292
- for (uint32_t i = 0; i < keys.Length(); i++) {
293
- RecordMember member = {};
294
-
295
- std::string key = keys.Get(i).As<Napi::String>();
296
- Napi::Value value = obj[key];
297
- int16_t align = 0;
298
-
299
- member.name = DuplicateString(key.c_str(), &instance->str_alloc).ptr;
300
-
301
- if (value.IsArray()) {
302
- Napi::Array array = value.As<Napi::Array>();
303
-
304
- if (array.Length() != 2 || !array.Get(0u).IsNumber()) {
305
- ThrowError<Napi::Error>(env, "Member specifier array must contain alignement value and type");
306
- return env.Null();
307
- }
308
-
309
- int64_t align64 = array.Get(0u).As<Napi::Number>().Int64Value();
310
-
311
- if (!CheckAlignment(align64)) {
312
- ThrowError<Napi::Error>(env, "Alignment of member '%1' must be 1, 2, 4 or 8", member.name);
313
- return env.Null();
314
- }
315
-
316
- value = array[1u];
317
- align = (int16_t)align64;
318
- }
319
-
320
- member.type = ResolveType(value);
321
- if (!member.type)
322
- return env.Null();
323
- if (!CanStoreType(member.type)) {
324
- ThrowError<Napi::TypeError>(env, "Type %1 cannot be used as a member (maybe try %1 *)", member.type->name);
325
- return env.Null();
326
- }
327
-
328
- if (!align) {
329
- align = pad ? member.type->align : 1;
330
- }
331
- member.offset = (int32_t)AlignLen(size, align);
332
-
333
- size = member.offset + member.type->size;
334
- type->align = std::max(type->align, align);
335
-
336
- member.countedby = -1;
337
-
338
- if (size > instance->config.max_type_size) {
339
- ThrowError<Napi::Error>(env, "Struct '%1' size is too high (max = %2)", type->name, FmtMemSize(size));
340
- return env.Null();
341
- }
342
-
343
- if (TestStr(member.name, "_"))
344
- continue;
345
-
346
- if (!IsNameValid(member.name)) {
347
- ThrowError<Napi::Error>(env, "Invalid member name '%1'", member.name);
348
- return env.Null();
349
- }
350
-
351
- bool inserted;
352
- members.InsertOrGet(member.name, &inserted);
353
-
354
- if (!inserted) {
355
- ThrowError<Napi::Error>(env, "Duplicate member '%1' in struct '%2'", member.name, type->name);
356
- return env.Null();
357
- }
358
-
359
- type->members.Append(member);
360
- }
361
-
362
- for (Size i = 0; i < type->members.len; i++) {
363
- RecordMember *member = &type->members[i];
364
- const char *countedby = member->type->countedby;
365
-
366
- if (countedby) {
367
- const RecordMember *by = std::find_if(type->members.begin(), type->members.end(),
368
- [&](const RecordMember &member) { return TestStr(member.name, countedby); });
369
-
370
- if (by == type->members.end()) {
371
- ThrowError<Napi::Error>(env, "Record type %1 does not have member '%2'", type->name, countedby);
372
- return env.Null();
373
- }
374
- if (!IsInteger(by->type)) {
375
- ThrowError<Napi::Error>(env, "Dynamic length member %1 is not an integer", countedby);
376
- return env.Null();
377
- }
378
- if (member->type->primitive == PrimitiveKind::Array && i < type->members.len - 1) {
379
- ThrowError<Napi::Error>(env, "Flexible array '%1' is not the last member of struct", member->name);
380
- return env.Null();
381
- }
382
-
383
- member->countedby = by - type->members.ptr;
384
- }
385
- }
386
-
387
- size = (int32_t)AlignLen(size, type->align);
388
- if (!size) {
389
- ThrowError<Napi::Error>(env, "Empty struct '%1' is not allowed in C", type->name);
390
- return env.Null();
391
- }
392
- type->size = (int32_t)size;
393
-
394
- type->flags &= ~(int)TypeFlag::IsIncomplete;
395
- err_guard.Disable();
396
-
397
- if (replace) {
398
- std::swap(*type, *replace);
399
- type = replace;
400
- }
401
-
402
- return WrapType(env, type);
403
- }
404
-
405
- static Napi::Value CreatePaddedStructType(const Napi::CallbackInfo &info)
406
- {
407
- return CreateStructType(info, true);
408
- }
409
-
410
- static Napi::Value CreatePackedStructType(const Napi::CallbackInfo &info)
411
- {
412
- return CreateStructType(info, false);
413
- }
414
-
415
- static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
416
- {
417
- Napi::Env env = info.Env();
418
- InstanceData *instance = env.GetInstanceData<InstanceData>();
419
-
420
- if (info.Length() < 1) {
421
- ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
422
- return env.Null();
423
- }
424
-
425
- bool skip = (info.Length() > 1);
426
- bool named = skip && !IsNullOrUndefined(info[0]);
427
- bool redefine = named && CheckValueTag(info[0], &TypeInfoMarker);
428
-
429
- if (named && !info[0].IsString() && !redefine) {
430
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
431
- return env.Null();
432
- }
433
- if (!IsObject(info[skip])) {
434
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for members, expected object", GetValueType(instance, info[1]));
435
- return env.Null();
436
- }
437
-
438
- Napi::String name = info[0].As<Napi::String>();
439
- Napi::Object obj = info[skip].As<Napi::Object>();
440
- Napi::Array keys = GetOwnPropertyNames(obj);
441
-
442
- K_DEFER_NC(err_guard, count = instance->types.count) {
443
- Size start = count + !skip;
444
-
445
- for (Size i = start; i < instance->types.count; i++) {
446
- const TypeInfo *it = &instance->types[i];
447
- const TypeInfo **ptr = instance->types_map.Find(it->name);
448
-
449
- if (ptr && *ptr == it) {
450
- instance->types_map.Remove(ptr);
451
- }
452
- }
453
-
454
- instance->types.RemoveFrom(count);
455
- };
456
-
457
- TypeInfo *type = instance->types.AppendDefault();
458
- TypeInfo *replace = nullptr;
459
-
460
- if (redefine) {
461
- Napi::External<TypeInfo> external = name.As<Napi::External<TypeInfo>>();
462
- const TypeInfo *raw = external.Data();
463
-
464
- replace = (TypeInfo *)AlignDown(raw, 4);
465
- type->name = replace->name;
466
-
467
- if (replace->primitive != PrimitiveKind::Void || replace == instance->void_type) {
468
- ThrowError<Napi::TypeError>(env, "Cannot redefine non-opaque type %1", replace->name);
469
- return env.Null();
470
- }
471
- } else if (named) {
472
- type->name = DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr;
473
-
474
- if (!MapType(env, instance, type, type->name))
475
- return env.Null();
476
- } else {
477
- type->name = Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
478
- }
479
-
480
- type->primitive = PrimitiveKind::Union;
481
- type->align = 1;
482
- type->flags = (int)TypeFlag::IsIncomplete;
483
-
484
- HashSet<const char *> members;
485
- int32_t size = 0;
486
-
487
- for (uint32_t i = 0; i < keys.Length(); i++) {
488
- RecordMember member = {};
489
-
490
- std::string key = keys.Get(i).As<Napi::String>();
491
- Napi::Value value = obj[key];
492
- int16_t align = 0;
493
-
494
- member.name = DuplicateString(key.c_str(), &instance->str_alloc).ptr;
495
-
496
- if (value.IsArray()) {
497
- Napi::Array array = value.As<Napi::Array>();
498
-
499
- if (array.Length() != 2 || !array.Get(0u).IsNumber()) {
500
- ThrowError<Napi::Error>(env, "Member specifier array must contain alignement value and type");
501
- return env.Null();
502
- }
503
-
504
- int64_t align64 = array.Get(0u).As<Napi::Number>().Int64Value();
505
-
506
- if (!CheckAlignment(align64)) {
507
- ThrowError<Napi::Error>(env, "Alignment of member '%1' must be 1, 2, 4 or 8", member.name);
508
- return env.Null();
509
- }
510
-
511
- value = array[1u];
512
- align = (int16_t)align64;
513
- }
514
-
515
- member.type = ResolveType(value);
516
- if (!member.type)
517
- return env.Null();
518
- if (!CanStoreType(member.type)) {
519
- ThrowError<Napi::TypeError>(env, "Type %1 cannot be used as a member (maybe try %1 *)", member.type->name);
520
- return env.Null();
521
- }
522
- if (member.type->countedby) {
523
- ThrowError<Napi::TypeError>(env, "Cannot use dynamic-length array or pointer inside of union");
524
- return env.Null();
525
- }
526
-
527
- align = align ? align : member.type->align;
528
- size = std::max(size, member.type->size);
529
- type->align = std::max(type->align, align);
530
-
531
- member.countedby = -1;
532
-
533
- if (TestStr(member.name, "_"))
534
- continue;
535
-
536
- if (!IsNameValid(member.name)) {
537
- ThrowError<Napi::Error>(env, "Invalid member name '%1'", member.name);
538
- return env.Null();
539
- }
540
-
541
- bool inserted;
542
- members.InsertOrGet(member.name, &inserted);
543
-
544
- if (!inserted) {
545
- ThrowError<Napi::Error>(env, "Duplicate member '%1' in union '%2'", member.name, type->name);
546
- return env.Null();
547
- }
548
-
549
- type->members.Append(member);
550
- }
551
-
552
- size = (int32_t)AlignLen(size, type->align);
553
- if (!size) {
554
- ThrowError<Napi::Error>(env, "Empty union '%1' is not allowed in C", type->name);
555
- return env.Null();
556
- }
557
- type->size = (int32_t)size;
558
-
559
- type->flags &= ~(int)TypeFlag::IsIncomplete;
560
- err_guard.Disable();
561
-
562
- // Union constructor
563
- Napi::Function constructor = MagicUnion::InitClass(env, type);
564
- type->construct.Reset(constructor, 1);
565
-
566
- if (replace) {
567
- std::swap(*type, *replace);
568
- type = replace;
569
- }
570
-
571
- return WrapType(env, type);
572
- }
573
-
574
- Napi::Value InstantiateUnion(const Napi::CallbackInfo &info)
575
- {
576
- Napi::Env env = info.Env();
577
-
578
- if (!info.IsConstructCall()) {
579
- ThrowError<Napi::TypeError>(env, "This function is a constructor and must be called with new");
580
- return env.Null();
581
- }
582
- if (info.Length() < 1) {
583
- ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
584
- return env.Null();
585
- }
586
-
587
- const TypeInfo *type = ResolveType(info[0]);
588
- if (!type)
589
- return env.Null();
590
- if (type->primitive != PrimitiveKind::Union) {
591
- ThrowError<Napi::TypeError>(env, "Expected union type, got %1", PrimitiveKindNames[(int)type->primitive]);
592
- return env.Null();
593
- }
594
-
595
- Napi::Object wrapper = type->construct.New({}).As<Napi::Object>();
596
- SetValueTag(wrapper, &MagicUnionMarker);
597
-
598
- return wrapper;
599
- }
600
-
601
- static Napi::Value CreateOpaqueType(const Napi::CallbackInfo &info)
602
- {
603
- Napi::Env env = info.Env();
604
- InstanceData *instance = env.GetInstanceData<InstanceData>();
605
-
606
- bool named = (info.Length() >= 1) && !IsNullOrUndefined(info[0]);
607
-
608
- if (named && !info[0].IsString()) {
609
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
610
- return env.Null();
611
- }
612
-
613
- Napi::String name = info[0].As<Napi::String>();
614
-
615
- TypeInfo *type = instance->types.AppendDefault();
616
- K_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
617
-
618
- type->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr
619
- : Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
620
-
621
- type->primitive = PrimitiveKind::Void;
622
- type->size = 0;
623
- type->align = 0;
624
-
625
- // If the insert succeeds, we cannot fail anymore
626
- if (named && !MapType(env, instance, type, type->name))
627
- return env.Null();
628
- err_guard.Disable();
629
-
630
- return WrapType(env, type);
631
- }
632
-
633
- static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
634
- {
635
- Napi::Env env = info.Env();
636
- InstanceData *instance = env.GetInstanceData<InstanceData>();
637
-
638
- if (info.Length() < 1) {
639
- ThrowError<Napi::TypeError>(env, "Expected 1 to 3 arguments, got %1", info.Length());
640
- return env.Null();
641
- }
642
-
643
- bool skip = (info.Length() > 1) && !info[1].IsNumber();
644
- bool named = skip && !IsNullOrUndefined(info[0]);
645
-
646
- if (named && !info[0].IsString()) {
647
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
648
- return env.Null();
649
- }
650
-
651
- std::string name = named ? info[0].As<Napi::String>() : std::string();
652
-
653
- const TypeInfo *ref = ResolveType(info[skip]);
654
- if (!ref)
655
- return env.Null();
656
-
657
- Napi::Value countedby;
658
- int count = 1;
659
-
660
- if (info.Length() >= 2u + skip) {
661
- if (info[1 + skip].IsString()) {
662
- countedby = info[1 + skip];
663
- } else if (info[1 + skip].IsNumber()) {
664
- count = info[1 + skip].As<Napi::Number>();
665
-
666
- if (count < 1 || count > 4) {
667
- ThrowError<Napi::TypeError>(env, "Value of count must be between 1 and 4");
668
- return env.Null();
669
- }
670
- } else {
671
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for count, expected number", GetValueType(instance, info[1 + skip]));
672
- return env.Null();
673
- }
674
- }
675
-
676
- TypeInfo *type = MakePointerType(instance, ref, count);
677
- K_ASSERT(type);
678
-
679
- if (named || !countedby.IsEmpty()) {
680
- TypeInfo *copy = instance->types.AppendDefault();
681
- K_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
682
-
683
- memcpy((void *)copy, type, K_SIZE(*type));
684
- copy->name = named ? DuplicateString(name.c_str(), &instance->str_alloc).ptr : copy->name;
685
-
686
- if (!countedby.IsEmpty()) {
687
- Napi::String str = countedby.As<Napi::String>();
688
- copy->countedby = DuplicateString(str.Utf8Value().c_str(), &instance->str_alloc).ptr;
689
- }
690
-
691
- // If the insert succeeds, we cannot fail anymore
692
- if (named && !MapType(env, instance, copy, copy->name))
693
- return env.Null();
694
- err_guard.Disable();
695
-
696
- type = copy;
697
- }
698
-
699
- return WrapType(env, type);
700
- }
701
-
702
- static Napi::Value EncodePointerDirection(const Napi::CallbackInfo &info, int directions)
703
- {
704
- K_ASSERT(directions >= 1 && directions <= 3);
705
-
706
- Napi::Env env = info.Env();
707
-
708
- if (info.Length() < 1) {
709
- ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
710
- return env.Null();
711
- }
712
-
713
- const TypeInfo *type = ResolveType(info[0]);
714
- if (!type)
715
- return env.Null();
716
-
717
- if (type->primitive != PrimitiveKind::Pointer &&
718
- type->primitive != PrimitiveKind::String &&
719
- type->primitive != PrimitiveKind::String16 &&
720
- type->primitive != PrimitiveKind::String32) {
721
- ThrowError<Napi::TypeError>(env, "Unexpected %1 type, expected pointer or string type", type->name);
722
- return env.Null();
723
- }
724
-
725
- // Embed direction in unused pointer bits
726
- const TypeInfo *marked = (const TypeInfo *)((uint8_t *)type + directions - 1);
727
-
728
- return WrapType(env, marked);
729
- }
730
-
731
- static Napi::Value MarkIn(const Napi::CallbackInfo &info)
732
- {
733
- return EncodePointerDirection(info, 1);
734
- }
735
-
736
- static Napi::Value MarkOut(const Napi::CallbackInfo &info)
737
- {
738
- return EncodePointerDirection(info, 2);
739
- }
740
-
741
- static Napi::Value MarkInOut(const Napi::CallbackInfo &info)
742
- {
743
- return EncodePointerDirection(info, 3);
744
- }
745
-
746
- static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
747
- {
748
- Napi::Env env = info.Env();
749
- InstanceData *instance = env.GetInstanceData<InstanceData>();
750
-
751
- if (info.Length() < 1) {
752
- ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
753
- return env.Null();
754
- }
755
-
756
- bool skip = (info.Length() > 1) && !info[1].IsFunction();
757
- bool named = skip && !IsNullOrUndefined(info[0]);
758
-
759
- if (named && !info[0].IsString()) {
760
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
761
- return env.Null();
762
- }
763
-
764
- Napi::String name = info[0].As<Napi::String>();
765
-
766
- const TypeInfo *src = ResolveType(info[skip]);
767
- if (!src)
768
- return env.Null();
769
- if (src->primitive != PrimitiveKind::Pointer &&
770
- src->primitive != PrimitiveKind::String &&
771
- src->primitive != PrimitiveKind::String16 &&
772
- src->primitive != PrimitiveKind::String32) {
773
- ThrowError<Napi::TypeError>(env, "Unexpected %1 type, expected pointer or string type", src->name);
774
- return env.Null();
775
- }
776
- if (src->dispose) {
777
- ThrowError<Napi::TypeError>(env, "Cannot use disposable type '%1' to create new disposable", src->name);
778
- return env.Null();
779
- }
780
-
781
- DisposeFunc *dispose;
782
- Napi::Function dispose_func;
783
- if (info.Length() >= 2u + skip && !IsNullOrUndefined(info[1 + skip])) {
784
- Napi::Function func = info[1 + skip].As<Napi::Function>();
785
-
786
- if (!func.IsFunction()) {
787
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for func, expected function", GetValueType(instance, func));
788
- return env.Null();
789
- }
790
-
791
- dispose = [](Napi::Env env, const TypeInfo *type, const void *ptr) {
792
- InstanceData *instance = env.GetInstanceData<InstanceData>();
793
- const Napi::FunctionReference &ref = type->dispose_ref;
794
-
795
- Napi::External<void> external = Napi::External<void>::New(env, (void *)ptr);
796
- SetValueTag(external, type->ref.marker);
797
-
798
- Napi::Value self = env.Null();
799
- napi_value args[] = {
800
- external
801
- };
802
-
803
- ref.Call(self, K_LEN(args), args);
804
- instance->stats.disposed++;
805
- };
806
- dispose_func = func;
807
- } else {
808
- dispose = [](Napi::Env env, const TypeInfo *, const void *ptr) {
809
- InstanceData *instance = env.GetInstanceData<InstanceData>();
810
-
811
- free((void *)ptr);
812
- instance->stats.disposed++;
813
- };
814
- }
815
-
816
- TypeInfo *type = instance->types.AppendDefault();
817
- K_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
818
-
819
- memcpy((void *)type, (const void *)src, K_SIZE(*src));
820
- type->members.allocator = GetNullAllocator();
821
-
822
- type->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr
823
- : Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
824
-
825
- type->dispose = dispose;
826
- type->dispose_ref = Napi::Persistent(dispose_func);
827
-
828
- // If the insert succeeds, we cannot fail anymore
829
- if (named && !MapType(env, instance, type, type->name))
830
- return env.Null();
831
- err_guard.Disable();
832
-
833
- return WrapType(env, type);
834
- }
835
-
836
- static inline bool GetExternalPointer(Napi::Env env, Napi::Value value, void **out_ptr)
837
- {
838
- InstanceData *instance = env.GetInstanceData<InstanceData>();
839
-
840
- if (IsNullOrUndefined(value)) {
841
- *out_ptr = 0;
842
- return true;
843
- } else if (IsRawBuffer(value)) {
844
- Span<uint8_t> buffer = GetRawBuffer(value);
845
-
846
- *out_ptr = buffer.ptr;
847
- return true;
848
- } else if (value.IsExternal() && !CheckValueTag(value, &TypeInfoMarker) &&
849
- !CheckValueTag(value, &CastMarker) &&
850
- !CheckValueTag(value, &MagicUnionMarker)) {
851
- Napi::External<void> external = value.As<Napi::External<void>>();
852
- void *ptr = external.Data();
853
-
854
- *out_ptr = ptr;
855
- return true;
856
- } else {
857
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected external pointer", GetValueType(instance, value));
858
- return false;
859
- }
860
- }
861
-
862
- static Napi::Value CallAlloc(const Napi::CallbackInfo &info)
863
- {
864
- Napi::Env env = info.Env();
865
- InstanceData *instance = env.GetInstanceData<InstanceData>();
866
-
867
- if (info.Length() < 2) {
868
- ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
869
- return env.Null();
870
- }
871
- if (!info[1].IsNumber()) {
872
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for length, expected number", GetValueType(instance, info[1]));
873
- return env.Null();
874
- }
875
-
876
- const TypeInfo *type = ResolveType(info[0]);
877
- if (!type)
878
- return env.Null();
879
-
880
- if (!type->size) [[unlikely]] {
881
- ThrowError<Napi::TypeError>(env, "Cannot allocate memory for zero-sized type %1", type->name);
882
- return env.Null();
883
- }
884
-
885
- int32_t len = info[1].As<Napi::Number>();
886
-
887
- if (len <= 0) [[unlikely]] {
888
- ThrowError<Napi::Error>(env, "Size must be greater than 0");
889
- return env.Null();
890
- }
891
- if (len > INT32_MAX / type->size) [[unlikely]] {
892
- ThrowError<Napi::Error>(env, "Cannot allocate more than %1 objects of type %2", INT32_MAX / type->size, type->name);
893
- return env.Null();
894
- }
895
-
896
- void *ptr = calloc((size_t)len, (size_t)type->size);
897
-
898
- if (!ptr) [[unlikely]] {
899
- Size size = (Size)(len * type->size);
900
-
901
- ThrowError<Napi::Error>(env, "Failed to allocate %1 of memory", FmtMemSize((Size)size));
902
- return env.Null();
903
- }
904
-
905
- Napi::External<void> external = Napi::External<void>::New(env, ptr);
906
- SetValueTag(external, type);
907
-
908
- return external;
909
- }
910
-
911
- static Napi::Value CallFree(const Napi::CallbackInfo &info)
912
- {
913
- Napi::Env env = info.Env();
914
-
915
- if (info.Length() < 1) {
916
- ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
917
- return env.Null();
918
- }
919
-
920
- void *ptr = nullptr;
921
- if (!GetExternalPointer(env, info[0], &ptr))
922
- return env.Null();
923
-
924
- free(ptr);
925
-
926
- return env.Undefined();
927
- }
928
-
929
- static Napi::Value GetOrSetErrNo(const Napi::CallbackInfo &info)
930
- {
931
- Napi::Env env = info.Env();
932
- InstanceData *instance = env.GetInstanceData<InstanceData>();
933
-
934
- if (info.Length() >= 1) {
935
- Napi::Number value = info[0].As<Napi::Number>();
936
-
937
- if (!value.IsNumber()) {
938
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for errno, expected integer", GetValueType(instance, value));
939
- return env.Null();
940
- }
941
-
942
- errno = value;
943
- }
944
-
945
- Napi::Number ret = Napi::Number::New(env, errno);
946
- return ret;
947
- }
948
-
949
- static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
950
- {
951
- Napi::Env env = info.Env();
952
- InstanceData *instance = env.GetInstanceData<InstanceData>();
953
-
954
- if (info.Length() < 2) {
955
- ThrowError<Napi::TypeError>(env, "Expected 2 to 4 arguments, got %1", info.Length());
956
- return env.Null();
957
- }
958
-
959
- const TypeInfo *ref = ResolveType(info[0]);
960
- if (!ref)
961
- return env.Null();
962
-
963
- bool dynamic = (info.Length() >= 3) && info[1].IsString();
964
-
965
- if (dynamic && !info[1].IsString()) {
966
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for countedBy, expected string", GetValueType(instance, info[1]));
967
- return env.Null();
968
- }
969
- if (!info[1 + dynamic].IsNumber()) {
970
- if (info.Length() == 2 && info[1].IsString()) {
971
- ThrowError<Napi::TypeError>(env, "Missing maxLen argument");
972
- } else {
973
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for %2, expected integer", GetValueType(instance, info[1]), dynamic ? "maxLen" : "len");
974
- }
975
- return env.Null();
976
- }
977
-
978
- int64_t len = info[1 + dynamic].As<Napi::Number>().Int64Value();
979
-
980
- if (len <= 0) {
981
- ThrowError<Napi::TypeError>(env, "Array length must be positive and non-zero");
982
- return env.Null();
983
- }
984
- if (len > instance->config.max_type_size / ref->size) {
985
- ThrowError<Napi::TypeError>(env, "Array length is too high (max = %1)", instance->config.max_type_size / ref->size);
986
- return env.Null();
987
- }
988
-
989
- TypeInfo *type = nullptr;
990
-
991
- if (info.Length() >= 3u + dynamic && !IsNullOrUndefined(info[2 + dynamic])) {
992
- if (!info[2 + dynamic].IsString()) {
993
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for hint, expected string", GetValueType(instance, info[2]));
994
- return env.Null();
995
- }
996
-
997
- std::string str = info[2 + dynamic].As<Napi::String>();
998
- ArrayHint hint = {};
999
-
1000
- if (str == "Typed" || str == "typed") {
1001
- if (!(ref->flags & (int)TypeFlag::HasTypedArray)) {
1002
- ThrowError<Napi::Error>(env, "Array hint 'Typed' cannot be used with type %1", ref->name);
1003
- return env.Null();
1004
- }
1005
-
1006
- hint = ArrayHint::Typed;
1007
- } else if (str == "Array" || str == "array") {
1008
- hint = ArrayHint::Array;
1009
- } else if (str == "String" || str == "string") {
1010
- if (ref->primitive != PrimitiveKind::Int8 && ref->primitive != PrimitiveKind::Int16) {
1011
- ThrowError<Napi::Error>(env, "Array hint 'String' can only be used with 8 and 16-bit signed integer types");
1012
- return env.Null();
1013
- }
1014
-
1015
- hint = ArrayHint::String;
1016
- } else {
1017
- ThrowError<Napi::Error>(env, "Array conversion hint must be 'Typed', 'Array' or 'String'");
1018
- return env.Null();
1019
- }
1020
-
1021
- type = MakeArrayType(instance, ref, len, hint);
1022
- } else {
1023
- type = MakeArrayType(instance, ref, len);
1024
- }
1025
-
1026
- if (dynamic) {
1027
- Napi::String str = info[1].As<Napi::String>();
1028
- type->countedby = DuplicateString(str.Utf8Value().c_str(), &instance->str_alloc).ptr;
1029
- }
1030
-
1031
- return WrapType(env, type);
1032
- }
1033
-
1034
- static bool ParseClassicFunction(const Napi::CallbackInfo &info, bool concrete, FunctionInfo *out_func)
1035
- {
1036
- K_ASSERT(info.Length() >= 2);
1037
-
1038
- Napi::Env env = info.Env();
1039
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1040
-
1041
- Napi::String name = info[0u].As<Napi::String>();
1042
- Napi::Value ret = info[1u];
1043
- Napi::Array parameters = info[2u].As<Napi::Array>();
1044
-
1045
- // Detect optional call convention
1046
- if (name.IsString() && DetectCallConvention(name.Utf8Value().c_str(), &out_func->convention)) {
1047
- if (info.Length() < 3) {
1048
- ThrowError<Napi::TypeError>(env, "Expected 3 or 4 arguments, got %1", info.Length());
1049
- return false;
1050
- }
1051
-
1052
- name = info[1u].As<Napi::String>();
1053
- ret = info[2u];
1054
- parameters = (info.Length() >= 4 ? info[3u] : env.Null()).As<Napi::Array>();
1055
- }
1056
-
1057
- bool named = parameters.IsArray();
1058
-
1059
- if (named) {
1060
- #if defined(_WIN32)
1061
- if (name.IsNumber()) {
1062
- out_func->ordinal_name = name.As<Napi::Number>().Int32Value();
1063
- name = name.ToString();
1064
- }
1065
- #endif
1066
- if (!name.IsString()) {
1067
- if (!concrete && IsNullOrUndefined(name)) {
1068
- named = false;
1069
- } else {
1070
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string or integer", GetValueType(instance, name));
1071
- return false;
1072
- }
1073
- }
1074
- } else {
1075
- parameters = ret.As<Napi::Array>();
1076
- ret = name;
1077
- }
1078
-
1079
- // Leave anonymous naming responsibility to caller
1080
- out_func->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr : nullptr;
1081
-
1082
- out_func->ret.type = ResolveType(ret);
1083
- if (!out_func->ret.type)
1084
- return false;
1085
- if (!CanReturnType(out_func->ret.type)) {
1086
- ThrowError<Napi::TypeError>(env, "You are not allowed to directly return %1 values (maybe try %1 *)", out_func->ret.type->name);
1087
- return false;
1088
- }
1089
-
1090
- if (!parameters.IsArray()) {
1091
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for parameters of '%2', expected an array", GetValueType(instance, parameters), out_func->name);
1092
- return false;
1093
- }
1094
-
1095
- uint32_t parameters_len = parameters.Length();
1096
-
1097
- if (parameters_len) {
1098
- Napi::String str = parameters.Get(parameters_len - 1).As<Napi::String>();
1099
-
1100
- if (str.IsString() && str.Utf8Value() == "...") {
1101
- out_func->variadic = true;
1102
- parameters_len--;
1103
- }
1104
- }
1105
-
1106
- for (uint32_t j = 0; j < parameters_len; j++) {
1107
- ParameterInfo param = {};
1108
-
1109
- param.type = ResolveType(parameters[j], &param.directions);
1110
-
1111
- if (!param.type)
1112
- return false;
1113
- if (!CanPassType(param.type, param.directions)) {
1114
- ThrowError<Napi::TypeError>(env, "Type %1 cannot be used as a parameter", param.type->name);
1115
- return false;
1116
- }
1117
- if (out_func->parameters.len >= MaxParameters) {
1118
- ThrowError<Napi::TypeError>(env, "Functions cannot have more than %1 parameters", MaxParameters);
1119
- return false;
1120
- }
1121
- if ((param.directions & 2) && ++out_func->out_parameters >= MaxParameters) {
1122
- ThrowError<Napi::TypeError>(env, "Functions cannot have more than %1 output parameters", MaxParameters);
1123
- return false;
1124
- }
1125
-
1126
- param.offset = (int8_t)j;
1127
-
1128
- out_func->parameters.Append(param);
1129
- }
1130
-
1131
- out_func->required_parameters = (int8_t)out_func->parameters.len;
1132
-
1133
- return true;
1134
- }
1135
-
1136
- static Napi::Value CreateFunctionType(const Napi::CallbackInfo &info)
1137
- {
1138
- Napi::Env env = info.Env();
1139
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1140
-
1141
- FunctionInfo *func = instance->callbacks.AppendDefault();
1142
- TypeInfo *type = instance->types.AppendDefault();
1143
-
1144
- K_DEFER_N(err_guard) {
1145
- instance->callbacks.RemoveLast(1);
1146
- instance->types.RemoveLast(1);
1147
- };
1148
-
1149
- if (info.Length() >= 2) {
1150
- if (!ParseClassicFunction(info, false, func))
1151
- return env.Null();
1152
- } else if (info.Length() >= 1) {
1153
- if (!info[0].IsString()) {
1154
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for prototype, expected string", GetValueType(instance, info[0]));
1155
- return env.Null();
1156
- }
1157
-
1158
- std::string proto = info[0u].As<Napi::String>();
1159
- if (!ParsePrototype(env, proto.c_str(), false, func))
1160
- return env.Null();
1161
- } else {
1162
- ThrowError<Napi::TypeError>(env, "Expected 1 to 4 arguments, got %1", info.Length());
1163
- return env.Null();
1164
- }
1165
-
1166
- bool named = func->name;
1167
-
1168
- if (!named) {
1169
- func->name = Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
1170
- }
1171
-
1172
- if (!AnalyseFunction(env, instance, func))
1173
- return env.Null();
1174
-
1175
- // Adjust parameter offsets for koffi.call()
1176
- for (ParameterInfo &param: func->parameters) {
1177
- param.offset += 2;
1178
- }
1179
- func->required_parameters += 2;
1180
-
1181
- type->name = func->name;
1182
-
1183
- type->primitive = PrimitiveKind::Prototype;
1184
- type->align = alignof(void *);
1185
- type->size = K_SIZE(void *);
1186
- type->ref.proto = func;
1187
-
1188
- // If the insert succeeds, we cannot fail anymore
1189
- if (named && !MapType(env, instance, type, type->name))
1190
- return env.Null();
1191
- err_guard.Disable();
1192
-
1193
- return WrapType(env, type);
1194
- }
1195
-
1196
- static Napi::Value CreateTypeAlias(const Napi::CallbackInfo &info)
1197
- {
1198
- Napi::Env env = info.Env();
1199
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1200
-
1201
- if (info.Length() < 2) {
1202
- ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
1203
- return env.Null();
1204
- }
1205
- if (!info[0].IsString()) {
1206
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
1207
- return env.Null();
1208
- }
1209
-
1210
- std::string name = info[0].As<Napi::String>();
1211
- const char *alias = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
1212
-
1213
- const TypeInfo *type = ResolveType(info[1]);
1214
- if (!type)
1215
- return env.Null();
1216
-
1217
- // Alias the type
1218
- if (!MapType(env, instance, type, alias))
1219
- return env.Null();
1220
-
1221
- return WrapType(env, type);
1222
- }
1223
-
1224
- static Napi::Value GetTypeSize(const Napi::CallbackInfo &info)
1225
- {
1226
- Napi::Env env = info.Env();
1227
-
1228
- if (info.Length() < 1) {
1229
- ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
1230
- return env.Null();
1231
- }
1232
-
1233
- const TypeInfo *type = ResolveType(info[0]);
1234
- if (!type)
1235
- return env.Null();
1236
-
1237
- return Napi::Number::New(env, type->size);
1238
- }
1239
-
1240
- static Napi::Value GetTypeAlign(const Napi::CallbackInfo &info)
1241
- {
1242
- Napi::Env env = info.Env();
1243
-
1244
- if (info.Length() < 1) {
1245
- ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
1246
- return env.Null();
1247
- }
1248
-
1249
- const TypeInfo *type = ResolveType(info[0]);
1250
- if (!type)
1251
- return env.Null();
1252
-
1253
- return Napi::Number::New(env, type->align);
1254
- }
1255
-
1256
- static Napi::Value GetMemberOffset(const Napi::CallbackInfo &info)
1257
- {
1258
- Napi::Env env = info.Env();
1259
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1260
-
1261
- if (info.Length() < 2) {
1262
- ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
1263
- return env.Null();
1264
- }
1265
- if (!info[1].IsString()) {
1266
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member, expected string", GetValueType(instance, info[1]));
1267
- return env.Null();
1268
- }
1269
-
1270
- const TypeInfo *type = ResolveType(info[0]);
1271
- if (!type)
1272
- return env.Null();
1273
- if (type->primitive != PrimitiveKind::Record) {
1274
- ThrowError<Napi::TypeError>(env, "The offsetof() function can only be used with record types");
1275
- return env.Null();
1276
- }
1277
-
1278
- std::string name = info[1].As<Napi::String>();
1279
-
1280
- const RecordMember *member = std::find_if(type->members.begin(), type->members.end(),
1281
- [&](const RecordMember &member) { return TestStr(member.name, name.c_str()); });
1282
- if (member == type->members.end()) {
1283
- ThrowError<Napi::Error>(env, "Record type %1 does not have member '%2'", type->name, name.c_str());
1284
- return env.Null();
1285
- }
1286
-
1287
- return Napi::Number::New(env, member->offset);
1288
- }
1289
-
1290
- static Napi::Value GetResolvedType(const Napi::CallbackInfo &info)
1291
- {
1292
- Napi::Env env = info.Env();
1293
-
1294
- if (info.Length() < 1) {
1295
- ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
1296
- return env.Null();
1297
- }
1298
-
1299
- const TypeInfo *type = ResolveType(info[0]);
1300
- if (!type)
1301
- return env.Null();
1302
-
1303
- return WrapType(env, type);
1304
- }
1305
-
1306
- static Napi::Value GetTypeDefinition(const Napi::CallbackInfo &info)
1307
- {
1308
- Napi::Env env = info.Env();
1309
-
1310
- if (info.Length() < 1) {
1311
- ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
1312
- return env.Null();
1313
- }
1314
-
1315
- const TypeInfo *type = ResolveType(info[0]);
1316
- if (!type)
1317
- return env.Null();
1318
-
1319
- if (type->defn.IsEmpty()) {
1320
- Napi::Object defn = Napi::Object::New(env);
1321
-
1322
- defn.Set("name", Napi::String::New(env, type->name));
1323
- defn.Set("primitive", PrimitiveKindNames[(int)type->primitive]);
1324
- defn.Set("size", Napi::Number::New(env, (double)type->size));
1325
- defn.Set("alignment", Napi::Number::New(env, (double)type->align));
1326
- defn.Set("disposable", Napi::Boolean::New(env, !!type->dispose));
1327
-
1328
- switch (type->primitive) {
1329
- case PrimitiveKind::Void:
1330
- case PrimitiveKind::Bool:
1331
- case PrimitiveKind::Int8:
1332
- case PrimitiveKind::UInt8:
1333
- case PrimitiveKind::Int16:
1334
- case PrimitiveKind::Int16S:
1335
- case PrimitiveKind::UInt16:
1336
- case PrimitiveKind::UInt16S:
1337
- case PrimitiveKind::Int32:
1338
- case PrimitiveKind::Int32S:
1339
- case PrimitiveKind::UInt32:
1340
- case PrimitiveKind::UInt32S:
1341
- case PrimitiveKind::Int64:
1342
- case PrimitiveKind::Int64S:
1343
- case PrimitiveKind::UInt64:
1344
- case PrimitiveKind::UInt64S:
1345
- case PrimitiveKind::String:
1346
- case PrimitiveKind::String16:
1347
- case PrimitiveKind::String32:
1348
- case PrimitiveKind::Float32:
1349
- case PrimitiveKind::Float64:
1350
- case PrimitiveKind::Prototype:
1351
- case PrimitiveKind::Callback: {} break;
1352
-
1353
- case PrimitiveKind::Array: {
1354
- uint32_t len = type->size / type->ref.type->size;
1355
- defn.Set("length", Napi::Number::New(env, (double)len));
1356
- defn.Set("hint", ArrayHintNames[(int)type->hint]);
1357
- } [[fallthrough]];
1358
- case PrimitiveKind::Pointer: {
1359
- Napi::Value value = WrapType(env, type->ref.type);
1360
- defn.Set("ref", value);
1361
- } break;
1362
- case PrimitiveKind::Record:
1363
- case PrimitiveKind::Union: {
1364
- Napi::Object members = Napi::Object::New(env);
1365
-
1366
- for (const RecordMember &member: type->members) {
1367
- Napi::Object obj = Napi::Object::New(env);
1368
-
1369
- obj.Set("name", member.name);
1370
- obj.Set("type", WrapType(env, member.type));
1371
- obj.Set("offset", member.offset);
1372
- if (member.countedby >= 0) {
1373
- obj.Set("countedBy", type->members[member.countedby].name);
1374
- }
1375
-
1376
- members.Set(member.name, obj);
1377
- }
1378
-
1379
- defn.Set("members", members);
1380
- } break;
1381
- }
1382
-
1383
- defn.Freeze();
1384
- type->defn.Reset(defn, 1);
1385
- }
1386
-
1387
- return type->defn.Value();
1388
- }
1389
-
1390
- InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, Size heap_size)
1391
- {
1392
- std::lock_guard<std::mutex> lock(instance->mem_mutex);
1393
-
1394
- for (Size i = 1; i < instance->memories.len; i++) {
1395
- InstanceMemory *mem = instance->memories[i];
1396
-
1397
- if (!mem->busy) {
1398
- mem->busy = true;
1399
- return mem;
1400
- }
1401
- }
1402
-
1403
- bool temporary = (instance->memories.len > instance->config.resident_async_pools);
1404
-
1405
- if (temporary && instance->temporaries > instance->config.max_temporaries)
1406
- return nullptr;
1407
-
1408
- InstanceMemory *mem = new InstanceMemory();
1409
- K_DEFER_N(mem_guard) { delete mem; };
1410
-
1411
- stack_size = AlignLen(stack_size, Kibibytes(64));
1412
-
1413
- #if defined(_WIN32)
1414
- // Allocate stack memory
1415
- mem->stack.len = stack_size;
1416
- mem->stack.ptr = (uint8_t *)VirtualAlloc(nullptr, mem->stack.len, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
1417
-
1418
- K_CRITICAL(mem->stack.ptr, "Failed to allocate %1 of memory", mem->stack.len);
1419
- #else
1420
- mem->stack.len = stack_size;
1421
- mem->stack.ptr = (uint8_t *)mmap(nullptr, mem->stack.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0);
1422
-
1423
- K_CRITICAL(mem->stack.ptr, "Failed to allocate %1 of memory", mem->stack.len);
1424
- #endif
1425
-
1426
- #if defined(__OpenBSD__)
1427
- // Make sure the SP points inside the MAP_STACK area, or (void) functions may crash on OpenBSD i386
1428
- mem->stack.len -= 16;
1429
- #endif
1430
-
1431
- // Keep real stack limits intact, in case we need them
1432
- mem->stack0 = mem->stack;
1433
-
1434
- #if defined(_WIN32) && !defined(_WIN64)
1435
- mem->stack.len -= K_SIZE(SehFrame);
1436
-
1437
- // Prepare at the top SEH frame record
1438
- {
1439
- SehFrame *seh = (SehFrame *)mem->stack.end();
1440
-
1441
- seh->Next = (void *)-1;
1442
- seh->Handler = (void *)SehHandler;
1443
- }
1444
- #endif
1445
-
1446
- mem->heap.len = heap_size;
1447
- #if defined(_WIN32)
1448
- mem->heap.ptr = (uint8_t *)VirtualAlloc(nullptr, mem->heap.len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
1449
- #else
1450
- mem->heap.ptr = (uint8_t *)mmap(nullptr, mem->heap.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
1451
- #endif
1452
- K_CRITICAL(mem->heap.ptr, "Failed to allocate %1 of memory", mem->heap.len);
1453
-
1454
- if (temporary) {
1455
- instance->temporaries++;
1456
- mem->temporary = true;
1457
- } else {
1458
- instance->memories.Append(mem);
1459
- mem->temporary = false;
1460
- }
1461
-
1462
- mem->busy = true;
1463
-
1464
- mem_guard.Disable();
1465
- return mem;
1466
- }
1467
-
1468
- void ReleaseMemory(InstanceData *instance, InstanceMemory *mem)
1469
- {
1470
- if (--mem->depth)
1471
- return;
1472
-
1473
- // The first InstanceMemory is used for sync calls, no need to manage the async stuff
1474
- if (mem == instance->memories[0])
1475
- return;
1476
-
1477
- std::lock_guard<std::mutex> lock(instance->mem_mutex);
1478
-
1479
- if (mem->temporary) {
1480
- instance->temporaries--;
1481
- delete mem;
1482
- } else {
1483
- mem->busy = false;
1484
- }
1485
- }
1486
-
1487
- static Napi::Value TranslateNormalCall(const FunctionInfo *func, void *native,
1488
- const Napi::CallbackInfo &info)
1489
- {
1490
- Napi::Env env = info.Env();
1491
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1492
-
1493
- if (info.Length() < (uint32_t)func->required_parameters) [[unlikely]] {
1494
- ThrowError<Napi::TypeError>(env, "Expected %1 arguments, got %2", func->parameters.len, info.Length());
1495
- return env.Null();
1496
- }
1497
-
1498
- InstanceMemory *mem = instance->memories[0];
1499
- CallData call(env, instance, mem);
1500
-
1501
- if (!call.Prepare(func, info)) [[unlikely]]
1502
- return env.Null();
1503
-
1504
- if (instance->debug) {
1505
- call.DumpForward(func);
1506
- }
1507
-
1508
- // Execute call
1509
- {
1510
- K_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
1511
- exec_call = &call;
1512
-
1513
- call.Execute(func, native);
1514
- }
1515
-
1516
- return call.Complete(func);
1517
- }
1518
-
1519
- Napi::Value TranslateNormalCall(const Napi::CallbackInfo &info)
1520
- {
1521
- FunctionInfo *func = (FunctionInfo *)info.Data();
1522
- return TranslateNormalCall(func, func->native, info);
1523
- }
1524
-
1525
- static Napi::Value TranslateVariadicCall(const FunctionInfo *func, void *native,
1526
- const Napi::CallbackInfo &info)
1527
- {
1528
- Napi::Env env = info.Env();
1529
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1530
-
1531
- FunctionInfo copy;
1532
- memcpy((void *)&copy, func, K_SIZE(*func));
1533
- copy.lib = nullptr;
1534
-
1535
- // This makes variadic calls non-reentrant
1536
- K_DEFER_C(len = copy.parameters.len) {
1537
- copy.parameters.RemoveFrom(len);
1538
- copy.parameters.Leak();
1539
- };
1540
-
1541
- if (info.Length() < (uint32_t)copy.required_parameters) [[unlikely]] {
1542
- ThrowError<Napi::TypeError>(env, "Expected %1 arguments or more, got %2", copy.parameters.len, info.Length());
1543
- return env.Null();
1544
- }
1545
- if ((info.Length() - copy.required_parameters) % 2) [[unlikely]] {
1546
- ThrowError<Napi::Error>(env, "Missing value argument for variadic call");
1547
- return env.Null();
1548
- }
1549
-
1550
- for (Size i = copy.required_parameters; i < (Size)info.Length(); i += 2) {
1551
- ParameterInfo param = {};
1552
-
1553
- param.type = ResolveType(info[(uint32_t)i], &param.directions);
1554
-
1555
- if (!param.type) [[unlikely]]
1556
- return env.Null();
1557
- if (!CanPassType(param.type, param.directions)) [[unlikely]] {
1558
- ThrowError<Napi::TypeError>(env, "Type %1 cannot be used as a parameter", param.type->name);
1559
- return env.Null();
1560
- }
1561
- if (copy.parameters.len >= MaxParameters) [[unlikely]] {
1562
- ThrowError<Napi::TypeError>(env, "Functions cannot have more than %1 parameters", MaxParameters);
1563
- return env.Null();
1564
- }
1565
- if ((param.directions & 2) && ++copy.out_parameters >= MaxParameters) [[unlikely]] {
1566
- ThrowError<Napi::TypeError>(env, "Functions cannot have more than %1 output parameters", MaxParameters);
1567
- return env.Null();
1568
- }
1569
-
1570
- param.variadic = true;
1571
- param.offset = (int8_t)(i + 1);
1572
-
1573
- copy.parameters.Append(param);
1574
- }
1575
-
1576
- if (!AnalyseFunction(env, instance, &copy)) [[unlikely]]
1577
- return env.Null();
1578
-
1579
- InstanceMemory *mem = instance->memories[0];
1580
- CallData call(env, instance, mem);
1581
-
1582
- if (!call.Prepare(&copy, info)) [[unlikely]]
1583
- return env.Null();
1584
-
1585
- if (instance->debug) {
1586
- call.DumpForward(&copy);
1587
- }
1588
-
1589
- // Execute call
1590
- {
1591
- K_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
1592
- exec_call = &call;
1593
-
1594
- call.Execute(&copy, native);
1595
- }
1596
-
1597
- return call.Complete(&copy);
1598
- }
1599
-
1600
- Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
1601
- {
1602
- FunctionInfo *func = (FunctionInfo *)info.Data();
1603
- return TranslateVariadicCall(func, func->native, info);
1604
- }
1605
-
1606
- class AsyncCall: public Napi::AsyncWorker {
1607
- Napi::Env env;
1608
-
1609
- const FunctionInfo *func;
1610
- void *native;
1611
-
1612
- CallData call;
1613
- bool prepared = false;
1614
-
1615
- public:
1616
- AsyncCall(Napi::Env env, InstanceData *instance, const FunctionInfo *func,
1617
- void *native, InstanceMemory *mem, Napi::Function &callback)
1618
- : Napi::AsyncWorker(callback), env(env), func(func->Ref()), native(native),
1619
- call(env, instance, mem) {}
1620
- ~AsyncCall() { func->Unref(); }
1621
-
1622
- bool Prepare(const Napi::CallbackInfo &info) {
1623
- prepared = call.Prepare(func, info);
1624
-
1625
- if (!prepared) {
1626
- Napi::Error err = env.GetAndClearPendingException();
1627
- SetError(err.Message());
1628
- }
1629
-
1630
- return prepared;
1631
- }
1632
- void DumpForward() { call.DumpForward(func); }
1633
-
1634
- void Execute() override;
1635
- void OnOK() override;
1636
- };
1637
-
1638
- void AsyncCall::Execute()
1639
- {
1640
- if (prepared) {
1641
- K_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
1642
- exec_call = &call;
1643
-
1644
- call.Execute(func, native);
1645
- }
1646
- }
1647
-
1648
- void AsyncCall::OnOK()
1649
- {
1650
- K_ASSERT(prepared);
1651
-
1652
- Napi::FunctionReference &callback = Callback();
1653
-
1654
- Napi::Value self = env.Null();
1655
- napi_value args[] = {
1656
- env.Null(),
1657
- call.Complete(func)
1658
- };
1659
-
1660
- callback.Call(self, K_LEN(args), args);
1661
- }
1662
-
1663
- static Napi::Value TranslateAsyncCall(const FunctionInfo *func, void *native,
1664
- const Napi::CallbackInfo &info)
1665
- {
1666
- K_ASSERT(!func->variadic);
1667
-
1668
- Napi::Env env = info.Env();
1669
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1670
-
1671
- if (info.Length() <= (uint32_t)func->required_parameters) {
1672
- ThrowError<Napi::TypeError>(env, "Expected %1 arguments, got %2", func->parameters.len + 1, info.Length());
1673
- return env.Null();
1674
- }
1675
-
1676
- Napi::Function callback = info[(uint32_t)func->required_parameters].As<Napi::Function>();
1677
-
1678
- if (!callback.IsFunction()) {
1679
- ThrowError<Napi::TypeError>(env, "Expected callback function as last argument, got %1", GetValueType(instance, callback));
1680
- return env.Null();
1681
- }
1682
-
1683
- InstanceMemory *mem = AllocateMemory(instance, instance->config.async_stack_size, instance->config.async_heap_size);
1684
- if (!mem) [[unlikely]] {
1685
- ThrowError<Napi::Error>(env, "Too many asynchronous calls are running");
1686
- return env.Null();
1687
- }
1688
- AsyncCall *async = new AsyncCall(env, instance, func, native, mem, callback);
1689
-
1690
- if (async->Prepare(info) && instance->debug) {
1691
- async->DumpForward();
1692
- }
1693
- async->Queue();
1694
-
1695
- return env.Undefined();
1696
- }
1697
-
1698
- Napi::Value TranslateAsyncCall(const Napi::CallbackInfo &info)
1699
- {
1700
- FunctionInfo *func = (FunctionInfo *)info.Data();
1701
- return TranslateAsyncCall(func, func->native, info);
1702
- }
1703
-
1704
- extern "C" void RelayCallback(Size idx, uint8_t *sp)
1705
- {
1706
- CallData *call = exec_call;
1707
-
1708
- // Try the fast path first: we are on the main thread and we are running a native call through Koffi.
1709
- // It should be easy, but in this case we are running on the custom Koffi stack, which will trip up
1710
- // Node and V8. So we need to switch back to the normal/main stack.
1711
- if (call && std::this_thread::get_id() == call->instance->main_thread_id) {
1712
- SwitchAndRelay(call, idx, sp, call->old_sp, &call->mem->stack);
1713
- return;
1714
- }
1715
-
1716
- // Otherwise, we need to allocate memory to perform the callback.
1717
- // Since the necessary machinery live in CallData, just use a temporary instance.
1718
- // In some cases we would reuse the existing call (exec_call may be not null),
1719
- // but it is rare so let's ignore this for simplicity.
1720
-
1721
- TrampolineInfo *trampoline = &shared.trampolines[idx];
1722
- Napi::Env env = trampoline->func.Env();
1723
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1724
-
1725
- InstanceMemory *mem = AllocateMemory(instance, instance->config.async_stack_size, instance->config.async_heap_size);
1726
- if (!mem) [[unlikely]] {
1727
- ThrowError<Napi::Error>(env, "Too many asynchronous calls are running");
1728
- return;
1729
- }
1730
-
1731
- if (std::this_thread::get_id() == instance->main_thread_id) {
1732
- CallData call(env, instance, mem);
1733
-
1734
- Napi::HandleScope scope(env);
1735
- call.Relay(idx, sp);
1736
- } else {
1737
- CallData call(env, instance, mem);
1738
- call.RelayAsync(idx, sp);
1739
- }
1740
- }
1741
-
1742
- extern "C" void RelayDirect(CallData *call, Size idx, uint8_t *sp)
1743
- {
1744
- TrampolineInfo *trampoline = &shared.trampolines[idx];
1745
- Napi::Env env = trampoline->func.Env();
1746
-
1747
- #if defined(_WIN32)
1748
- TEB *teb = GetTEB();
1749
- InstanceData *instance = trampoline->instance;
1750
-
1751
- // Restore previous stack limits at the end
1752
- K_DEFER_C(base = teb->StackBase,
1753
- limit = teb->StackLimit,
1754
- dealloc = teb->DeallocationStack) {
1755
- teb->StackBase = base;
1756
- teb->StackLimit = limit;
1757
- teb->DeallocationStack = dealloc;
1758
- };
1759
-
1760
- // Adjust stack limits so SEH works correctly
1761
- teb->StackBase = instance->main_stack_max;
1762
- teb->StackLimit = instance->main_stack_min;
1763
- teb->DeallocationStack = instance->main_stack_min;
1764
- #endif
1765
-
1766
- if (env.IsExceptionPending()) [[unlikely]]
1767
- return;
1768
- if (!trampoline->used) [[unlikely]] {
1769
- ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
1770
- return;
1771
- }
1772
-
1773
- Napi::HandleScope scope(call->env);
1774
- call->Relay(idx, sp);
1775
- }
1776
-
1777
- static Napi::Value FindLibraryFunction(const Napi::CallbackInfo &info)
1778
- {
1779
- Napi::Env env = info.Env();
1780
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1781
- LibraryHolder *lib = (LibraryHolder *)info.Data();
1782
-
1783
- FunctionInfo *func = new FunctionInfo();
1784
- K_DEFER { func->Unref(); };
1785
-
1786
- func->lib = lib->Ref();
1787
-
1788
- if (info.Length() >= 2) {
1789
- if (!ParseClassicFunction(info, true, func))
1790
- return env.Null();
1791
- } else if (info.Length() >= 1) {
1792
- if (!info[0].IsString()) {
1793
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for prototype, expected string", GetValueType(instance, info[0]));
1794
- return env.Null();
1795
- }
1796
-
1797
- std::string proto = info[0u].As<Napi::String>();
1798
- if (!ParsePrototype(env, proto.c_str(), true, func))
1799
- return env.Null();
1800
- } else {
1801
- ThrowError<Napi::TypeError>(env, "Expected 1 to 4 arguments, got %1", info.Length());
1802
- return env.Null();
1803
- }
1804
-
1805
- if (func->convention != CallConvention::Cdecl && func->variadic) {
1806
- LogError("Call convention '%1' does not support variadic functions, ignoring",
1807
- CallConventionNames[(int)func->convention]);
1808
- func->convention = CallConvention::Cdecl;
1809
- }
1810
-
1811
- if (!AnalyseFunction(env, instance, func))
1812
- return env.Null();
1813
- if (func->variadic) {
1814
- // Minimize reallocations
1815
- func->parameters.Grow(32);
1816
- }
1817
-
1818
- #if defined(_WIN32)
1819
- if (func->ordinal_name < 0) {
1820
- if (func->decorated_name) {
1821
- func->native = (void *)GetProcAddress((HMODULE)lib->module, func->decorated_name);
1822
- }
1823
- if (!func->native) {
1824
- func->native = (void *)GetProcAddress((HMODULE)lib->module, func->name);
1825
- }
1826
- } else {
1827
- uint16_t ordinal = (uint16_t)func->ordinal_name;
1828
-
1829
- func->decorated_name = nullptr;
1830
- func->native = (void *)GetProcAddress((HMODULE)lib->module, (LPCSTR)(size_t)ordinal);
1831
- }
1832
- #else
1833
- if (func->decorated_name) {
1834
- func->native = dlsym(lib->module, func->decorated_name);
1835
- }
1836
- if (!func->native) {
1837
- func->native = dlsym(lib->module, func->name);
1838
- }
1839
- #endif
1840
- if (!func->native) {
1841
- ThrowError<Napi::Error>(env, "Cannot find function '%1' in shared library", func->name);
1842
- return env.Null();
1843
- }
1844
-
1845
- Napi::Function wrapper = WrapFunction(env, func);
1846
- return wrapper;
1847
- }
1848
-
1849
- static Napi::Value FindSymbol(const Napi::CallbackInfo &info)
1850
- {
1851
- Napi::Env env = info.Env();
1852
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1853
- LibraryHolder *lib = (LibraryHolder *)info.Data();
1854
-
1855
- if (info.Length() < 2) {
1856
- ThrowError<Napi::TypeError>(env, "Expected 2, got %1", info.Length());
1857
- return env.Null();
1858
- }
1859
- if (!info[0].IsString()) {
1860
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
1861
- return env.Null();
1862
- }
1863
-
1864
- std::string name = info[0].As<Napi::String>();
1865
-
1866
- const TypeInfo *type = ResolveType(info[1]);
1867
- if (!type)
1868
- return env.Null();
1869
-
1870
- #if defined(_WIN32)
1871
- void *ptr = (void *)GetProcAddress((HMODULE)lib->module, name.c_str());
1872
- #else
1873
- void *ptr = (void *)dlsym(lib->module, name.c_str());
1874
- #endif
1875
- if (!ptr) {
1876
- ThrowError<Napi::Error>(env, "Cannot find symbol '%1' in shared library", name.c_str());
1877
- return env.Null();
1878
- }
1879
-
1880
- Napi::External<void> external = Napi::External<void>::New(env, ptr);
1881
- SetValueTag(external, &type);
1882
-
1883
- return external;
1884
- }
1885
-
1886
- static Napi::Value UnloadLibrary(const Napi::CallbackInfo &info)
1887
- {
1888
- Napi::Env env = info.Env();
1889
- LibraryHolder *lib = (LibraryHolder *)info.Data();
1890
-
1891
- lib->Unload();
1892
-
1893
- return env.Undefined();
1894
- }
1895
-
1896
- static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
1897
- {
1898
- Napi::Env env = info.Env();
1899
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1900
-
1901
- if (info.Length() < 1) {
1902
- ThrowError<Napi::TypeError>(env, "Expected 1 or 2 arguments, got %1", info.Length());
1903
- return env.Null();
1904
- }
1905
- if (!info[0].IsString() && !IsNullOrUndefined(info[0])) {
1906
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for filename, expected string or null", GetValueType(instance, info[0]));
1907
- return env.Null();
1908
- }
1909
- if (info.Length() >= 2 && !IsObject(info[1])) {
1910
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for options, expected object", GetValueType(instance, info[1]));
1911
- return env.Null();
1912
- }
1913
-
1914
- #if !defined(_WIN32)
1915
- int flags = 0;
1916
-
1917
- if (info.Length() >= 2) {
1918
- Napi::Object options = info[1].As<Napi::Object>();
1919
-
1920
- flags |= options.Get("lazy").ToBoolean() ? RTLD_LAZY : RTLD_NOW;
1921
- flags |= options.Get("global").ToBoolean() ? RTLD_GLOBAL : RTLD_LOCAL;
1922
- #if defined(RTLD_DEEPBIND)
1923
- flags |= options.Get("deep").ToBoolean() ? RTLD_DEEPBIND : 0;
1924
- #endif
1925
- } else {
1926
- flags = RTLD_NOW | RTLD_LOCAL;
1927
- }
1928
- #endif
1929
-
1930
- if (!instance->memories.len) {
1931
- AllocateMemory(instance, instance->config.sync_stack_size, instance->config.sync_heap_size);
1932
- K_ASSERT(instance->memories.len == 1);
1933
- }
1934
-
1935
- // Load shared library
1936
- void *module = nullptr;
1937
- #if defined(_WIN32)
1938
- if (info[0].IsString()) {
1939
- std::string filename = info[0].As<Napi::String>();
1940
- module = LoadWindowsLibrary(env, filename.c_str());
1941
-
1942
- if (!module)
1943
- return env.Null();
1944
- } else {
1945
- module = GetModuleHandle(nullptr);
1946
- K_ASSERT(module);
1947
- }
1948
- #else
1949
- if (info[0].IsString()) {
1950
- std::string filename = info[0].As<Napi::String>();
1951
- module = dlopen(filename.c_str(), flags);
1952
-
1953
- if (!module) {
1954
- const char *msg = dlerror();
1955
-
1956
- if (StartsWith(msg, filename.c_str())) {
1957
- msg += filename.length();
1958
-
1959
- while (strchr(": ", msg[0]) && msg[0]) {
1960
- msg++;
1961
- }
1962
- }
1963
-
1964
- ThrowError<Napi::Error>(env, "Failed to load shared library: %1", msg);
1965
- return env.Null();
1966
- }
1967
- } else {
1968
- module = RTLD_DEFAULT;
1969
- }
1970
- #endif
1971
-
1972
- LibraryHolder *lib = new LibraryHolder(module);
1973
- K_DEFER { lib->Unref(); };
1974
-
1975
- Napi::Object obj = Napi::Object::New(env);
1976
-
1977
- #define ADD_METHOD(Name, Call) \
1978
- do { \
1979
- const auto wrapper = [](const Napi::CallbackInfo &info) { return Call; }; \
1980
- Napi::Function func = Napi::Function::New(env, wrapper, (Name), (void *)lib->Ref()); \
1981
- func.AddFinalizer([](Napi::Env, LibraryHolder *lib) { lib->Unref(); }, lib); \
1982
- obj.Set((Name), func); \
1983
- } while (false)
1984
-
1985
- ADD_METHOD("func", FindLibraryFunction(info));
1986
- ADD_METHOD("symbol", FindSymbol(info));
1987
-
1988
- // We can't unref the library after unload, obviously
1989
- obj.Set("unload", Napi::Function::New(env, UnloadLibrary, "unload", (void *)lib->Ref()));
1990
-
1991
- #undef ADD_METHOD
1992
-
1993
- return obj;
1994
- }
1995
-
1996
- static Napi::Value RegisterCallback(const Napi::CallbackInfo &info)
1997
- {
1998
- Napi::Env env = info.Env();
1999
- InstanceData *instance = env.GetInstanceData<InstanceData>();
2000
-
2001
- if (!InitAsyncBroker(env, instance)) [[unlikely]]
2002
- return env.Null();
2003
-
2004
- bool has_recv = (info.Length() >= 3 && info[1].IsFunction());
2005
-
2006
- if (info.Length() < 2u + has_recv) {
2007
- ThrowError<Napi::TypeError>(env, "Expected 2 or 3 arguments, got %1", info.Length());
2008
- return env.Null();
2009
- }
2010
- if (!info[0u + has_recv].IsFunction()) {
2011
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for func, expected function", GetValueType(instance, info[0 + has_recv]));
2012
- return env.Null();
2013
- }
2014
-
2015
- Napi::Value recv = has_recv ? info[0] : env.Undefined();
2016
- Napi::Function func = info[0u + has_recv].As<Napi::Function>();
2017
-
2018
- const TypeInfo *type = ResolveType(info[1u + has_recv]);
2019
- if (!type)
2020
- return env.Null();
2021
- if (type->primitive != PrimitiveKind::Callback) {
2022
- ThrowError<Napi::TypeError>(env, "Unexpected %1 type, expected <callback> * type", type->name);
2023
- return env.Null();
2024
- }
2025
-
2026
- int16_t idx;
2027
- {
2028
- std::lock_guard<std::mutex> lock(shared.mutex);
2029
-
2030
- if (!shared.available.len) [[unlikely]] {
2031
- ThrowError<Napi::Error>(env, "Too many callbacks are in use (max = %1)", MaxTrampolines);
2032
- return env.Null();
2033
- }
2034
-
2035
- idx = shared.available.data[--shared.available.len];
2036
- }
2037
-
2038
- TrampolineInfo *trampoline = &shared.trampolines[idx];
2039
-
2040
- trampoline->instance = instance;
2041
- trampoline->proto = type->ref.proto;
2042
- trampoline->func.Reset(func, 1);
2043
- if (!IsNullOrUndefined(recv)) {
2044
- trampoline->recv.Reset(recv, 1);
2045
- } else {
2046
- trampoline->recv.Reset();
2047
- }
2048
- trampoline->used = true;
2049
-
2050
- void *ptr = GetTrampoline(idx);
2051
-
2052
- Napi::External<void> external = Napi::External<void>::New(env, ptr);
2053
- SetValueTag(external, type->ref.marker);
2054
-
2055
- // Cache index for fast unregistration
2056
- instance->trampolines_map.Set(ptr, idx);
2057
-
2058
- return external;
2059
- }
2060
-
2061
- static Napi::Value UnregisterCallback(const Napi::CallbackInfo &info)
2062
- {
2063
- Napi::Env env = info.Env();
2064
- InstanceData *instance = env.GetInstanceData<InstanceData>();
2065
-
2066
- if (info.Length() < 1) {
2067
- ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
2068
- return env.Null();
2069
- }
2070
- if (!info[0].IsExternal()) {
2071
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for id, expected registered callback", GetValueType(instance, info[0]));
2072
- return env.Null();
2073
- }
2074
-
2075
- Napi::External<void> external = info[0].As<Napi::External<void>>();
2076
- void *ptr = external.Data();
2077
-
2078
- int16_t idx;
2079
- {
2080
- int16_t *it = instance->trampolines_map.Find(ptr);
2081
-
2082
- if (!it) [[unlikely]] {
2083
- ThrowError<Napi::Error>(env, "Could not find matching registered callback");
2084
- return env.Null();
2085
- }
2086
-
2087
- idx = *it;
2088
- instance->trampolines_map.Remove(it);
2089
- }
2090
-
2091
- // Release shared trampoline safely
2092
- {
2093
- std::lock_guard<std::mutex> lock(shared.mutex);
2094
-
2095
- TrampolineInfo *trampoline = &shared.trampolines[idx];
2096
- K_ASSERT(!trampoline->func.IsEmpty());
2097
-
2098
- trampoline->func.Reset();
2099
- trampoline->recv.Reset();
2100
- trampoline->used = false;
2101
-
2102
- shared.available.Append(idx);
2103
- }
2104
-
2105
- return env.Undefined();
2106
- }
2107
-
2108
- static Napi::Value CastValue(const Napi::CallbackInfo &info)
2109
- {
2110
- Napi::Env env = info.Env();
2111
-
2112
- if (info.Length() < 2) [[unlikely]] {
2113
- ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
2114
- return env.Null();
2115
- }
2116
-
2117
- Napi::Value value = info[0];
2118
-
2119
- const TypeInfo *type = ResolveType(info[1]);
2120
- if (!type) [[unlikely]]
2121
- return env.Null();
2122
- if (type->primitive != PrimitiveKind::Pointer &&
2123
- type->primitive != PrimitiveKind::Callback &&
2124
- type->primitive != PrimitiveKind::String &&
2125
- type->primitive != PrimitiveKind::String16 &&
2126
- type->primitive != PrimitiveKind::String32) [[unlikely]] {
2127
- ThrowError<Napi::TypeError>(env, "Only pointer or string types can be used for casting");
2128
- return env.Null();
2129
- }
2130
-
2131
- ValueCast *cast = new ValueCast;
2132
-
2133
- cast->ref.Reset(value, 1);
2134
- cast->type = type;
2135
-
2136
- Napi::External<ValueCast> external = Napi::External<ValueCast>::New(env, cast, [](Napi::Env, ValueCast *cast) { delete cast; });
2137
- SetValueTag(external, &CastMarker);
2138
-
2139
- return external;
2140
- }
2141
-
2142
- static Napi::Value DecodeValue(const Napi::CallbackInfo &info)
2143
- {
2144
- Napi::Env env = info.Env();
2145
-
2146
- bool has_offset = (info.Length() >= 2 && info[1].IsNumber());
2147
- bool has_len = (info.Length() >= 3u + has_offset && info[2 + has_offset].IsNumber());
2148
-
2149
- if (info.Length() < 2u + has_offset) [[unlikely]] {
2150
- ThrowError<Napi::TypeError>(env, "Expected %1 to 4 arguments, got %2", 2 + has_offset, info.Length());
2151
- return env.Null();
2152
- }
2153
-
2154
- const TypeInfo *type = ResolveType(info[1u + has_offset]);
2155
- if (!type) [[unlikely]]
2156
- return env.Null();
2157
-
2158
- Napi::Value value = info[0];
2159
- int64_t offset = has_offset ? info[1].As<Napi::Number>().Int64Value() : 0;
2160
-
2161
- if (has_len) {
2162
- Size len = info[2 + has_offset].As<Napi::Number>();
2163
-
2164
- Napi::Value ret = Decode(value, offset, type, &len);
2165
- return ret;
2166
- } else {
2167
- Napi::Value ret = Decode(value, offset, type);
2168
- return ret;
2169
- }
2170
- }
2171
-
2172
- static Napi::Value GetPointerAddress(const Napi::CallbackInfo &info)
2173
- {
2174
- Napi::Env env = info.Env();
2175
-
2176
- if (info.Length() < 1) {
2177
- ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
2178
- return env.Null();
2179
- }
2180
-
2181
- void *ptr = nullptr;
2182
- if (!GetExternalPointer(env, info[0], &ptr))
2183
- return env.Null();
2184
-
2185
- uint64_t ptr64 = (uint64_t)(uintptr_t)ptr;
2186
- Napi::BigInt bigint = Napi::BigInt::New(env, ptr64);
2187
-
2188
- return bigint;
2189
- }
2190
-
2191
- static Napi::Value CallPointerSync(const Napi::CallbackInfo &info)
2192
- {
2193
- Napi::Env env = info.Env();
2194
- InstanceData *instance = env.GetInstanceData<InstanceData>();
2195
-
2196
- if (info.Length() < 2) [[unlikely]] {
2197
- ThrowError<Napi::TypeError>(env, "Expected 2 or more arguments, got %1", info.Length());
2198
- return env.Null();
2199
- }
2200
-
2201
- void *ptr = nullptr;
2202
- if (!GetExternalPointer(env, info[0], &ptr)) [[unlikely]]
2203
- return env.Null();
2204
-
2205
- const TypeInfo *type = ResolveType(info[1]);
2206
- if (!type) [[unlikely]]
2207
- return env.Null();
2208
- if (type->primitive != PrimitiveKind::Prototype) [[unlikely]] {
2209
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for type, expected function type", GetValueType(instance, info[1]));
2210
- return env.Null();
2211
- }
2212
-
2213
- const FunctionInfo *proto = type->ref.proto;
2214
-
2215
- return proto->variadic ? TranslateVariadicCall(proto, ptr, info)
2216
- : TranslateNormalCall(proto, ptr, info);
2217
- }
2218
-
2219
- static Napi::Value EncodeValue(const Napi::CallbackInfo &info)
2220
- {
2221
- Napi::Env env = info.Env();
2222
-
2223
- bool has_offset = (info.Length() >= 2 && info[1].IsNumber());
2224
- bool has_len = (info.Length() >= 4u + has_offset && info[3 + has_offset].IsNumber());
2225
-
2226
- if (info.Length() < 3u + has_offset) [[unlikely]] {
2227
- ThrowError<Napi::TypeError>(env, "Expected %1 to 5 arguments, got %2", 3 + has_offset, info.Length());
2228
- return env.Null();
2229
- }
2230
-
2231
- const TypeInfo *type = ResolveType(info[1u + has_offset]);
2232
- if (!type) [[unlikely]]
2233
- return env.Null();
2234
-
2235
- Napi::Value ref = info[0];
2236
- int64_t offset = has_offset ? info[1].As<Napi::Number>().Int64Value() : 0;
2237
- Napi::Value value = info[2 + has_offset];
2238
-
2239
- if (has_len) {
2240
- Size len = info[3 + has_offset].As<Napi::Number>();
2241
-
2242
- if (!Encode(ref, offset, value, type, &len))
2243
- return env.Null();
2244
- } else {
2245
- if (!Encode(ref, offset, value, type))
2246
- return env.Null();
2247
- }
2248
-
2249
- return env.Undefined();
2250
- }
2251
-
2252
- static Napi::Value CreateView(const Napi::CallbackInfo &info)
2253
- {
2254
- Napi::Env env = info.Env();
2255
- InstanceData *instance = env.GetInstanceData<InstanceData>();
2256
-
2257
- if (info.Length() < 1) {
2258
- ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
2259
- return env.Null();
2260
- }
2261
- if (!info[1].IsNumber()) {
2262
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for length, expected integer", GetValueType(instance, info[1]));
2263
- return env.Null();
2264
- }
2265
-
2266
- void *ptr = nullptr;
2267
- if (!GetExternalPointer(env, info[0], &ptr))
2268
- return env.Null();
2269
- Size len = (Size)info[1].As<Napi::Number>().Int64Value();
2270
-
2271
- if (len < 0) {
2272
- ThrowError<Napi::TypeError>(env, "Array length must be positive and non-zero");
2273
- return env.Null();
2274
- }
2275
-
2276
- if (len) {
2277
- Napi::ArrayBuffer view = Napi::ArrayBuffer::New(env, ptr, (size_t)len);
2278
-
2279
- if (!view.ByteLength()) {
2280
- ThrowError<Napi::Error>(env, "This runtime does not support external buffers");
2281
- return env.Null();
2282
- }
2283
-
2284
- return view;
2285
- } else {
2286
- return Napi::ArrayBuffer::New(env, 0);
2287
- }
2288
- }
2289
-
2290
- static Napi::Value ResetKoffi(const Napi::CallbackInfo &info)
2291
- {
2292
- Napi::Env env = info.Env();
2293
- InstanceData *instance = env.GetInstanceData<InstanceData>();
2294
-
2295
- if (instance->broker) {
2296
- napi_release_threadsafe_function(instance->broker, napi_tsfn_abort);
2297
- instance->broker = nullptr;
2298
- }
2299
-
2300
- instance->types.RemoveFrom(instance->base_types_count);
2301
-
2302
- {
2303
- HashSet<const void *> base_types;
2304
- HashMap<const char *, const TypeInfo *> new_map;
2305
-
2306
- for (const TypeInfo &type: instance->types) {
2307
- base_types.Set(&type);
2308
- }
2309
-
2310
- for (const auto &bucket: instance->types_map.table) {
2311
- if (base_types.Find(bucket.value)) {
2312
- new_map.Set(bucket.key, bucket.value);
2313
- }
2314
- }
2315
-
2316
- std::swap(instance->types_map, new_map);
2317
- }
2318
-
2319
- instance->callbacks.Clear();
2320
-
2321
- return env.Undefined();
2322
- }
2323
-
2324
- void LibraryHolder::Unload()
2325
- {
2326
- #if defined(_WIN32)
2327
- if (module && module != GetModuleHandle(nullptr)) {
2328
- FreeLibrary((HMODULE)module);
2329
- }
2330
- #else
2331
- if (module && module != RTLD_DEFAULT) {
2332
- dlclose(module);
2333
- }
2334
- #endif
2335
-
2336
- module = nullptr;
2337
- }
2338
-
2339
- const LibraryHolder *LibraryHolder::Ref() const
2340
- {
2341
- refcount++;
2342
- return this;
2343
- }
2344
-
2345
- void LibraryHolder::Unref() const
2346
- {
2347
- if (!--refcount) {
2348
- delete this;
2349
- }
2350
- }
2351
-
2352
- FunctionInfo::~FunctionInfo()
2353
- {
2354
- if (lib) {
2355
- lib->Unref();
2356
- }
2357
- }
2358
-
2359
- const FunctionInfo *FunctionInfo::Ref() const
2360
- {
2361
- refcount++;
2362
- return this;
2363
- }
2364
-
2365
- void FunctionInfo::Unref() const
2366
- {
2367
- if (!--refcount) {
2368
- delete this;
2369
- }
2370
- }
2371
-
2372
- InstanceMemory::~InstanceMemory()
2373
- {
2374
- #if defined(_WIN32)
2375
- if (stack.ptr) {
2376
- VirtualFree(stack.ptr, 0, MEM_RELEASE);
2377
- }
2378
- if (heap.ptr) {
2379
- VirtualFree(heap.ptr, 0, MEM_RELEASE);
2380
- }
2381
- #else
2382
- if (stack.ptr) {
2383
- munmap(stack.ptr, stack.len);
2384
- }
2385
- if (heap.ptr) {
2386
- munmap(heap.ptr, heap.len);
2387
- }
2388
- #endif
2389
- }
2390
-
2391
- bool InitAsyncBroker(Napi::Env env, InstanceData *instance)
2392
- {
2393
- if (!instance->broker) {
2394
- if (napi_create_threadsafe_function(env, nullptr, nullptr,
2395
- Napi::String::New(env, "Koffi Async Callback Broker"),
2396
- 0, 1, nullptr, nullptr, nullptr,
2397
- PerformAsyncRelay, &instance->broker) != napi_ok) {
2398
- LogError("Failed to create async callback broker");
2399
- return false;
2400
- }
2401
- napi_unref_threadsafe_function(env, instance->broker);
2402
- }
2403
-
2404
- return true;
2405
- }
2406
-
2407
- static void RegisterPrimitiveType(Napi::Env env, Napi::Object map, std::initializer_list<const char *> names,
2408
- PrimitiveKind primitive, int32_t size, int16_t align, const char *ref = nullptr)
2409
- {
2410
- K_ASSERT(names.size() > 0);
2411
- K_ASSERT(align <= size);
2412
-
2413
- InstanceData *instance = env.GetInstanceData<InstanceData>();
2414
-
2415
- TypeInfo *type = instance->types.AppendDefault();
2416
-
2417
- type->name = *names.begin();
2418
-
2419
- type->primitive = primitive;
2420
- type->size = size;
2421
- type->align = align;
2422
-
2423
- if (IsInteger(type) || IsFloat(type)) {
2424
- type->flags |= (int)TypeFlag::HasTypedArray;
2425
- }
2426
- if (TestStr(type->name, "char") ||
2427
- TestStr(type->name, "char16") || TestStr(type->name, "char16_t") ||
2428
- TestStr(type->name, "char32") || TestStr(type->name, "char32_t") ||
2429
- TestStr(type->name, "wchar") || TestStr(type->name, "wchar_t")) {
2430
- type->flags |= (int)TypeFlag::IsCharLike;
2431
- }
2432
-
2433
- if (ref) {
2434
- const TypeInfo *marker = instance->types_map.FindValue(ref, nullptr);
2435
- K_ASSERT(marker);
2436
-
2437
- type->ref.marker = marker;
2438
- }
2439
-
2440
- Napi::Value wrapper = WrapType(env, type);
2441
-
2442
- for (const char *name: names) {
2443
- bool inserted;
2444
- instance->types_map.InsertOrGet(name, type, &inserted);
2445
- K_ASSERT(inserted);
2446
-
2447
- if (!EndsWith(name, "*")) {
2448
- map.Set(name, wrapper);
2449
- }
2450
- }
2451
- }
2452
-
2453
- static inline PrimitiveKind GetSignPrimitive(Size len, bool sign)
2454
- {
2455
- switch (len) {
2456
- case 1: return sign ? PrimitiveKind::Int8 : PrimitiveKind::UInt8;
2457
- case 2: return sign ? PrimitiveKind::Int16 : PrimitiveKind::UInt16;
2458
- case 4: return sign ? PrimitiveKind::Int32 : PrimitiveKind::UInt32;
2459
- case 8: return sign ? PrimitiveKind::Int64 : PrimitiveKind::UInt64;
2460
- }
2461
-
2462
- K_UNREACHABLE();
2463
- }
2464
-
2465
- static inline PrimitiveKind GetLittleEndianPrimitive(PrimitiveKind kind)
2466
- {
2467
- #if defined(K_BIG_ENDIAN)
2468
- return (PrimitiveKind)((int)kind + 1);
2469
- #else
2470
- return kind;
2471
- #endif
2472
- }
2473
-
2474
- static inline PrimitiveKind GetBigEndianPrimitive(PrimitiveKind kind)
2475
- {
2476
- #if defined(K_BIG_ENDIAN)
2477
- return kind;
2478
- #else
2479
- return (PrimitiveKind)((int)kind + 1);
2480
- #endif
2481
- }
2482
-
2483
- static InstanceData *CreateInstance()
2484
- {
2485
- InstanceData *instance = new InstanceData();
2486
- K_DEFER_N(err_guard) { delete instance; };
2487
-
2488
- instance->main_thread_id = std::this_thread::get_id();
2489
-
2490
- instance->debug = GetDebugFlag("DUMP_CALLS");
2491
-
2492
- #if defined(_WIN32)
2493
- TEB *teb = GetTEB();
2494
-
2495
- instance->main_stack_max = teb->StackBase;
2496
- instance->main_stack_min = teb->DeallocationStack;
2497
- #endif
2498
-
2499
- err_guard.Disable();
2500
- return instance;
2501
- }
2502
-
2503
- static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2504
- {
2505
- InstanceData *instance = CreateInstance();
2506
- K_CRITICAL(instance, "Failed to initialize Koffi");
2507
-
2508
- env.SetInstanceData(instance);
2509
-
2510
- exports.Set("config", Napi::Function::New(env, GetSetConfig, "config"));
2511
- exports.Set("stats", Napi::Function::New(env, GetStats, "stats"));
2512
-
2513
- exports.Set("struct", Napi::Function::New(env, CreatePaddedStructType, "struct"));
2514
- exports.Set("pack", Napi::Function::New(env, CreatePackedStructType, "pack"));
2515
- exports.Set("union", Napi::Function::New(env, CreateUnionType, "union"));
2516
- exports.Set("Union", Napi::Function::New(env, InstantiateUnion, "Union"));
2517
- exports.Set("opaque", Napi::Function::New(env, CreateOpaqueType, "opaque"));
2518
- exports.Set("pointer", Napi::Function::New(env, CreatePointerType, "pointer"));
2519
- exports.Set("array", Napi::Function::New(env, CreateArrayType, "array"));
2520
- exports.Set("proto", Napi::Function::New(env, CreateFunctionType, "proto"));
2521
- exports.Set("alias", Napi::Function::New(env, CreateTypeAlias, "alias"));
2522
-
2523
- exports.Set("sizeof", Napi::Function::New(env, GetTypeSize, "sizeof"));
2524
- exports.Set("alignof", Napi::Function::New(env, GetTypeAlign, "alignof"));
2525
- exports.Set("offsetof", Napi::Function::New(env, GetMemberOffset, "offsetof"));
2526
- exports.Set("resolve", Napi::Function::New(env, GetResolvedType, "resolve"));
2527
- exports.Set("introspect", Napi::Function::New(env, GetTypeDefinition, "introspect"));
2528
-
2529
- exports.Set("load", Napi::Function::New(env, LoadSharedLibrary, "load"));
2530
-
2531
- exports.Set("in", Napi::Function::New(env, MarkIn, "in"));
2532
- exports.Set("out", Napi::Function::New(env, MarkOut, "out"));
2533
- exports.Set("inout", Napi::Function::New(env, MarkInOut, "inout"));
2534
-
2535
- exports.Set("disposable", Napi::Function::New(env, CreateDisposableType, "disposable"));
2536
- exports.Set("alloc", Napi::Function::New(env, CallAlloc, "alloc"));
2537
- exports.Set("free", Napi::Function::New(env, CallFree, "free"));
2538
-
2539
- exports.Set("register", Napi::Function::New(env, RegisterCallback, "register"));
2540
- exports.Set("unregister", Napi::Function::New(env, UnregisterCallback, "unregister"));
2541
-
2542
- exports.Set("as", Napi::Function::New(env, CastValue, "as"));
2543
- exports.Set("decode", Napi::Function::New(env, DecodeValue, "decode"));
2544
- exports.Set("address", Napi::Function::New(env, GetPointerAddress, "address"));
2545
- exports.Set("call", Napi::Function::New(env, CallPointerSync, "call"));
2546
- exports.Set("encode", Napi::Function::New(env, EncodeValue, "encode"));
2547
- exports.Set("view", Napi::Function::New(env, CreateView, "view"));
2548
-
2549
- exports.Set("reset", Napi::Function::New(env, ResetKoffi, "reset"));
2550
-
2551
- exports.Set("errno", Napi::Function::New(env, GetOrSetErrNo, "errno"));
2552
-
2553
- // Export useful OS info
2554
- {
2555
- Napi::Object os = Napi::Object::New(env);
2556
- exports.Set("os", os);
2557
-
2558
- Napi::Object codes = Napi::Object::New(env);
2559
-
2560
- for (const ErrnoCodeInfo &info: ErrnoCodes) {
2561
- codes.Set(info.name, Napi::Number::New(env, info.value));
2562
- }
2563
-
2564
- os.Set("errno", codes);
2565
- }
2566
-
2567
- #if defined(_WIN32)
2568
- exports.Set("extension", Napi::String::New(env, ".dll"));
2569
- #elif defined(__APPLE__)
2570
- exports.Set("extension", Napi::String::New(env, ".dylib"));
2571
- #else
2572
- exports.Set("extension", Napi::String::New(env, ".so"));
2573
- #endif
2574
-
2575
- // Init base types
2576
- {
2577
- Napi::Object types = Napi::Object::New(env);
2578
- exports.Set("types", types);
2579
-
2580
- RegisterPrimitiveType(env, types, {"void"}, PrimitiveKind::Void, 0, 0);
2581
- RegisterPrimitiveType(env, types, {"bool"}, PrimitiveKind::Bool, K_SIZE(bool), alignof(bool));
2582
- RegisterPrimitiveType(env, types, {"int8_t", "int8"}, PrimitiveKind::Int8, 1, 1);
2583
- RegisterPrimitiveType(env, types, {"uint8_t", "uint8"}, PrimitiveKind::UInt8, 1, 1);
2584
- RegisterPrimitiveType(env, types, {"char"}, PrimitiveKind::Int8, 1, 1);
2585
- RegisterPrimitiveType(env, types, {"unsigned char", "uchar"}, PrimitiveKind::UInt8, 1, 1);
2586
- RegisterPrimitiveType(env, types, {"char16_t", "char16"}, PrimitiveKind::Int16, 2, 2);
2587
- RegisterPrimitiveType(env, types, {"char32_t", "char32"}, PrimitiveKind::Int32, 4, 4);
2588
- if (K_SIZE(wchar_t) == 2) {
2589
- RegisterPrimitiveType(env, types, {"wchar_t", "wchar"}, PrimitiveKind::Int16, 2, 2);
2590
- } else if (K_SIZE(wchar_t) == 4) {
2591
- RegisterPrimitiveType(env, types, {"wchar_t", "wchar"}, PrimitiveKind::Int32, 4, 4);
2592
- }
2593
- RegisterPrimitiveType(env, types, {"int16_t", "int16"}, PrimitiveKind::Int16, 2, 2);
2594
- RegisterPrimitiveType(env, types, {"int16_le_t", "int16_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int16), 2, 2);
2595
- RegisterPrimitiveType(env, types, {"int16_be_t", "int16_be"}, GetBigEndianPrimitive(PrimitiveKind::Int16), 2, 2);
2596
- RegisterPrimitiveType(env, types, {"uint16_t", "uint16"}, PrimitiveKind::UInt16, 2, 2);
2597
- RegisterPrimitiveType(env, types, {"uint16_le_t", "uint16_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt16), 2, 2);
2598
- RegisterPrimitiveType(env, types, {"uint16_be_t", "uint16_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt16), 2, 2);
2599
- RegisterPrimitiveType(env, types, {"short"}, PrimitiveKind::Int16, 2, 2);
2600
- RegisterPrimitiveType(env, types, {"unsigned short", "ushort"}, PrimitiveKind::UInt16, 2, 2);
2601
- RegisterPrimitiveType(env, types, {"int32_t", "int32"}, PrimitiveKind::Int32, 4, 4);
2602
- RegisterPrimitiveType(env, types, {"int32_le_t", "int32_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int32), 4, 4);
2603
- RegisterPrimitiveType(env, types, {"int32_be_t", "int32_be"}, GetBigEndianPrimitive(PrimitiveKind::Int32), 4, 4);
2604
- RegisterPrimitiveType(env, types, {"uint32_t", "uint32"}, PrimitiveKind::UInt32, 4, 4);
2605
- RegisterPrimitiveType(env, types, {"uint32_le_t", "uint32_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt32), 4, 4);
2606
- RegisterPrimitiveType(env, types, {"uint32_be_t", "uint32_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt32), 4, 4);
2607
- RegisterPrimitiveType(env, types, {"int"}, PrimitiveKind::Int32, 4, 4);
2608
- RegisterPrimitiveType(env, types, {"unsigned int", "uint"}, PrimitiveKind::UInt32, 4, 4);
2609
- RegisterPrimitiveType(env, types, {"int64_t", "int64"}, PrimitiveKind::Int64, 8, alignof(int64_t));
2610
- RegisterPrimitiveType(env, types, {"int64_le_t", "int64_le"}, GetLittleEndianPrimitive(PrimitiveKind::Int64), 8, alignof(int64_t));
2611
- RegisterPrimitiveType(env, types, {"int64_be_t", "int64_be"}, GetBigEndianPrimitive(PrimitiveKind::Int64), 8, alignof(int64_t));
2612
- RegisterPrimitiveType(env, types, {"uint64_t", "uint64"}, PrimitiveKind::UInt64, 8, alignof(int64_t));
2613
- RegisterPrimitiveType(env, types, {"uint64_le_t", "uint64_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
2614
- RegisterPrimitiveType(env, types, {"uint64_be_t", "uint64_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
2615
- RegisterPrimitiveType(env, types, {"intptr_t", "intptr"}, GetSignPrimitive(K_SIZE(intptr_t), true), K_SIZE(intptr_t), alignof(intptr_t));
2616
- RegisterPrimitiveType(env, types, {"uintptr_t", "uintptr"}, GetSignPrimitive(K_SIZE(intptr_t), false), K_SIZE(intptr_t), alignof(intptr_t));
2617
- RegisterPrimitiveType(env, types, {"size_t"}, GetSignPrimitive(K_SIZE(size_t), false), K_SIZE(size_t), alignof(size_t));
2618
- RegisterPrimitiveType(env, types, {"long"}, GetSignPrimitive(K_SIZE(long), true), K_SIZE(long), alignof(long));
2619
- RegisterPrimitiveType(env, types, {"unsigned long", "ulong"}, GetSignPrimitive(K_SIZE(long), false), K_SIZE(long), alignof(long));
2620
- RegisterPrimitiveType(env, types, {"long long", "longlong"}, PrimitiveKind::Int64, K_SIZE(int64_t), alignof(int64_t));
2621
- RegisterPrimitiveType(env, types, {"unsigned long long", "ulonglong"}, PrimitiveKind::UInt64, K_SIZE(uint64_t), alignof(uint64_t));
2622
- RegisterPrimitiveType(env, types, {"float", "float32"}, PrimitiveKind::Float32, 4, alignof(float));
2623
- RegisterPrimitiveType(env, types, {"double", "float64"}, PrimitiveKind::Float64, 8, alignof(double));
2624
- RegisterPrimitiveType(env, types, {"char *", "str", "string"}, PrimitiveKind::String, K_SIZE(void *), alignof(void *), "char");
2625
- RegisterPrimitiveType(env, types, {"char16_t *", "char16 *", "str16", "string16"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "char16_t");
2626
- RegisterPrimitiveType(env, types, {"char32_t *", "char32 *", "str32", "string32"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "char32_t");
2627
- if (K_SIZE(wchar_t) == 2) {
2628
- RegisterPrimitiveType(env, types, {"wchar_t *", "wchar *"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "wchar_t");
2629
- } else if (K_SIZE(wchar_t) == 4) {
2630
- RegisterPrimitiveType(env, types, {"wchar_t *", "wchar *"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "wchar_t");
2631
- }
2632
-
2633
- instance->void_type = instance->types_map.FindValue("void", nullptr);
2634
- instance->char_type = instance->types_map.FindValue("char", nullptr);
2635
- instance->char16_type = instance->types_map.FindValue("char16", nullptr);
2636
- instance->char32_type = instance->types_map.FindValue("char32", nullptr);
2637
- instance->str_type = instance->types_map.FindValue("char *", nullptr);
2638
- instance->str16_type = instance->types_map.FindValue("char16_t *", nullptr);
2639
- instance->str32_type = instance->types_map.FindValue("char32_t *", nullptr);
2640
-
2641
- Napi::Symbol symbol = Napi::Symbol::New(env, "active");
2642
- instance->active_symbol.Reset(symbol, 1);
2643
-
2644
- instance->base_types_count = instance->types.count;
2645
- }
2646
-
2647
- // Expose internal Node stuff
2648
- {
2649
- Napi::Object node = Napi::Object::New(env);
2650
- exports.Set("node", node);
2651
-
2652
- Napi::External<void> external = Napi::External<void>::New(env, (napi_env)env);
2653
- SetValueTag(external, instance->void_type);
2654
-
2655
- node.Set("env", external);
2656
-
2657
- node.Set("poll", Napi::Function::New(env, &Poll, "poll"));
2658
- node.Set("PollHandle", PollHandle::Define(env));
2659
- }
2660
-
2661
- exports.Set("version", Napi::String::New(env, K_STRINGIFY(VERSION)));
2662
-
2663
- napi_add_env_cleanup_hook(env, [](void *udata) {
2664
- InstanceData *instance = (InstanceData *)udata;
2665
-
2666
- if (instance->broker) {
2667
- // This deadlocks if we try to do this when the module is destroyed, when
2668
- // the InstanceData destructor runs, so run in the env cleanup hook instead,
2669
- // where it seems to go okay.
2670
- napi_release_threadsafe_function(instance->broker, napi_tsfn_abort);
2671
- }
2672
- }, instance);
2673
-
2674
- return exports;
2675
- }
2676
-
2677
- InstanceData::~InstanceData()
2678
- {
2679
- for (InstanceMemory *mem: memories) {
2680
- delete mem;
2681
- }
2682
-
2683
- // Clean-up leftover trampoline references
2684
- {
2685
- std::lock_guard<std::mutex> lock(shared.mutex);
2686
-
2687
- for (int16_t idx = 0; idx < MaxTrampolines; idx++) {
2688
- TrampolineInfo *trampoline = &shared.trampolines[idx];
2689
-
2690
- if (trampoline->instance == this) {
2691
- trampoline->instance = nullptr;
2692
- trampoline->func.Reset();
2693
- trampoline->recv.Reset();
2694
- trampoline->used = false;
2695
- }
2696
- }
2697
- }
2698
- }
2699
-
2700
- NODE_API_MODULE(koffi, InitModule);
2701
-
2702
- }