@wolfx/opencode-magic-context 0.21.8-patch.1

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 (544) hide show
  1. package/dist/agents/dreamer.d.ts +2 -0
  2. package/dist/agents/dreamer.d.ts.map +1 -0
  3. package/dist/agents/historian.d.ts +3 -0
  4. package/dist/agents/historian.d.ts.map +1 -0
  5. package/dist/agents/magic-context-prompt.d.ts +3 -0
  6. package/dist/agents/magic-context-prompt.d.ts.map +1 -0
  7. package/dist/agents/permissions.d.ts +142 -0
  8. package/dist/agents/permissions.d.ts.map +1 -0
  9. package/dist/agents/sidekick.d.ts +2 -0
  10. package/dist/agents/sidekick.d.ts.map +1 -0
  11. package/dist/config/agent-disable.d.ts +26 -0
  12. package/dist/config/agent-disable.d.ts.map +1 -0
  13. package/dist/config/index.d.ts +33 -0
  14. package/dist/config/index.d.ts.map +1 -0
  15. package/dist/config/schema/agent-overrides.d.ts +55 -0
  16. package/dist/config/schema/agent-overrides.d.ts.map +1 -0
  17. package/dist/config/schema/magic-context.d.ts +841 -0
  18. package/dist/config/schema/magic-context.d.ts.map +1 -0
  19. package/dist/config/schema.d.ts +3 -0
  20. package/dist/config/schema.d.ts.map +1 -0
  21. package/dist/config/variable.d.ts +48 -0
  22. package/dist/config/variable.d.ts.map +1 -0
  23. package/dist/features/builtin-commands/commands.d.ts +3 -0
  24. package/dist/features/builtin-commands/commands.d.ts.map +1 -0
  25. package/dist/features/builtin-commands/types.d.ts +5 -0
  26. package/dist/features/builtin-commands/types.d.ts.map +1 -0
  27. package/dist/features/magic-context/compaction-marker.d.ts +91 -0
  28. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -0
  29. package/dist/features/magic-context/compaction.d.ts +7 -0
  30. package/dist/features/magic-context/compaction.d.ts.map +1 -0
  31. package/dist/features/magic-context/compartment-lease.d.ts +14 -0
  32. package/dist/features/magic-context/compartment-lease.d.ts.map +1 -0
  33. package/dist/features/magic-context/compartment-storage.d.ts +130 -0
  34. package/dist/features/magic-context/compartment-storage.d.ts.map +1 -0
  35. package/dist/features/magic-context/compression-depth-storage.d.ts +14 -0
  36. package/dist/features/magic-context/compression-depth-storage.d.ts.map +1 -0
  37. package/dist/features/magic-context/defaults.d.ts +2 -0
  38. package/dist/features/magic-context/defaults.d.ts.map +1 -0
  39. package/dist/features/magic-context/dreamer/index.d.ts +8 -0
  40. package/dist/features/magic-context/dreamer/index.d.ts.map +1 -0
  41. package/dist/features/magic-context/dreamer/lease.d.ts +8 -0
  42. package/dist/features/magic-context/dreamer/lease.d.ts.map +1 -0
  43. package/dist/features/magic-context/dreamer/queue.d.ts +44 -0
  44. package/dist/features/magic-context/dreamer/queue.d.ts.map +1 -0
  45. package/dist/features/magic-context/dreamer/runner.d.ts +81 -0
  46. package/dist/features/magic-context/dreamer/runner.d.ts.map +1 -0
  47. package/dist/features/magic-context/dreamer/scheduler.d.ts +33 -0
  48. package/dist/features/magic-context/dreamer/scheduler.d.ts.map +1 -0
  49. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +41 -0
  50. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -0
  51. package/dist/features/magic-context/dreamer/storage-dream-state.d.ts +5 -0
  52. package/dist/features/magic-context/dreamer/storage-dream-state.d.ts.map +1 -0
  53. package/dist/features/magic-context/dreamer/task-prompts.d.ts +26 -0
  54. package/dist/features/magic-context/dreamer/task-prompts.d.ts.map +1 -0
  55. package/dist/features/magic-context/git-commits/git-log-reader.d.ts +57 -0
  56. package/dist/features/magic-context/git-commits/git-log-reader.d.ts.map +1 -0
  57. package/dist/features/magic-context/git-commits/index.d.ts +7 -0
  58. package/dist/features/magic-context/git-commits/index.d.ts.map +1 -0
  59. package/dist/features/magic-context/git-commits/indexer.d.ts +43 -0
  60. package/dist/features/magic-context/git-commits/indexer.d.ts.map +1 -0
  61. package/dist/features/magic-context/git-commits/search-git-commits.d.ts +32 -0
  62. package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -0
  63. package/dist/features/magic-context/git-commits/storage-git-commit-embeddings.d.ts +19 -0
  64. package/dist/features/magic-context/git-commits/storage-git-commit-embeddings.d.ts.map +1 -0
  65. package/dist/features/magic-context/git-commits/storage-git-commits.d.ts +47 -0
  66. package/dist/features/magic-context/git-commits/storage-git-commits.d.ts.map +1 -0
  67. package/dist/features/magic-context/index.d.ts +12 -0
  68. package/dist/features/magic-context/index.d.ts.map +1 -0
  69. package/dist/features/magic-context/key-files/aft-availability.d.ts +11 -0
  70. package/dist/features/magic-context/key-files/aft-availability.d.ts.map +1 -0
  71. package/dist/features/magic-context/key-files/identify-key-files.d.ts +84 -0
  72. package/dist/features/magic-context/key-files/identify-key-files.d.ts.map +1 -0
  73. package/dist/features/magic-context/key-files/project-key-files.d.ts +42 -0
  74. package/dist/features/magic-context/key-files/project-key-files.d.ts.map +1 -0
  75. package/dist/features/magic-context/key-files/read-history.d.ts +26 -0
  76. package/dist/features/magic-context/key-files/read-history.d.ts.map +1 -0
  77. package/dist/features/magic-context/key-files/read-stats.d.ts +20 -0
  78. package/dist/features/magic-context/key-files/read-stats.d.ts.map +1 -0
  79. package/dist/features/magic-context/key-files/storage-key-files.d.ts +25 -0
  80. package/dist/features/magic-context/key-files/storage-key-files.d.ts.map +1 -0
  81. package/dist/features/magic-context/memory/constants.d.ts +5 -0
  82. package/dist/features/magic-context/memory/constants.d.ts.map +1 -0
  83. package/dist/features/magic-context/memory/cosine-similarity.d.ts +2 -0
  84. package/dist/features/magic-context/memory/cosine-similarity.d.ts.map +1 -0
  85. package/dist/features/magic-context/memory/embedding-backfill.d.ts +9 -0
  86. package/dist/features/magic-context/memory/embedding-backfill.d.ts.map +1 -0
  87. package/dist/features/magic-context/memory/embedding-cache.d.ts +8 -0
  88. package/dist/features/magic-context/memory/embedding-cache.d.ts.map +1 -0
  89. package/dist/features/magic-context/memory/embedding-identity.d.ts +11 -0
  90. package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -0
  91. package/dist/features/magic-context/memory/embedding-local.d.ts +20 -0
  92. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -0
  93. package/dist/features/magic-context/memory/embedding-openai.d.ts +44 -0
  94. package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -0
  95. package/dist/features/magic-context/memory/embedding-probe.d.ts +69 -0
  96. package/dist/features/magic-context/memory/embedding-probe.d.ts.map +1 -0
  97. package/dist/features/magic-context/memory/embedding-provider.d.ts +15 -0
  98. package/dist/features/magic-context/memory/embedding-provider.d.ts.map +1 -0
  99. package/dist/features/magic-context/memory/embedding.d.ts +39 -0
  100. package/dist/features/magic-context/memory/embedding.d.ts.map +1 -0
  101. package/dist/features/magic-context/memory/index.d.ts +12 -0
  102. package/dist/features/magic-context/memory/index.d.ts.map +1 -0
  103. package/dist/features/magic-context/memory/normalize-hash.d.ts +3 -0
  104. package/dist/features/magic-context/memory/normalize-hash.d.ts.map +1 -0
  105. package/dist/features/magic-context/memory/project-identity.d.ts +23 -0
  106. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -0
  107. package/dist/features/magic-context/memory/promotion.d.ts +13 -0
  108. package/dist/features/magic-context/memory/promotion.d.ts.map +1 -0
  109. package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts +8 -0
  110. package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts.map +1 -0
  111. package/dist/features/magic-context/memory/storage-memory-fts.d.ts +12 -0
  112. package/dist/features/magic-context/memory/storage-memory-fts.d.ts.map +1 -0
  113. package/dist/features/magic-context/memory/storage-memory.d.ts +31 -0
  114. package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -0
  115. package/dist/features/magic-context/memory/types.d.ts +37 -0
  116. package/dist/features/magic-context/memory/types.d.ts.map +1 -0
  117. package/dist/features/magic-context/message-index-async.d.ts +12 -0
  118. package/dist/features/magic-context/message-index-async.d.ts.map +1 -0
  119. package/dist/features/magic-context/message-index.d.ts +10 -0
  120. package/dist/features/magic-context/message-index.d.ts.map +1 -0
  121. package/dist/features/magic-context/migrations.d.ts +33 -0
  122. package/dist/features/magic-context/migrations.d.ts.map +1 -0
  123. package/dist/features/magic-context/mock-database.d.ts +3 -0
  124. package/dist/features/magic-context/mock-database.d.ts.map +1 -0
  125. package/dist/features/magic-context/overflow-detection.d.ts +51 -0
  126. package/dist/features/magic-context/overflow-detection.d.ts.map +1 -0
  127. package/dist/features/magic-context/plugin-messages.d.ts +75 -0
  128. package/dist/features/magic-context/plugin-messages.d.ts.map +1 -0
  129. package/dist/features/magic-context/project-embedding-registry.d.ts +44 -0
  130. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -0
  131. package/dist/features/magic-context/range-parser.d.ts +13 -0
  132. package/dist/features/magic-context/range-parser.d.ts.map +1 -0
  133. package/dist/features/magic-context/resolve-subagent-fallback.d.ts +40 -0
  134. package/dist/features/magic-context/resolve-subagent-fallback.d.ts.map +1 -0
  135. package/dist/features/magic-context/scheduler.d.ts +18 -0
  136. package/dist/features/magic-context/scheduler.d.ts.map +1 -0
  137. package/dist/features/magic-context/search.d.ts +69 -0
  138. package/dist/features/magic-context/search.d.ts.map +1 -0
  139. package/dist/features/magic-context/sidekick/agent.d.ts +13 -0
  140. package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -0
  141. package/dist/features/magic-context/sidekick/core.d.ts +38 -0
  142. package/dist/features/magic-context/sidekick/core.d.ts.map +1 -0
  143. package/dist/features/magic-context/sidekick/index.d.ts +3 -0
  144. package/dist/features/magic-context/sidekick/index.d.ts.map +1 -0
  145. package/dist/features/magic-context/storage-db.d.ts +48 -0
  146. package/dist/features/magic-context/storage-db.d.ts.map +1 -0
  147. package/dist/features/magic-context/storage-meta-persisted.d.ts +246 -0
  148. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -0
  149. package/dist/features/magic-context/storage-meta-session.d.ts +6 -0
  150. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -0
  151. package/dist/features/magic-context/storage-meta-shared.d.ts +31 -0
  152. package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -0
  153. package/dist/features/magic-context/storage-meta.d.ts +3 -0
  154. package/dist/features/magic-context/storage-meta.d.ts.map +1 -0
  155. package/dist/features/magic-context/storage-notes.d.ts +62 -0
  156. package/dist/features/magic-context/storage-notes.d.ts.map +1 -0
  157. package/dist/features/magic-context/storage-ops.d.ts +7 -0
  158. package/dist/features/magic-context/storage-ops.d.ts.map +1 -0
  159. package/dist/features/magic-context/storage-source.d.ts +5 -0
  160. package/dist/features/magic-context/storage-source.d.ts.map +1 -0
  161. package/dist/features/magic-context/storage-subagent-invocations.d.ts +52 -0
  162. package/dist/features/magic-context/storage-subagent-invocations.d.ts.map +1 -0
  163. package/dist/features/magic-context/storage-tags.d.ts +206 -0
  164. package/dist/features/magic-context/storage-tags.d.ts.map +1 -0
  165. package/dist/features/magic-context/storage.d.ts +11 -0
  166. package/dist/features/magic-context/storage.d.ts.map +1 -0
  167. package/dist/features/magic-context/subagent-token-capture.d.ts +33 -0
  168. package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -0
  169. package/dist/features/magic-context/tagger.d.ts +64 -0
  170. package/dist/features/magic-context/tagger.d.ts.map +1 -0
  171. package/dist/features/magic-context/tool-definition-tokens.d.ts +79 -0
  172. package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -0
  173. package/dist/features/magic-context/tool-owner-backfill.d.ts +90 -0
  174. package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -0
  175. package/dist/features/magic-context/types.d.ts +72 -0
  176. package/dist/features/magic-context/types.d.ts.map +1 -0
  177. package/dist/features/magic-context/user-memory/review-user-memories.d.ts +22 -0
  178. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -0
  179. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts +33 -0
  180. package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -0
  181. package/dist/features/magic-context/work-metrics.d.ts +13 -0
  182. package/dist/features/magic-context/work-metrics.d.ts.map +1 -0
  183. package/dist/hooks/auto-update-checker/cache.d.ts +23 -0
  184. package/dist/hooks/auto-update-checker/cache.d.ts.map +1 -0
  185. package/dist/hooks/auto-update-checker/checker.d.ts +13 -0
  186. package/dist/hooks/auto-update-checker/checker.d.ts.map +1 -0
  187. package/dist/hooks/auto-update-checker/constants.d.ts +10 -0
  188. package/dist/hooks/auto-update-checker/constants.d.ts.map +1 -0
  189. package/dist/hooks/auto-update-checker/index.d.ts +40 -0
  190. package/dist/hooks/auto-update-checker/index.d.ts.map +1 -0
  191. package/dist/hooks/auto-update-checker/types.d.ts +50 -0
  192. package/dist/hooks/auto-update-checker/types.d.ts.map +1 -0
  193. package/dist/hooks/is-anthropic-provider.d.ts +2 -0
  194. package/dist/hooks/is-anthropic-provider.d.ts.map +1 -0
  195. package/dist/hooks/magic-context/apply-context-nudge.d.ts +5 -0
  196. package/dist/hooks/magic-context/apply-context-nudge.d.ts.map +1 -0
  197. package/dist/hooks/magic-context/apply-operations.d.ts +7 -0
  198. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -0
  199. package/dist/hooks/magic-context/auto-search-hint.d.ts +34 -0
  200. package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -0
  201. package/dist/hooks/magic-context/auto-search-runner.d.ts +53 -0
  202. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -0
  203. package/dist/hooks/magic-context/boundary-execution.d.ts +24 -0
  204. package/dist/hooks/magic-context/boundary-execution.d.ts.map +1 -0
  205. package/dist/hooks/magic-context/cache-busting-signals.d.ts +10 -0
  206. package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -0
  207. package/dist/hooks/magic-context/caveman-cleanup.d.ts +86 -0
  208. package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -0
  209. package/dist/hooks/magic-context/caveman.d.ts +35 -0
  210. package/dist/hooks/magic-context/caveman.d.ts.map +1 -0
  211. package/dist/hooks/magic-context/command-handler.d.ts +89 -0
  212. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -0
  213. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +106 -0
  214. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -0
  215. package/dist/hooks/magic-context/compartment-parser.d.ts +18 -0
  216. package/dist/hooks/magic-context/compartment-parser.d.ts.map +1 -0
  217. package/dist/hooks/magic-context/compartment-prompt.d.ts +19 -0
  218. package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -0
  219. package/dist/hooks/magic-context/compartment-runner-compressor.d.ts +87 -0
  220. package/dist/hooks/magic-context/compartment-runner-compressor.d.ts.map +1 -0
  221. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +26 -0
  222. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -0
  223. package/dist/hooks/magic-context/compartment-runner-historian.d.ts +42 -0
  224. package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -0
  225. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +6 -0
  226. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -0
  227. package/dist/hooks/magic-context/compartment-runner-mapping.d.ts +33 -0
  228. package/dist/hooks/magic-context/compartment-runner-mapping.d.ts.map +1 -0
  229. package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts +29 -0
  230. package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -0
  231. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts +3 -0
  232. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -0
  233. package/dist/hooks/magic-context/compartment-runner-state-xml.d.ts +21 -0
  234. package/dist/hooks/magic-context/compartment-runner-state-xml.d.ts.map +1 -0
  235. package/dist/hooks/magic-context/compartment-runner-types.d.ts +102 -0
  236. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -0
  237. package/dist/hooks/magic-context/compartment-runner-validation.d.ts +28 -0
  238. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -0
  239. package/dist/hooks/magic-context/compartment-runner.d.ts +54 -0
  240. package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -0
  241. package/dist/hooks/magic-context/compartment-trigger.d.ts +17 -0
  242. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -0
  243. package/dist/hooks/magic-context/derive-budgets.d.ts +57 -0
  244. package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -0
  245. package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts +4 -0
  246. package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -0
  247. package/dist/hooks/magic-context/event-handler.d.ts +49 -0
  248. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -0
  249. package/dist/hooks/magic-context/event-payloads.d.ts +62 -0
  250. package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -0
  251. package/dist/hooks/magic-context/event-resolvers.d.ts +72 -0
  252. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -0
  253. package/dist/hooks/magic-context/execute-flush.d.ts +3 -0
  254. package/dist/hooks/magic-context/execute-flush.d.ts.map +1 -0
  255. package/dist/hooks/magic-context/execute-status.d.ts +12 -0
  256. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -0
  257. package/dist/hooks/magic-context/format-bytes.d.ts +2 -0
  258. package/dist/hooks/magic-context/format-bytes.d.ts.map +1 -0
  259. package/dist/hooks/magic-context/heuristic-cleanup.d.ts +22 -0
  260. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -0
  261. package/dist/hooks/magic-context/historian-state-file.d.ts +43 -0
  262. package/dist/hooks/magic-context/historian-state-file.d.ts.map +1 -0
  263. package/dist/hooks/magic-context/hook-handlers.d.ts +165 -0
  264. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -0
  265. package/dist/hooks/magic-context/hook.d.ts +118 -0
  266. package/dist/hooks/magic-context/hook.d.ts.map +1 -0
  267. package/dist/hooks/magic-context/image-token-estimate.d.ts +6 -0
  268. package/dist/hooks/magic-context/image-token-estimate.d.ts.map +1 -0
  269. package/dist/hooks/magic-context/index.d.ts +3 -0
  270. package/dist/hooks/magic-context/index.d.ts.map +1 -0
  271. package/dist/hooks/magic-context/inject-compartments.d.ts +52 -0
  272. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -0
  273. package/dist/hooks/magic-context/key-files-block.d.ts +27 -0
  274. package/dist/hooks/magic-context/key-files-block.d.ts.map +1 -0
  275. package/dist/hooks/magic-context/live-session-state.d.ts +42 -0
  276. package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -0
  277. package/dist/hooks/magic-context/note-nudger.d.ts +71 -0
  278. package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -0
  279. package/dist/hooks/magic-context/note-visibility.d.ts +43 -0
  280. package/dist/hooks/magic-context/note-visibility.d.ts.map +1 -0
  281. package/dist/hooks/magic-context/nudge-bands.d.ts +6 -0
  282. package/dist/hooks/magic-context/nudge-bands.d.ts.map +1 -0
  283. package/dist/hooks/magic-context/nudge-injection.d.ts +7 -0
  284. package/dist/hooks/magic-context/nudge-injection.d.ts.map +1 -0
  285. package/dist/hooks/magic-context/nudge-placement-store.d.ts +15 -0
  286. package/dist/hooks/magic-context/nudge-placement-store.d.ts.map +1 -0
  287. package/dist/hooks/magic-context/nudger.d.ts +21 -0
  288. package/dist/hooks/magic-context/nudger.d.ts.map +1 -0
  289. package/dist/hooks/magic-context/read-session-chunk.d.ts +99 -0
  290. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -0
  291. package/dist/hooks/magic-context/read-session-db.d.ts +21 -0
  292. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -0
  293. package/dist/hooks/magic-context/read-session-formatting.d.ts +35 -0
  294. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -0
  295. package/dist/hooks/magic-context/read-session-raw.d.ts +10 -0
  296. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -0
  297. package/dist/hooks/magic-context/send-session-notification.d.ts +13 -0
  298. package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -0
  299. package/dist/hooks/magic-context/sentinel.d.ts +102 -0
  300. package/dist/hooks/magic-context/sentinel.d.ts.map +1 -0
  301. package/dist/hooks/magic-context/strip-content.d.ts +140 -0
  302. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -0
  303. package/dist/hooks/magic-context/strip-structural-noise.d.ts +17 -0
  304. package/dist/hooks/magic-context/strip-structural-noise.d.ts.map +1 -0
  305. package/dist/hooks/magic-context/system-injection-stripper.d.ts +2 -0
  306. package/dist/hooks/magic-context/system-injection-stripper.d.ts.map +1 -0
  307. package/dist/hooks/magic-context/system-prompt-hash.d.ts +85 -0
  308. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -0
  309. package/dist/hooks/magic-context/tag-content-primitives.d.ts +6 -0
  310. package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -0
  311. package/dist/hooks/magic-context/tag-id-fallback.d.ts +9 -0
  312. package/dist/hooks/magic-context/tag-id-fallback.d.ts.map +1 -0
  313. package/dist/hooks/magic-context/tag-messages.d.ts +48 -0
  314. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -0
  315. package/dist/hooks/magic-context/tag-part-guards.d.ts +23 -0
  316. package/dist/hooks/magic-context/tag-part-guards.d.ts.map +1 -0
  317. package/dist/hooks/magic-context/temporal-awareness.d.ts +73 -0
  318. package/dist/hooks/magic-context/temporal-awareness.d.ts.map +1 -0
  319. package/dist/hooks/magic-context/text-complete.d.ts +8 -0
  320. package/dist/hooks/magic-context/text-complete.d.ts.map +1 -0
  321. package/dist/hooks/magic-context/todo-view.d.ts +102 -0
  322. package/dist/hooks/magic-context/todo-view.d.ts.map +1 -0
  323. package/dist/hooks/magic-context/tokenizer-calibration.d.ts +85 -0
  324. package/dist/hooks/magic-context/tokenizer-calibration.d.ts.map +1 -0
  325. package/dist/hooks/magic-context/tool-drop-target.d.ts +48 -0
  326. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -0
  327. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +66 -0
  328. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -0
  329. package/dist/hooks/magic-context/transform-context-state.d.ts +12 -0
  330. package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -0
  331. package/dist/hooks/magic-context/transform-message-helpers.d.ts +29 -0
  332. package/dist/hooks/magic-context/transform-message-helpers.d.ts.map +1 -0
  333. package/dist/hooks/magic-context/transform-operations.d.ts +5 -0
  334. package/dist/hooks/magic-context/transform-operations.d.ts.map +1 -0
  335. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +100 -0
  336. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -0
  337. package/dist/hooks/magic-context/transform-stage-logger.d.ts +2 -0
  338. package/dist/hooks/magic-context/transform-stage-logger.d.ts.map +1 -0
  339. package/dist/hooks/magic-context/transform.d.ts +145 -0
  340. package/dist/hooks/magic-context/transform.d.ts.map +1 -0
  341. package/dist/index.d.ts +4 -0
  342. package/dist/index.d.ts.map +1 -0
  343. package/dist/index.js +179800 -0
  344. package/dist/plugin/conflict-warning-hook.d.ts +34 -0
  345. package/dist/plugin/conflict-warning-hook.d.ts.map +1 -0
  346. package/dist/plugin/dream-timer.d.ts +44 -0
  347. package/dist/plugin/dream-timer.d.ts.map +1 -0
  348. package/dist/plugin/embedding-bootstrap-helpers.d.ts +35 -0
  349. package/dist/plugin/embedding-bootstrap-helpers.d.ts.map +1 -0
  350. package/dist/plugin/embedding-bootstrap.d.ts +3 -0
  351. package/dist/plugin/embedding-bootstrap.d.ts.map +1 -0
  352. package/dist/plugin/event.d.ts +13 -0
  353. package/dist/plugin/event.d.ts.map +1 -0
  354. package/dist/plugin/hooks/create-session-hooks.d.ts +44 -0
  355. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -0
  356. package/dist/plugin/messages-transform.d.ts +46 -0
  357. package/dist/plugin/messages-transform.d.ts.map +1 -0
  358. package/dist/plugin/normalize-tool-arg-schemas.d.ts +7 -0
  359. package/dist/plugin/normalize-tool-arg-schemas.d.ts.map +1 -0
  360. package/dist/plugin/rpc-handlers.d.ts +21 -0
  361. package/dist/plugin/rpc-handlers.d.ts.map +1 -0
  362. package/dist/plugin/sidebar-snapshot-cache.d.ts +19 -0
  363. package/dist/plugin/sidebar-snapshot-cache.d.ts.map +1 -0
  364. package/dist/plugin/tool-registry.d.ts +8 -0
  365. package/dist/plugin/tool-registry.d.ts.map +1 -0
  366. package/dist/plugin/types.d.ts +3 -0
  367. package/dist/plugin/types.d.ts.map +1 -0
  368. package/dist/shared/announcement.d.ts +55 -0
  369. package/dist/shared/announcement.d.ts.map +1 -0
  370. package/dist/shared/assistant-message-extractor.d.ts +2 -0
  371. package/dist/shared/assistant-message-extractor.d.ts.map +1 -0
  372. package/dist/shared/bounded-session-map.d.ts +45 -0
  373. package/dist/shared/bounded-session-map.d.ts.map +1 -0
  374. package/dist/shared/conflict-detector.d.ts +74 -0
  375. package/dist/shared/conflict-detector.d.ts.map +1 -0
  376. package/dist/shared/conflict-fixer.d.ts +3 -0
  377. package/dist/shared/conflict-fixer.d.ts.map +1 -0
  378. package/dist/shared/data-path.d.ts +121 -0
  379. package/dist/shared/data-path.d.ts.map +1 -0
  380. package/dist/shared/error-message.d.ts +32 -0
  381. package/dist/shared/error-message.d.ts.map +1 -0
  382. package/dist/shared/format-bytes.d.ts +2 -0
  383. package/dist/shared/format-bytes.d.ts.map +1 -0
  384. package/dist/shared/format-threshold.d.ts +24 -0
  385. package/dist/shared/format-threshold.d.ts.map +1 -0
  386. package/dist/shared/harness.d.ts +43 -0
  387. package/dist/shared/harness.d.ts.map +1 -0
  388. package/dist/shared/index.d.ts +6 -0
  389. package/dist/shared/index.d.ts.map +1 -0
  390. package/dist/shared/internal-initiator-marker.d.ts +2 -0
  391. package/dist/shared/internal-initiator-marker.d.ts.map +1 -0
  392. package/dist/shared/jsonc-parser.d.ts +8 -0
  393. package/dist/shared/jsonc-parser.d.ts.map +1 -0
  394. package/dist/shared/logger.d.ts +10 -0
  395. package/dist/shared/logger.d.ts.map +1 -0
  396. package/dist/shared/model-requirements.d.ts +26 -0
  397. package/dist/shared/model-requirements.d.ts.map +1 -0
  398. package/dist/shared/model-suggestion-retry.d.ts +68 -0
  399. package/dist/shared/model-suggestion-retry.d.ts.map +1 -0
  400. package/dist/shared/models-dev-cache.d.ts +65 -0
  401. package/dist/shared/models-dev-cache.d.ts.map +1 -0
  402. package/dist/shared/native-binding.d.ts +87 -0
  403. package/dist/shared/native-binding.d.ts.map +1 -0
  404. package/dist/shared/normalize-sdk-response.d.ts +5 -0
  405. package/dist/shared/normalize-sdk-response.d.ts.map +1 -0
  406. package/dist/shared/opencode-compaction-detector.d.ts +2 -0
  407. package/dist/shared/opencode-compaction-detector.d.ts.map +1 -0
  408. package/dist/shared/opencode-config-dir-types.d.ts +14 -0
  409. package/dist/shared/opencode-config-dir-types.d.ts.map +1 -0
  410. package/dist/shared/opencode-config-dir.d.ts +5 -0
  411. package/dist/shared/opencode-config-dir.d.ts.map +1 -0
  412. package/dist/shared/record-type-guard.d.ts +2 -0
  413. package/dist/shared/record-type-guard.d.ts.map +1 -0
  414. package/dist/shared/resolve-fallbacks.d.ts +32 -0
  415. package/dist/shared/resolve-fallbacks.d.ts.map +1 -0
  416. package/dist/shared/rpc-client.d.ts +17 -0
  417. package/dist/shared/rpc-client.d.ts.map +1 -0
  418. package/dist/shared/rpc-notifications.d.ts +24 -0
  419. package/dist/shared/rpc-notifications.d.ts.map +1 -0
  420. package/dist/shared/rpc-server.d.ts +20 -0
  421. package/dist/shared/rpc-server.d.ts.map +1 -0
  422. package/dist/shared/rpc-types.d.ts +105 -0
  423. package/dist/shared/rpc-types.d.ts.map +1 -0
  424. package/dist/shared/rpc-utils.d.ts +19 -0
  425. package/dist/shared/rpc-utils.d.ts.map +1 -0
  426. package/dist/shared/sqlite-helpers.d.ts +16 -0
  427. package/dist/shared/sqlite-helpers.d.ts.map +1 -0
  428. package/dist/shared/sqlite.d.ts +43 -0
  429. package/dist/shared/sqlite.d.ts.map +1 -0
  430. package/dist/shared/stable-json.d.ts +21 -0
  431. package/dist/shared/stable-json.d.ts.map +1 -0
  432. package/dist/shared/subagent-runner.d.ts +208 -0
  433. package/dist/shared/subagent-runner.d.ts.map +1 -0
  434. package/dist/shared/system-directive.d.ts +3 -0
  435. package/dist/shared/system-directive.d.ts.map +1 -0
  436. package/dist/shared/tag-transcript.d.ts +66 -0
  437. package/dist/shared/tag-transcript.d.ts.map +1 -0
  438. package/dist/shared/transcript-opencode.d.ts +71 -0
  439. package/dist/shared/transcript-opencode.d.ts.map +1 -0
  440. package/dist/shared/transcript.d.ts +212 -0
  441. package/dist/shared/transcript.d.ts.map +1 -0
  442. package/dist/shared/tui-config.d.ts +10 -0
  443. package/dist/shared/tui-config.d.ts.map +1 -0
  444. package/dist/tools/ctx-expand/constants.d.ts +3 -0
  445. package/dist/tools/ctx-expand/constants.d.ts.map +1 -0
  446. package/dist/tools/ctx-expand/index.d.ts +2 -0
  447. package/dist/tools/ctx-expand/index.d.ts.map +1 -0
  448. package/dist/tools/ctx-expand/tools.d.ts +3 -0
  449. package/dist/tools/ctx-expand/tools.d.ts.map +1 -0
  450. package/dist/tools/ctx-expand/types.d.ts +5 -0
  451. package/dist/tools/ctx-expand/types.d.ts.map +1 -0
  452. package/dist/tools/ctx-memory/constants.d.ts +4 -0
  453. package/dist/tools/ctx-memory/constants.d.ts.map +1 -0
  454. package/dist/tools/ctx-memory/index.d.ts +4 -0
  455. package/dist/tools/ctx-memory/index.d.ts.map +1 -0
  456. package/dist/tools/ctx-memory/tools.d.ts +4 -0
  457. package/dist/tools/ctx-memory/tools.d.ts.map +1 -0
  458. package/dist/tools/ctx-memory/types.d.ts +35 -0
  459. package/dist/tools/ctx-memory/types.d.ts.map +1 -0
  460. package/dist/tools/ctx-note/constants.d.ts +2 -0
  461. package/dist/tools/ctx-note/constants.d.ts.map +1 -0
  462. package/dist/tools/ctx-note/index.d.ts +4 -0
  463. package/dist/tools/ctx-note/index.d.ts.map +1 -0
  464. package/dist/tools/ctx-note/tools.d.ts +15 -0
  465. package/dist/tools/ctx-note/tools.d.ts.map +1 -0
  466. package/dist/tools/ctx-note/types.d.ts +9 -0
  467. package/dist/tools/ctx-note/types.d.ts.map +1 -0
  468. package/dist/tools/ctx-reduce/constants.d.ts +2 -0
  469. package/dist/tools/ctx-reduce/constants.d.ts.map +1 -0
  470. package/dist/tools/ctx-reduce/index.d.ts +4 -0
  471. package/dist/tools/ctx-reduce/index.d.ts.map +1 -0
  472. package/dist/tools/ctx-reduce/tools.d.ts +9 -0
  473. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -0
  474. package/dist/tools/ctx-reduce/types.d.ts +4 -0
  475. package/dist/tools/ctx-reduce/types.d.ts.map +1 -0
  476. package/dist/tools/ctx-search/constants.d.ts +4 -0
  477. package/dist/tools/ctx-search/constants.d.ts.map +1 -0
  478. package/dist/tools/ctx-search/index.d.ts +4 -0
  479. package/dist/tools/ctx-search/index.d.ts.map +1 -0
  480. package/dist/tools/ctx-search/tools.d.ts +4 -0
  481. package/dist/tools/ctx-search/tools.d.ts.map +1 -0
  482. package/dist/tools/ctx-search/types.d.ts +34 -0
  483. package/dist/tools/ctx-search/types.d.ts.map +1 -0
  484. package/dist/tools/index.d.ts +6 -0
  485. package/dist/tools/index.d.ts.map +1 -0
  486. package/dist/tui/data/context-db.d.ts +36 -0
  487. package/dist/tui/data/context-db.d.ts.map +1 -0
  488. package/package.json +80 -0
  489. package/src/shared/announcement.test.ts +143 -0
  490. package/src/shared/announcement.ts +97 -0
  491. package/src/shared/assistant-message-extractor.ts +74 -0
  492. package/src/shared/bounded-session-map.test.ts +97 -0
  493. package/src/shared/bounded-session-map.ts +84 -0
  494. package/src/shared/conflict-detector.test.ts +232 -0
  495. package/src/shared/conflict-detector.ts +371 -0
  496. package/src/shared/conflict-fixer.test.ts +124 -0
  497. package/src/shared/conflict-fixer.ts +222 -0
  498. package/src/shared/data-path.test.ts +159 -0
  499. package/src/shared/data-path.ts +155 -0
  500. package/src/shared/error-message.test.ts +94 -0
  501. package/src/shared/error-message.ts +115 -0
  502. package/src/shared/format-bytes.ts +5 -0
  503. package/src/shared/format-threshold.ts +28 -0
  504. package/src/shared/harness.ts +61 -0
  505. package/src/shared/index.ts +5 -0
  506. package/src/shared/internal-initiator-marker.ts +1 -0
  507. package/src/shared/jsonc-parser.ts +138 -0
  508. package/src/shared/logger.ts +94 -0
  509. package/src/shared/model-requirements.ts +86 -0
  510. package/src/shared/model-suggestion-retry.test.ts +251 -0
  511. package/src/shared/model-suggestion-retry.ts +348 -0
  512. package/src/shared/models-dev-cache.test.ts +394 -0
  513. package/src/shared/models-dev-cache.ts +337 -0
  514. package/src/shared/native-binding.ts +311 -0
  515. package/src/shared/normalize-sdk-response.ts +40 -0
  516. package/src/shared/opencode-compaction-detector.test.ts +222 -0
  517. package/src/shared/opencode-compaction-detector.ts +81 -0
  518. package/src/shared/opencode-config-dir-types.ts +15 -0
  519. package/src/shared/opencode-config-dir.ts +38 -0
  520. package/src/shared/record-type-guard.ts +3 -0
  521. package/src/shared/resolve-fallbacks.test.ts +136 -0
  522. package/src/shared/resolve-fallbacks.ts +76 -0
  523. package/src/shared/rpc-client.test.ts +161 -0
  524. package/src/shared/rpc-client.ts +183 -0
  525. package/src/shared/rpc-notifications.test.ts +20 -0
  526. package/src/shared/rpc-notifications.ts +53 -0
  527. package/src/shared/rpc-server.ts +174 -0
  528. package/src/shared/rpc-types.ts +104 -0
  529. package/src/shared/rpc-utils.ts +72 -0
  530. package/src/shared/session-messages-bounded.test.ts +112 -0
  531. package/src/shared/sqlite-helpers.ts +27 -0
  532. package/src/shared/sqlite.ts +134 -0
  533. package/src/shared/stable-json.test.ts +87 -0
  534. package/src/shared/stable-json.ts +37 -0
  535. package/src/shared/subagent-runner.ts +222 -0
  536. package/src/shared/system-directive.ts +9 -0
  537. package/src/shared/tag-transcript.ts +553 -0
  538. package/src/shared/transcript-opencode.ts +259 -0
  539. package/src/shared/transcript.ts +226 -0
  540. package/src/shared/tui-config.ts +99 -0
  541. package/src/tui/data/context-db.ts +303 -0
  542. package/src/tui/index.tsx +692 -0
  543. package/src/tui/slots/sidebar-content.tsx +482 -0
  544. package/src/tui/types/opencode-plugin-tui.d.ts +232 -0
@@ -0,0 +1,337 @@
1
+ /**
2
+ * Resolve per-model context limits to match whatever OpenCode itself sees.
3
+ *
4
+ * Two layers:
5
+ *
6
+ * 1. API cache (primary): populated asynchronously via
7
+ * `client.config.providers()`. OpenCode's own provider service merges
8
+ * the live models.dev cache file, its compiled-in snapshot fallback,
9
+ * opencode.json custom provider overrides, and derived experimental
10
+ * modes. Whatever OpenCode reports is the source of truth.
11
+ *
12
+ * 2. File cache (fallback): read-from-disk parse of OpenCode's
13
+ * `models.json` plus `opencode.json(c)` custom provider entries.
14
+ * Used during cold starts before the API cache warms up and in any
15
+ * code path that cannot reach the SDK client.
16
+ *
17
+ * The public getter (`getModelsDevContextLimit()`) is synchronous: it checks
18
+ * the API cache first, then the file cache. The plugin warms the API cache
19
+ * once from `src/index.ts` at startup. Runtime retries are reserved for the
20
+ * issue #77 cache-regression recovery path.
21
+ */
22
+
23
+ import { createHash } from "node:crypto";
24
+ import { existsSync, readFileSync } from "node:fs";
25
+ import { homedir, platform } from "node:os";
26
+ import { join } from "node:path";
27
+ import { getCacheDir } from "./data-path";
28
+ import { parseJsonc } from "./jsonc-parser";
29
+ import { sessionLog } from "./logger";
30
+
31
+ interface OpencodeClientLike {
32
+ config: {
33
+ providers: () => Promise<{ data?: { providers?: unknown } }>;
34
+ };
35
+ }
36
+
37
+ // File-cache fallback only. The primary API refresh is one-shot at startup;
38
+ // this 5-minute interval governs the on-disk-cache fallback path when the API
39
+ // loader hasn't run yet (e.g. during plugin warmup).
40
+ const RELOAD_INTERVAL_MS = 5 * 60 * 1000;
41
+
42
+ interface CachedModelMetadata {
43
+ limit?: number;
44
+ }
45
+
46
+ /** Populated async from OpenCode SDK. Primary source of truth when available. */
47
+ let apiCache: Map<string, CachedModelMetadata> | null = null;
48
+ let apiLoadedAt = 0;
49
+
50
+ /** Populated sync from disk as fallback. */
51
+ let fileCache: Map<string, CachedModelMetadata> | null = null;
52
+ let fileLastAttempt = 0;
53
+
54
+ function hashFast(input: string): string {
55
+ // Matches OpenCode's Hash.fast() (packages/shared/src/util/hash.ts).
56
+ return createHash("sha1").update(input).digest("hex");
57
+ }
58
+
59
+ function getModelsJsonPath(): string {
60
+ // 1. Explicit path override (OpenCode's OPENCODE_MODELS_PATH takes highest priority).
61
+ const explicit = process.env.OPENCODE_MODELS_PATH?.trim();
62
+ if (explicit) return explicit;
63
+
64
+ // OpenCode uses `xdg-basedir`, which falls back to `<homedir>/.cache` on
65
+ // every platform (including Windows) when XDG_CACHE_HOME is unset. See
66
+ // shared/data-path.ts#getCacheDir for the shared helper.
67
+ const cacheBase = getCacheDir();
68
+
69
+ // 2. Custom models source → hashed filename (matches OpenCode).
70
+ // source === "https://models.dev" ? "models.json" : `models-${Hash.fast(source)}.json`
71
+ const source = process.env.OPENCODE_MODELS_URL?.trim();
72
+ const filename =
73
+ source && source !== "https://models.dev"
74
+ ? `models-${hashFast(source)}.json`
75
+ : "models.json";
76
+
77
+ return join(cacheBase, "opencode", filename);
78
+ }
79
+
80
+ function getOpencodeConfigPath(): string | null {
81
+ const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
82
+ const configDir = envDir
83
+ ? envDir
84
+ : platform() === "win32"
85
+ ? join(homedir(), ".config", "opencode")
86
+ : join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), "opencode");
87
+
88
+ // Check jsonc first, then json (matches OpenCode's own lookup order).
89
+ const jsonc = join(configDir, "opencode.jsonc");
90
+ if (existsSync(jsonc)) return jsonc;
91
+ const json = join(configDir, "opencode.json");
92
+ if (existsSync(json)) return json;
93
+ return null;
94
+ }
95
+
96
+ /**
97
+ * Resolve the effective pressure limit for a model's `limit` object.
98
+ *
99
+ * Prefers `limit.input` (max prompt tokens the provider will accept) over
100
+ * `limit.context` (total window including output). For GitHub Copilot and
101
+ * several proxy providers, `context` is the marketing number (input + output
102
+ * combined), and sending a prompt sized against `context` gets rejected.
103
+ * OpenCode's own `session/overflow.ts` uses `input ?? context` for the same
104
+ * reason — the denominator that drives overflow/pressure must be the number
105
+ * the provider actually enforces on input.
106
+ */
107
+ function resolveLimit(limit: { context?: number; input?: number } | undefined): number | undefined {
108
+ if (!limit) return undefined;
109
+ if (typeof limit.input === "number" && limit.input > 0) return limit.input;
110
+ if (typeof limit.context === "number" && limit.context > 0) return limit.context;
111
+ return undefined;
112
+ }
113
+
114
+ function setCachedModelMetadata(
115
+ cache: Map<string, CachedModelMetadata>,
116
+ key: string,
117
+ model:
118
+ | {
119
+ limit?: { context?: number; input?: number };
120
+ experimental?: { modes?: Record<string, unknown> };
121
+ }
122
+ | undefined,
123
+ ): void {
124
+ const limit = resolveLimit(model?.limit);
125
+
126
+ if (limit === undefined) {
127
+ return;
128
+ }
129
+
130
+ const value: CachedModelMetadata = { limit };
131
+ cache.set(key, value);
132
+
133
+ // OpenCode creates derived model IDs from experimental.modes
134
+ // e.g. gpt-5.4 + modes.fast → gpt-5.4-fast. These inherit the same
135
+ // context limit as the parent model.
136
+ const modes = model?.experimental?.modes;
137
+ if (modes && typeof modes === "object") {
138
+ for (const mode of Object.keys(modes)) {
139
+ cache.set(`${key}-${mode}`, value);
140
+ }
141
+ }
142
+ }
143
+
144
+ function loadModelsDevMetadataFromFile(): Map<string, CachedModelMetadata> {
145
+ const metadata = new Map<string, CachedModelMetadata>();
146
+
147
+ // 1. Read OpenCode's models.dev cache file (base layer).
148
+ const modelsJsonPath = getModelsJsonPath();
149
+ let fileFound = false;
150
+ try {
151
+ if (existsSync(modelsJsonPath)) {
152
+ fileFound = true;
153
+ const raw = readFileSync(modelsJsonPath, "utf-8");
154
+ const data = JSON.parse(raw) as Record<
155
+ string,
156
+ {
157
+ models?: Record<
158
+ string,
159
+ {
160
+ limit?: { context?: number; input?: number };
161
+ experimental?: { modes?: Record<string, unknown> };
162
+ }
163
+ >;
164
+ }
165
+ >;
166
+
167
+ for (const [providerId, provider] of Object.entries(data)) {
168
+ if (!provider?.models || typeof provider.models !== "object") continue;
169
+ for (const [modelId, model] of Object.entries(provider.models)) {
170
+ setCachedModelMetadata(metadata, `${providerId}/${modelId}`, model);
171
+ }
172
+ }
173
+ }
174
+ } catch (error) {
175
+ sessionLog(
176
+ "global",
177
+ `models-dev-cache: failed to read models.json at ${modelsJsonPath}:`,
178
+ error instanceof Error ? error.message : String(error),
179
+ );
180
+ }
181
+
182
+ // 2. Overlay custom provider models from OpenCode config (higher priority).
183
+ // Users define custom/proxy models via provider.<id>.models.<name>.limit.{input,context}
184
+ // in opencode.json(c). These override models.dev entries for the same key.
185
+ try {
186
+ const configPath = getOpencodeConfigPath();
187
+ if (configPath && existsSync(configPath)) {
188
+ // Use the shared JSONC parser — handles `//` comments AND trailing commas.
189
+ // The previous custom regex stripped comments only; OpenCode's `opencode.jsonc`
190
+ // frequently contains trailing commas (valid JSONC, invalid JSON), which broke
191
+ // custom provider model-limit resolution silently. See issue #14 follow-up.
192
+ const config = parseJsonc<{
193
+ provider?: Record<
194
+ string,
195
+ {
196
+ models?: Record<string, { limit?: { context?: number; input?: number } }>;
197
+ }
198
+ >;
199
+ }>(readFileSync(configPath, "utf-8"));
200
+
201
+ if (config.provider && typeof config.provider === "object") {
202
+ for (const [providerId, provider] of Object.entries(config.provider)) {
203
+ if (!provider?.models || typeof provider.models !== "object") continue;
204
+ for (const [modelId, model] of Object.entries(provider.models)) {
205
+ setCachedModelMetadata(metadata, `${providerId}/${modelId}`, model);
206
+ }
207
+ }
208
+ }
209
+ }
210
+ } catch (error) {
211
+ sessionLog(
212
+ "global",
213
+ "models-dev-cache: failed to read opencode config for custom models:",
214
+ error instanceof Error ? error.message : String(error),
215
+ );
216
+ }
217
+
218
+ sessionLog(
219
+ "global",
220
+ `models-dev-cache: file-layer loaded ${metadata.size} model metadata entries (modelsJsonPath=${modelsJsonPath}, found=${fileFound})`,
221
+ );
222
+
223
+ return metadata;
224
+ }
225
+
226
+ /**
227
+ * Asynchronously refresh the API-layer cache from OpenCode's SDK.
228
+ *
229
+ * Call this at plugin startup and from the issue #77 regression-recovery path.
230
+ * OpenCode's `/config/providers` endpoint returns every provider with full
231
+ * model metadata — including `limit.context` — resolved through the same path
232
+ * OpenCode itself uses (live cache + compiled-in snapshot + opencode.json
233
+ * overrides + derived experimental modes).
234
+ *
235
+ * Safe to call concurrently; only overwrites the cache on success.
236
+ */
237
+ export async function refreshModelLimitsFromApi(client: OpencodeClientLike): Promise<void> {
238
+ try {
239
+ const result = await client.config.providers();
240
+ const data = (result as { data?: { providers?: Array<unknown> } }).data;
241
+ const providers = data?.providers;
242
+ if (!Array.isArray(providers)) {
243
+ sessionLog("global", "models-dev-cache: API refresh returned no providers payload");
244
+ return;
245
+ }
246
+
247
+ const map = new Map<string, CachedModelMetadata>();
248
+ for (const entry of providers) {
249
+ const p = entry as {
250
+ id?: string;
251
+ models?: Record<
252
+ string,
253
+ {
254
+ limit?: { context?: number; input?: number };
255
+ experimental?: { modes?: Record<string, unknown> };
256
+ }
257
+ >;
258
+ };
259
+ if (!p?.id || !p.models || typeof p.models !== "object") continue;
260
+ for (const [modelId, model] of Object.entries(p.models)) {
261
+ setCachedModelMetadata(map, `${p.id}/${modelId}`, model);
262
+ }
263
+ }
264
+
265
+ const previousSize = apiCache?.size ?? null;
266
+ apiCache = map;
267
+ apiLoadedAt = Date.now();
268
+
269
+ if (previousSize === null) {
270
+ sessionLog(
271
+ "global",
272
+ `models-dev-cache: API layer loaded ${map.size} model metadata entries`,
273
+ );
274
+ } else if (previousSize !== map.size) {
275
+ sessionLog(
276
+ "global",
277
+ `models-dev-cache: API layer loaded ${map.size} model metadata entries (was ${previousSize})`,
278
+ );
279
+ }
280
+ } catch (error) {
281
+ sessionLog(
282
+ "global",
283
+ "models-dev-cache: API refresh failed:",
284
+ error instanceof Error ? error.message : String(error),
285
+ );
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Returns the context limit for a provider/model.
291
+ *
292
+ * Lookup order:
293
+ * 1. API cache (populated by {@link refreshModelLimitsFromApi}). Matches
294
+ * what OpenCode sees exactly, including snapshot-only models.
295
+ * 2. File cache (parsed from models.json + opencode.json overrides).
296
+ * Used before the API cache warms and as a last resort.
297
+ *
298
+ * Returns `undefined` if neither layer knows the model.
299
+ */
300
+ export function getModelsDevContextLimit(providerID: string, modelID: string): number | undefined {
301
+ const key = `${providerID}/${modelID}`;
302
+
303
+ if (apiCache) {
304
+ const fromApi = apiCache.get(key)?.limit;
305
+ if (typeof fromApi === "number") return fromApi;
306
+ }
307
+
308
+ const now = Date.now();
309
+ if (!fileCache || now - fileLastAttempt > RELOAD_INTERVAL_MS) {
310
+ fileLastAttempt = now;
311
+ fileCache = loadModelsDevMetadataFromFile();
312
+ }
313
+ return fileCache.get(key)?.limit;
314
+ }
315
+
316
+ /** Clear in-memory caches (for testing). */
317
+ export function clearModelsDevCache(): void {
318
+ apiCache = null;
319
+ apiLoadedAt = 0;
320
+ fileCache = null;
321
+ fileLastAttempt = 0;
322
+ }
323
+
324
+ /** Inspection helpers (for logging / debugging). */
325
+ export function getModelsDevCacheState(): {
326
+ apiLoaded: boolean;
327
+ apiCount: number;
328
+ apiAgeMs: number;
329
+ fileCount: number;
330
+ } {
331
+ return {
332
+ apiLoaded: apiCache !== null,
333
+ apiCount: apiCache?.size ?? 0,
334
+ apiAgeMs: apiLoadedAt > 0 ? Date.now() - apiLoadedAt : -1,
335
+ fileCount: fileCache?.size ?? 0,
336
+ };
337
+ }
@@ -0,0 +1,311 @@
1
+ /**
2
+ * Native-binding resolver for Electron-runtime mismatches.
3
+ *
4
+ * Why this module exists
5
+ * ----------------------
6
+ * `better-sqlite3` uses raw v8/nan bindings, so its compiled `.node` file is
7
+ * locked to a specific NODE_MODULE_VERSION (Node-API ABI revision). When
8
+ * OpenCode Desktop (Electron 41 → ABI 145) loads a plugin whose `node_modules`
9
+ * was populated by `bun install` / `npm install` under a different runtime,
10
+ * the fetched prebuild is for `node-vNNN` (e.g. ABI 137 for Node 22) and
11
+ * Electron refuses to load it with:
12
+ *
13
+ * The module '...better_sqlite3.node' was compiled against a different
14
+ * Node.js version using NODE_MODULE_VERSION 137. This version of Node.js
15
+ * requires NODE_MODULE_VERSION 145.
16
+ *
17
+ * `onnxruntime-node` (used by `@huggingface/transformers` for local
18
+ * embeddings) is N-API v3 and is ABI-stable across runtimes, so it does NOT
19
+ * have this problem. Only `better-sqlite3` is affected.
20
+ *
21
+ * What this does
22
+ * --------------
23
+ * On plugin load, before constructing any `Database`:
24
+ *
25
+ * 1. If we are NOT running under Electron (`process.versions.electron` is
26
+ * unset), return null. Bun uses `bun:sqlite` and never reaches this code;
27
+ * Pi/Node-CLI install matching Node-vNNN prebuilds via npm, which work
28
+ * natively against the on-disk binary.
29
+ *
30
+ * 2. If we ARE on Electron, locate the `.node` file path that
31
+ * `better-sqlite3`'s default `bindings()` lookup would try first. Probe
32
+ * its ABI by attempting a sandboxed `process.dlopen`. If it succeeds
33
+ * (Electron-compatible), return null — the default lookup will work.
34
+ *
35
+ * 3. Otherwise, look for a cached Electron prebuild at
36
+ * `<XDG_CACHE_HOME>/cortexkit/native-bindings/better-sqlite3/v<version>/electron-v<abi>-<platform>-<arch>/better_sqlite3.node`.
37
+ * Download it from the `WiseLibs/better-sqlite3` GitHub release if
38
+ * missing, extract with `nanotar` (pure-JS, ~45 KB, zero deps), validate
39
+ * the ABI, and return the absolute path.
40
+ *
41
+ * The caller (`sqlite.ts`) then passes this path through `better-sqlite3`'s
42
+ * documented `nativeBinding` constructor option:
43
+ *
44
+ * new Database(filename, { nativeBinding: <our cached path> })
45
+ *
46
+ * `better-sqlite3` calls `require()` directly on that path, bypassing the
47
+ * normal `bindings()` lookup chain. This is a first-class API the maintainer
48
+ * added for exactly this kind of cross-runtime extension scenario — see
49
+ * `node_modules/better-sqlite3/lib/database.js` `nativeBinding` handling.
50
+ *
51
+ * Why we don't replace the on-disk binary
52
+ * ---------------------------------------
53
+ * An earlier iteration copied the cached Electron binary over the in-tree
54
+ * `node_modules/.../better_sqlite3.node`. That worked but mutates a shared
55
+ * resource: in monorepo dev setups (or any case where multiple runtimes
56
+ * share one `node_modules`), a Pi process opening the plugin from the same
57
+ * workspace would then load the Electron-ABI binary and fail. Returning a
58
+ * separate cached path keeps the on-disk file untouched so each runtime
59
+ * sees the binary it needs.
60
+ *
61
+ * Failure modes
62
+ * -------------
63
+ * If GitHub is unreachable (corporate firewall, offline laptop, rate limit)
64
+ * AND no cached binary exists, this throws. The caller (sqlite.ts →
65
+ * openDatabase) surfaces a `storage unavailable` error and Magic Context
66
+ * disables itself for the run. The user can connect to the network and
67
+ * restart, or wait for a cached binary from a previous successful launch.
68
+ */
69
+
70
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
71
+ import { createRequire } from "node:module";
72
+ import * as path from "node:path";
73
+ import { parseTarGzip } from "nanotar";
74
+ import { getCacheDir } from "./data-path";
75
+ import { log } from "./logger";
76
+
77
+ const PREFIX = "[native-binding]";
78
+
79
+ function logInfo(message: string): void {
80
+ log(`${PREFIX} ${message}`);
81
+ }
82
+
83
+ function logWarn(message: string): void {
84
+ log(`${PREFIX} WARN ${message}`);
85
+ }
86
+
87
+ /**
88
+ * Result of probing a `.node` file's ABI by attempting a sandboxed `dlopen`.
89
+ *
90
+ * - `ok: true` means the runtime accepted the binary; the on-disk file is
91
+ * already Electron-compatible and we don't need to do anything.
92
+ * - `ok: false` carries the parsed `actual` ABI for diagnostics (or `null`
93
+ * if the error message didn't match any known shape).
94
+ */
95
+ type ProbeResult = { ok: true } | { ok: false; expected: string; actual: string | null };
96
+
97
+ function probeAbi(binaryPath: string): ProbeResult {
98
+ const expected = process.versions.modules;
99
+ try {
100
+ // Throwaway sandbox: process.dlopen runs the module's init function
101
+ // against `sandbox.exports`. On ABI mismatch it throws BEFORE init
102
+ // runs, so the binary is NOT loaded into process memory in the
103
+ // failure case. On success the binary IS loaded (Node refcounts
104
+ // these, so a second dlopen by the real `require()` is cheap).
105
+ const sandbox = { exports: {} as Record<string, unknown> };
106
+ process.dlopen(sandbox, binaryPath);
107
+ return { ok: true };
108
+ } catch (err) {
109
+ const message = err instanceof Error ? err.message : String(err);
110
+ const pair = message.match(/NODE_MODULE_VERSION (\d+).*NODE_MODULE_VERSION (\d+)/s);
111
+ if (pair?.[1] && pair[2]) {
112
+ return { ok: false, expected: pair[2], actual: pair[1] };
113
+ }
114
+ const single = message.match(/NODE_MODULE_VERSION[ =:]+(\d+)/);
115
+ if (single?.[1]) {
116
+ return { ok: false, expected, actual: single[1] };
117
+ }
118
+ // Couldn't parse — log raw message so we can refine the regex if a
119
+ // future runtime emits a different shape.
120
+ logWarn(`could not parse ABI from dlopen error: ${message}`);
121
+ return { ok: false, expected, actual: null };
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Locate the on-disk path `better-sqlite3` ships its `.node` file at, plus
127
+ * the package version. Returns null if better-sqlite3 isn't resolvable —
128
+ * that's a broken install we let propagate naturally through the dynamic
129
+ * import in sqlite.ts.
130
+ */
131
+ function resolveBetterSqlite3OnDisk(
132
+ requireFn: NodeRequire,
133
+ ): { binaryPath: string; pkgVersion: string } | null {
134
+ try {
135
+ const pkgJsonPath = requireFn.resolve("better-sqlite3/package.json");
136
+ const pkgDir = path.dirname(pkgJsonPath);
137
+ const pkgJson = requireFn(pkgJsonPath) as { version: string };
138
+ const binaryPath = path.join(pkgDir, "build", "Release", "better_sqlite3.node");
139
+ return { binaryPath, pkgVersion: pkgJson.version };
140
+ } catch (err) {
141
+ logWarn(
142
+ `could not resolve better-sqlite3 in node_modules: ${err instanceof Error ? err.message : String(err)}`,
143
+ );
144
+ return null;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Cache directory for downloaded native bindings. Keyed by
150
+ * `<pkgVersion>/electron-v<abi>-<platform>-<arch>` so a Magic Context update
151
+ * that bumps better-sqlite3 or an OpenCode update that bumps Electron both
152
+ * trigger a fresh download cleanly.
153
+ */
154
+ function getCachedBinaryPath(pkgVersion: string, abi: string): string {
155
+ return path.join(
156
+ getCacheDir(),
157
+ "cortexkit",
158
+ "native-bindings",
159
+ "better-sqlite3",
160
+ `v${pkgVersion}`,
161
+ `electron-v${abi}-${process.platform}-${process.arch}`,
162
+ "better_sqlite3.node",
163
+ );
164
+ }
165
+
166
+ /**
167
+ * Download the Electron-targeted prebuild tarball from WiseLibs/better-sqlite3
168
+ * GitHub releases and extract the `.node` bytes. Throws on HTTP failure or
169
+ * if the tarball doesn't contain the expected file.
170
+ */
171
+ async function downloadElectronPrebuild(pkgVersion: string, abi: string): Promise<Uint8Array> {
172
+ const filename = `better-sqlite3-v${pkgVersion}-electron-v${abi}-${process.platform}-${process.arch}.tar.gz`;
173
+ const url = `https://github.com/WiseLibs/better-sqlite3/releases/download/v${pkgVersion}/${filename}`;
174
+ logInfo(`downloading ${url}`);
175
+
176
+ const response = await fetch(url, {
177
+ redirect: "follow",
178
+ headers: { "User-Agent": "magic-context-plugin/native-binding" },
179
+ });
180
+ if (!response.ok) {
181
+ throw new Error(
182
+ `failed to download Electron prebuild (HTTP ${response.status} ${response.statusText}) from ${url}`,
183
+ );
184
+ }
185
+
186
+ const tarballBytes = new Uint8Array(await response.arrayBuffer());
187
+ logInfo(`downloaded ${(tarballBytes.length / 1024).toFixed(1)} KB; extracting`);
188
+
189
+ const files = await parseTarGzip(tarballBytes);
190
+ const nodeFile = files.find((f) => f.name.endsWith("better_sqlite3.node"));
191
+ if (!nodeFile?.data) {
192
+ const names = files.map((f) => f.name).join(", ");
193
+ throw new Error(
194
+ `Electron prebuild tarball did not contain better_sqlite3.node; got: [${names}]`,
195
+ );
196
+ }
197
+ return nodeFile.data instanceof Uint8Array ? nodeFile.data : new Uint8Array(nodeFile.data);
198
+ }
199
+
200
+ /**
201
+ * Singleton promise so concurrent callers (multiple plugin init paths in the
202
+ * same process) only do the check + download once. Reset to null after
203
+ * completion so a future call can retry on transient failures.
204
+ */
205
+ let inFlight: Promise<string | null> | null = null;
206
+
207
+ /**
208
+ * Resolve the absolute path to a `better-sqlite3` `.node` binary that the
209
+ * current runtime can load.
210
+ *
211
+ * - Returns `null` outside Electron (Bun uses `bun:sqlite`; Pi/Node CLI
212
+ * loads matching prebuilds from `node_modules` natively).
213
+ * - Returns `null` on Electron when the on-disk binary already matches
214
+ * the runtime's ABI (rare but possible — a future OpenCode build that
215
+ * post-install-rebuilds for Electron would hit this fast path).
216
+ * - Returns the cached/downloaded prebuild path on Electron when the
217
+ * on-disk binary's ABI doesn't match.
218
+ *
219
+ * The returned path is suitable as the `nativeBinding` option to
220
+ * `new Database(filename, { nativeBinding })`. better-sqlite3 calls `require()`
221
+ * directly on it, bypassing the default `bindings()` lookup chain — this is
222
+ * a documented public API in better-sqlite3, not an internal hack.
223
+ */
224
+ export async function resolveBetterSqliteNativeBinding(): Promise<string | null> {
225
+ if (!process.versions.electron) {
226
+ return null;
227
+ }
228
+
229
+ if (inFlight) {
230
+ return inFlight;
231
+ }
232
+
233
+ const promise = (async () => {
234
+ const expected = process.versions.modules;
235
+ logInfo(
236
+ `Electron detected (v${process.versions.electron}, NODE_MODULE_VERSION ${expected}); verifying better-sqlite3 binding`,
237
+ );
238
+
239
+ const requireFn = createRequire(import.meta.url);
240
+ const resolved = resolveBetterSqlite3OnDisk(requireFn);
241
+ if (!resolved) {
242
+ return null;
243
+ }
244
+ const { binaryPath: diskPath, pkgVersion } = resolved;
245
+
246
+ // Fast path: if the on-disk binary already matches the runtime's
247
+ // ABI, we don't need to override the lookup at all. This handles
248
+ // any future OpenCode build that rebuilds native modules for
249
+ // Electron at install time, plus the case where the user manually
250
+ // ran `prebuild-install --runtime=electron`.
251
+ if (existsSync(diskPath)) {
252
+ const diskProbe = probeAbi(diskPath);
253
+ if (diskProbe.ok) {
254
+ logInfo(
255
+ `on-disk binary already matches Electron ABI v${expected}; using default bindings() lookup`,
256
+ );
257
+ return null;
258
+ }
259
+ logInfo(
260
+ `on-disk binary ABI ${diskProbe.actual ?? "unknown"} != required ${expected}; will use Electron prebuild`,
261
+ );
262
+ } else {
263
+ logWarn(
264
+ `expected better-sqlite3 binary not found at ${diskPath}; will fetch Electron prebuild anyway`,
265
+ );
266
+ }
267
+
268
+ // Look for a cached Electron prebuild from a previous launch.
269
+ const cachedPath = getCachedBinaryPath(pkgVersion, expected);
270
+ if (existsSync(cachedPath)) {
271
+ const cachedProbe = probeAbi(cachedPath);
272
+ if (cachedProbe.ok) {
273
+ logInfo(`using cached Electron prebuild at ${cachedPath}`);
274
+ return cachedPath;
275
+ }
276
+ logWarn(
277
+ `cached binary at ${cachedPath} has wrong ABI (${cachedProbe.actual ?? "unknown"} != ${expected}); refetching`,
278
+ );
279
+ }
280
+
281
+ // Download fresh.
282
+ mkdirSync(path.dirname(cachedPath), { recursive: true });
283
+ const nodeFileBytes = await downloadElectronPrebuild(pkgVersion, expected);
284
+ writeFileSync(cachedPath, nodeFileBytes);
285
+ logInfo(
286
+ `cached Electron prebuild at ${cachedPath} (${(nodeFileBytes.length / 1024).toFixed(1)} KB)`,
287
+ );
288
+
289
+ // Validate the freshly downloaded binary before returning it — if
290
+ // the upstream tarball was malformed or for the wrong ABI, fail
291
+ // loudly here rather than letting the better-sqlite3 constructor
292
+ // throw a less actionable error later.
293
+ const finalProbe = probeAbi(cachedPath);
294
+ if (!finalProbe.ok) {
295
+ throw new Error(
296
+ `downloaded Electron prebuild has wrong ABI (${finalProbe.actual ?? "unknown"} != ${expected}); refusing to use`,
297
+ );
298
+ }
299
+
300
+ return cachedPath;
301
+ })();
302
+
303
+ inFlight = promise;
304
+ try {
305
+ return await promise;
306
+ } finally {
307
+ if (inFlight === promise) {
308
+ inFlight = null;
309
+ }
310
+ }
311
+ }
@@ -0,0 +1,40 @@
1
+ export interface NormalizeSDKResponseOptions {
2
+ preferResponseOnMissingData?: boolean;
3
+ }
4
+
5
+ // Audit note: `as TData` casts are intentional at this boundary. The OpenCode plugin SDK types
6
+ // external responses as `unknown`. Adding Zod validation here would require schema definitions
7
+ // for every SDK response shape, which changes with each OpenCode release. The fallback parameter
8
+ // provides safe degradation when shapes mismatch.
9
+ export function normalizeSDKResponse<TData>(
10
+ response: unknown,
11
+ fallback: TData,
12
+ options?: NormalizeSDKResponseOptions,
13
+ ): TData {
14
+ if (response === null || response === undefined) {
15
+ return fallback;
16
+ }
17
+
18
+ if (Array.isArray(response)) {
19
+ return response as TData;
20
+ }
21
+
22
+ if (typeof response === "object" && "data" in response) {
23
+ const data = (response as { data?: unknown }).data;
24
+ if (data !== null && data !== undefined) {
25
+ return data as TData;
26
+ }
27
+
28
+ if (options?.preferResponseOnMissingData === true) {
29
+ return response as TData;
30
+ }
31
+
32
+ return fallback;
33
+ }
34
+
35
+ if (options?.preferResponseOnMissingData === true) {
36
+ return response as TData;
37
+ }
38
+
39
+ return fallback;
40
+ }