@dev-sergeev/datalab-kit 0.1.2 → 0.1.4

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 (355) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +23 -5
  3. package/THIRD_PARTY_NOTICES.md +6 -2
  4. package/docs/adr/0001-user-settings-priority.md +2 -0
  5. package/docs/adr/0002-package-delivery.md +8 -0
  6. package/node_modules/@pi-plugins/elapsed/LICENSE +21 -0
  7. package/node_modules/@pi-plugins/elapsed/README.md +45 -0
  8. package/node_modules/@pi-plugins/elapsed/dist/index.d.mts +8 -0
  9. package/node_modules/@pi-plugins/elapsed/dist/index.d.mts.map +1 -0
  10. package/node_modules/@pi-plugins/elapsed/dist/index.mjs +47 -0
  11. package/node_modules/@pi-plugins/elapsed/dist/index.mjs.map +1 -0
  12. package/node_modules/@pi-plugins/elapsed/package.json +65 -0
  13. package/node_modules/@tifan/pi-recap/README.md +61 -0
  14. package/node_modules/@tifan/pi-recap/package.json +43 -0
  15. package/node_modules/@tifan/pi-recap/src/index.ts +586 -0
  16. package/node_modules/@tifan/pi-recap/src/model-picker.ts +234 -0
  17. package/node_modules/@tifan/pi-recap/src/models.ts +180 -0
  18. package/node_modules/@tifan/pi-recap/src/sanitize.ts +119 -0
  19. package/node_modules/@tifan/pi-recap/src/tui.ts +155 -0
  20. package/node_modules/@zigai/pi-extension-internals/README.md +24 -0
  21. package/node_modules/@zigai/pi-extension-internals/dist/editor-enhancer-registry.d.ts +21 -0
  22. package/node_modules/@zigai/pi-extension-internals/dist/editor-enhancer-registry.js +233 -0
  23. package/node_modules/@zigai/pi-extension-internals/dist/index.d.ts +6 -0
  24. package/node_modules/@zigai/pi-extension-internals/dist/index.js +3 -0
  25. package/node_modules/@zigai/pi-extension-internals/dist/linked-method-patch.d.ts +34 -0
  26. package/node_modules/@zigai/pi-extension-internals/dist/linked-method-patch.js +272 -0
  27. package/node_modules/@zigai/pi-extension-internals/dist/pi-internal-import.d.ts +11 -0
  28. package/node_modules/@zigai/pi-extension-internals/dist/pi-internal-import.js +139 -0
  29. package/node_modules/@zigai/pi-extension-internals/package.json +41 -0
  30. package/node_modules/@zigai/pi-extension-settings/LICENSE +21 -0
  31. package/node_modules/@zigai/pi-extension-settings/README.md +36 -0
  32. package/node_modules/@zigai/pi-extension-settings/dist/artifacts.d.ts +23 -0
  33. package/node_modules/@zigai/pi-extension-settings/dist/artifacts.d.ts.map +1 -0
  34. package/node_modules/@zigai/pi-extension-settings/dist/artifacts.js +75 -0
  35. package/node_modules/@zigai/pi-extension-settings/dist/artifacts.js.map +1 -0
  36. package/node_modules/@zigai/pi-extension-settings/dist/cli-entry.d.ts +3 -0
  37. package/node_modules/@zigai/pi-extension-settings/dist/cli-entry.d.ts.map +1 -0
  38. package/node_modules/@zigai/pi-extension-settings/dist/cli-entry.js +5 -0
  39. package/node_modules/@zigai/pi-extension-settings/dist/cli-entry.js.map +1 -0
  40. package/node_modules/@zigai/pi-extension-settings/dist/cli.d.ts +6 -0
  41. package/node_modules/@zigai/pi-extension-settings/dist/cli.d.ts.map +1 -0
  42. package/node_modules/@zigai/pi-extension-settings/dist/cli.js +87 -0
  43. package/node_modules/@zigai/pi-extension-settings/dist/cli.js.map +1 -0
  44. package/node_modules/@zigai/pi-extension-settings/dist/definition-marker.d.ts +2 -0
  45. package/node_modules/@zigai/pi-extension-settings/dist/definition-marker.d.ts.map +1 -0
  46. package/node_modules/@zigai/pi-extension-settings/dist/definition-marker.js +2 -0
  47. package/node_modules/@zigai/pi-extension-settings/dist/definition-marker.js.map +1 -0
  48. package/node_modules/@zigai/pi-extension-settings/dist/definition.d.ts +159 -0
  49. package/node_modules/@zigai/pi-extension-settings/dist/definition.d.ts.map +1 -0
  50. package/node_modules/@zigai/pi-extension-settings/dist/definition.js +248 -0
  51. package/node_modules/@zigai/pi-extension-settings/dist/definition.js.map +1 -0
  52. package/node_modules/@zigai/pi-extension-settings/dist/file-system.d.ts +10 -0
  53. package/node_modules/@zigai/pi-extension-settings/dist/file-system.d.ts.map +1 -0
  54. package/node_modules/@zigai/pi-extension-settings/dist/file-system.js +115 -0
  55. package/node_modules/@zigai/pi-extension-settings/dist/file-system.js.map +1 -0
  56. package/node_modules/@zigai/pi-extension-settings/dist/index.d.ts +2 -0
  57. package/node_modules/@zigai/pi-extension-settings/dist/index.d.ts.map +1 -0
  58. package/node_modules/@zigai/pi-extension-settings/dist/index.js +2 -0
  59. package/node_modules/@zigai/pi-extension-settings/dist/index.js.map +1 -0
  60. package/node_modules/@zigai/pi-extension-settings/dist/json-value.d.ts +18 -0
  61. package/node_modules/@zigai/pi-extension-settings/dist/json-value.d.ts.map +1 -0
  62. package/node_modules/@zigai/pi-extension-settings/dist/json-value.js +56 -0
  63. package/node_modules/@zigai/pi-extension-settings/dist/json-value.js.map +1 -0
  64. package/node_modules/@zigai/pi-extension-settings/dist/paths.d.ts +11 -0
  65. package/node_modules/@zigai/pi-extension-settings/dist/paths.d.ts.map +1 -0
  66. package/node_modules/@zigai/pi-extension-settings/dist/paths.js +23 -0
  67. package/node_modules/@zigai/pi-extension-settings/dist/paths.js.map +1 -0
  68. package/node_modules/@zigai/pi-extension-settings/dist/pi-host-paths.d.ts +5 -0
  69. package/node_modules/@zigai/pi-extension-settings/dist/pi-host-paths.d.ts.map +1 -0
  70. package/node_modules/@zigai/pi-extension-settings/dist/pi-host-paths.js +21 -0
  71. package/node_modules/@zigai/pi-extension-settings/dist/pi-host-paths.js.map +1 -0
  72. package/node_modules/@zigai/pi-extension-settings/dist/pi.d.ts +106 -0
  73. package/node_modules/@zigai/pi-extension-settings/dist/pi.d.ts.map +1 -0
  74. package/node_modules/@zigai/pi-extension-settings/dist/pi.js +122 -0
  75. package/node_modules/@zigai/pi-extension-settings/dist/pi.js.map +1 -0
  76. package/node_modules/@zigai/pi-extension-settings/dist/pi.ts +2537 -0
  77. package/node_modules/@zigai/pi-extension-settings/dist/pi.ts.map +7 -0
  78. package/node_modules/@zigai/pi-extension-settings/dist/projects.d.ts +10 -0
  79. package/node_modules/@zigai/pi-extension-settings/dist/projects.d.ts.map +1 -0
  80. package/node_modules/@zigai/pi-extension-settings/dist/projects.js +177 -0
  81. package/node_modules/@zigai/pi-extension-settings/dist/projects.js.map +1 -0
  82. package/node_modules/@zigai/pi-extension-settings/dist/runtime.d.ts +40 -0
  83. package/node_modules/@zigai/pi-extension-settings/dist/runtime.d.ts.map +1 -0
  84. package/node_modules/@zigai/pi-extension-settings/dist/runtime.js +158 -0
  85. package/node_modules/@zigai/pi-extension-settings/dist/runtime.js.map +1 -0
  86. package/node_modules/@zigai/pi-extension-settings/dist/runtime.ts +158 -0
  87. package/node_modules/@zigai/pi-extension-settings/dist/runtime.ts.map +7 -0
  88. package/node_modules/@zigai/pi-extension-settings/dist/schema-document.d.ts +19 -0
  89. package/node_modules/@zigai/pi-extension-settings/dist/schema-document.d.ts.map +1 -0
  90. package/node_modules/@zigai/pi-extension-settings/dist/schema-document.js +168 -0
  91. package/node_modules/@zigai/pi-extension-settings/dist/schema-document.js.map +1 -0
  92. package/node_modules/@zigai/pi-extension-settings/dist/settings-documentation.d.ts +9 -0
  93. package/node_modules/@zigai/pi-extension-settings/dist/settings-documentation.d.ts.map +1 -0
  94. package/node_modules/@zigai/pi-extension-settings/dist/settings-documentation.js +242 -0
  95. package/node_modules/@zigai/pi-extension-settings/dist/settings-documentation.js.map +1 -0
  96. package/node_modules/@zigai/pi-extension-settings/dist/settings-layer.d.ts +59 -0
  97. package/node_modules/@zigai/pi-extension-settings/dist/settings-layer.d.ts.map +1 -0
  98. package/node_modules/@zigai/pi-extension-settings/dist/settings-layer.js +98 -0
  99. package/node_modules/@zigai/pi-extension-settings/dist/settings-layer.js.map +1 -0
  100. package/node_modules/@zigai/pi-extension-settings/dist/settings-loader.d.ts +80 -0
  101. package/node_modules/@zigai/pi-extension-settings/dist/settings-loader.d.ts.map +1 -0
  102. package/node_modules/@zigai/pi-extension-settings/dist/settings-loader.js +144 -0
  103. package/node_modules/@zigai/pi-extension-settings/dist/settings-loader.js.map +1 -0
  104. package/node_modules/@zigai/pi-extension-settings/dist/settings-merge.d.ts +5 -0
  105. package/node_modules/@zigai/pi-extension-settings/dist/settings-merge.d.ts.map +1 -0
  106. package/node_modules/@zigai/pi-extension-settings/dist/settings-merge.js +30 -0
  107. package/node_modules/@zigai/pi-extension-settings/dist/settings-merge.js.map +1 -0
  108. package/node_modules/@zigai/pi-extension-settings/dist/settings-revision.d.ts +10 -0
  109. package/node_modules/@zigai/pi-extension-settings/dist/settings-revision.d.ts.map +1 -0
  110. package/node_modules/@zigai/pi-extension-settings/dist/settings-revision.js +16 -0
  111. package/node_modules/@zigai/pi-extension-settings/dist/settings-revision.js.map +1 -0
  112. package/node_modules/@zigai/pi-extension-settings/dist/settings-transaction.d.ts +54 -0
  113. package/node_modules/@zigai/pi-extension-settings/dist/settings-transaction.d.ts.map +1 -0
  114. package/node_modules/@zigai/pi-extension-settings/dist/settings-transaction.js +202 -0
  115. package/node_modules/@zigai/pi-extension-settings/dist/settings-transaction.js.map +1 -0
  116. package/node_modules/@zigai/pi-extension-settings/dist/typebox-runtime.d.ts +5 -0
  117. package/node_modules/@zigai/pi-extension-settings/dist/typebox-runtime.d.ts.map +1 -0
  118. package/node_modules/@zigai/pi-extension-settings/dist/typebox-runtime.js +9 -0
  119. package/node_modules/@zigai/pi-extension-settings/dist/typebox-runtime.js.map +1 -0
  120. package/node_modules/@zigai/pi-extension-settings/docs/generation.md +71 -0
  121. package/node_modules/@zigai/pi-extension-settings/docs/manual-setup.md +98 -0
  122. package/node_modules/@zigai/pi-extension-settings/docs/runtime.md +100 -0
  123. package/node_modules/@zigai/pi-extension-settings/docs/ui-controls.md +31 -0
  124. package/node_modules/@zigai/pi-extension-settings/package.json +97 -0
  125. package/node_modules/@zigai/pi-mention-anything/README.md +113 -0
  126. package/node_modules/@zigai/pi-mention-anything/config.schema.json +313 -0
  127. package/node_modules/@zigai/pi-mention-anything/docs/command-protocol.md +106 -0
  128. package/node_modules/@zigai/pi-mention-anything/docs/providers.md +128 -0
  129. package/node_modules/@zigai/pi-mention-anything/examples/query-command.mjs +96 -0
  130. package/node_modules/@zigai/pi-mention-anything/examples/recursive-tree.ts +28 -0
  131. package/node_modules/@zigai/pi-mention-anything/examples/static.ts +28 -0
  132. package/node_modules/@zigai/pi-mention-anything/examples/tmux.ts +90 -0
  133. package/node_modules/@zigai/pi-mention-anything/examples/tree-settings.json +25 -0
  134. package/node_modules/@zigai/pi-mention-anything/package.json +58 -0
  135. package/node_modules/@zigai/pi-mention-anything/src/api.ts +75 -0
  136. package/node_modules/@zigai/pi-mention-anything/src/autocomplete.ts +231 -0
  137. package/node_modules/@zigai/pi-mention-anything/src/chain-autocomplete.ts +596 -0
  138. package/node_modules/@zigai/pi-mention-anything/src/chain-syntax.ts +345 -0
  139. package/node_modules/@zigai/pi-mention-anything/src/command-provider.ts +291 -0
  140. package/node_modules/@zigai/pi-mention-anything/src/configured-source.ts +66 -0
  141. package/node_modules/@zigai/pi-mention-anything/src/editor.ts +180 -0
  142. package/node_modules/@zigai/pi-mention-anything/src/expand-mentions.ts +162 -0
  143. package/node_modules/@zigai/pi-mention-anything/src/index.ts +54 -0
  144. package/node_modules/@zigai/pi-mention-anything/src/initial-suggestions.ts +190 -0
  145. package/node_modules/@zigai/pi-mention-anything/src/list-provider.ts +71 -0
  146. package/node_modules/@zigai/pi-mention-anything/src/mention-hub.ts +307 -0
  147. package/node_modules/@zigai/pi-mention-anything/src/mention-resolution.ts +374 -0
  148. package/node_modules/@zigai/pi-mention-anything/src/mention-syntax.ts +105 -0
  149. package/node_modules/@zigai/pi-mention-anything/src/register-mention.ts +89 -0
  150. package/node_modules/@zigai/pi-mention-anything/src/rendering.ts +53 -0
  151. package/node_modules/@zigai/pi-mention-anything/src/selected-items.ts +21 -0
  152. package/node_modules/@zigai/pi-mention-anything/src/selection-history.ts +135 -0
  153. package/node_modules/@zigai/pi-mention-anything/src/settings-input.ts +317 -0
  154. package/node_modules/@zigai/pi-mention-anything/src/settings.prevalidated.ts +57 -0
  155. package/node_modules/@zigai/pi-mention-anything/src/settings.ts +52 -0
  156. package/node_modules/@zigai/pi-mention-anything/src/source-contract.ts +174 -0
  157. package/node_modules/@zigai/pi-mention-anything/src/source-controller.ts +1070 -0
  158. package/node_modules/@zigai/pi-mention-anything/src/source-runtime.ts +99 -0
  159. package/node_modules/@zigai/pi-mention-skill/README.md +60 -0
  160. package/node_modules/@zigai/pi-mention-skill/config.schema.json +81 -0
  161. package/node_modules/@zigai/pi-mention-skill/package.json +56 -0
  162. package/node_modules/@zigai/pi-mention-skill/src/index.ts +60 -0
  163. package/node_modules/@zigai/pi-mention-skill/src/settings-input.ts +74 -0
  164. package/node_modules/@zigai/pi-mention-skill/src/settings.prevalidated.ts +18 -0
  165. package/node_modules/@zigai/pi-mention-skill/src/settings.ts +54 -0
  166. package/node_modules/@zigai/pi-mention-skill/src/skill-commands.ts +18 -0
  167. package/node_modules/@zigai/pi-mention-skill/src/skill-content.ts +60 -0
  168. package/node_modules/@zigai/pi-mention-skill/src/skill-provider.ts +105 -0
  169. package/node_modules/@zigai/pi-mention-skill/src/slash-skill-filter.ts +29 -0
  170. package/node_modules/argparse/LICENSE +21 -0
  171. package/node_modules/argparse/README.md +257 -0
  172. package/node_modules/argparse/index.js +3 -0
  173. package/node_modules/argparse/lib/action/append/constant.js +47 -0
  174. package/node_modules/argparse/lib/action/append.js +53 -0
  175. package/node_modules/argparse/lib/action/count.js +40 -0
  176. package/node_modules/argparse/lib/action/help.js +47 -0
  177. package/node_modules/argparse/lib/action/store/constant.js +43 -0
  178. package/node_modules/argparse/lib/action/store/false.js +27 -0
  179. package/node_modules/argparse/lib/action/store/true.js +26 -0
  180. package/node_modules/argparse/lib/action/store.js +50 -0
  181. package/node_modules/argparse/lib/action/subparsers.js +149 -0
  182. package/node_modules/argparse/lib/action/version.js +47 -0
  183. package/node_modules/argparse/lib/action.js +146 -0
  184. package/node_modules/argparse/lib/action_container.js +482 -0
  185. package/node_modules/argparse/lib/argparse.js +14 -0
  186. package/node_modules/argparse/lib/argument/error.js +50 -0
  187. package/node_modules/argparse/lib/argument/exclusive.js +54 -0
  188. package/node_modules/argparse/lib/argument/group.js +75 -0
  189. package/node_modules/argparse/lib/argument_parser.js +1161 -0
  190. package/node_modules/argparse/lib/const.js +21 -0
  191. package/node_modules/argparse/lib/help/added_formatters.js +87 -0
  192. package/node_modules/argparse/lib/help/formatter.js +795 -0
  193. package/node_modules/argparse/lib/namespace.js +76 -0
  194. package/node_modules/argparse/lib/utils.js +57 -0
  195. package/node_modules/argparse/package.json +34 -0
  196. package/node_modules/esprima/LICENSE.BSD +21 -0
  197. package/node_modules/esprima/README.md +46 -0
  198. package/node_modules/esprima/bin/esparse.js +139 -0
  199. package/node_modules/esprima/bin/esvalidate.js +236 -0
  200. package/node_modules/esprima/dist/esprima.js +6709 -0
  201. package/node_modules/esprima/package.json +112 -0
  202. package/node_modules/extend-shallow/LICENSE +21 -0
  203. package/node_modules/extend-shallow/README.md +61 -0
  204. package/node_modules/extend-shallow/index.js +33 -0
  205. package/node_modules/extend-shallow/package.json +56 -0
  206. package/node_modules/graceful-fs/LICENSE +15 -0
  207. package/node_modules/graceful-fs/README.md +143 -0
  208. package/node_modules/graceful-fs/clone.js +23 -0
  209. package/node_modules/graceful-fs/graceful-fs.js +448 -0
  210. package/node_modules/graceful-fs/legacy-streams.js +118 -0
  211. package/node_modules/graceful-fs/package.json +53 -0
  212. package/node_modules/graceful-fs/polyfills.js +355 -0
  213. package/node_modules/gray-matter/LICENSE +21 -0
  214. package/node_modules/gray-matter/README.md +565 -0
  215. package/node_modules/gray-matter/gray-matter.d.ts +114 -0
  216. package/node_modules/gray-matter/index.js +228 -0
  217. package/node_modules/gray-matter/lib/defaults.js +18 -0
  218. package/node_modules/gray-matter/lib/engine.js +30 -0
  219. package/node_modules/gray-matter/lib/engines.js +54 -0
  220. package/node_modules/gray-matter/lib/excerpt.js +32 -0
  221. package/node_modules/gray-matter/lib/parse.js +13 -0
  222. package/node_modules/gray-matter/lib/stringify.js +56 -0
  223. package/node_modules/gray-matter/lib/to-file.js +43 -0
  224. package/node_modules/gray-matter/lib/utils.js +66 -0
  225. package/node_modules/gray-matter/package.json +127 -0
  226. package/node_modules/is-extendable/LICENSE +21 -0
  227. package/node_modules/is-extendable/README.md +72 -0
  228. package/node_modules/is-extendable/index.js +13 -0
  229. package/node_modules/is-extendable/package.json +51 -0
  230. package/node_modules/js-yaml/LICENSE +21 -0
  231. package/node_modules/js-yaml/README.md +302 -0
  232. package/node_modules/js-yaml/bin/js-yaml.js +132 -0
  233. package/node_modules/js-yaml/dist/js-yaml.js +4024 -0
  234. package/node_modules/js-yaml/dist/js-yaml.min.js +1 -0
  235. package/node_modules/js-yaml/index.js +7 -0
  236. package/node_modules/js-yaml/lib/js-yaml/common.js +59 -0
  237. package/node_modules/js-yaml/lib/js-yaml/dumper.js +850 -0
  238. package/node_modules/js-yaml/lib/js-yaml/exception.js +43 -0
  239. package/node_modules/js-yaml/lib/js-yaml/loader.js +1679 -0
  240. package/node_modules/js-yaml/lib/js-yaml/mark.js +76 -0
  241. package/node_modules/js-yaml/lib/js-yaml/schema/core.js +18 -0
  242. package/node_modules/js-yaml/lib/js-yaml/schema/default_full.js +25 -0
  243. package/node_modules/js-yaml/lib/js-yaml/schema/default_safe.js +28 -0
  244. package/node_modules/js-yaml/lib/js-yaml/schema/failsafe.js +17 -0
  245. package/node_modules/js-yaml/lib/js-yaml/schema/json.js +25 -0
  246. package/node_modules/js-yaml/lib/js-yaml/schema.js +108 -0
  247. package/node_modules/js-yaml/lib/js-yaml/type/binary.js +138 -0
  248. package/node_modules/js-yaml/lib/js-yaml/type/bool.js +35 -0
  249. package/node_modules/js-yaml/lib/js-yaml/type/float.js +116 -0
  250. package/node_modules/js-yaml/lib/js-yaml/type/int.js +173 -0
  251. package/node_modules/js-yaml/lib/js-yaml/type/js/function.js +93 -0
  252. package/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js +60 -0
  253. package/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js +28 -0
  254. package/node_modules/js-yaml/lib/js-yaml/type/map.js +8 -0
  255. package/node_modules/js-yaml/lib/js-yaml/type/merge.js +12 -0
  256. package/node_modules/js-yaml/lib/js-yaml/type/null.js +34 -0
  257. package/node_modules/js-yaml/lib/js-yaml/type/omap.js +44 -0
  258. package/node_modules/js-yaml/lib/js-yaml/type/pairs.js +53 -0
  259. package/node_modules/js-yaml/lib/js-yaml/type/seq.js +8 -0
  260. package/node_modules/js-yaml/lib/js-yaml/type/set.js +29 -0
  261. package/node_modules/js-yaml/lib/js-yaml/type/str.js +8 -0
  262. package/node_modules/js-yaml/lib/js-yaml/type/timestamp.js +88 -0
  263. package/node_modules/js-yaml/lib/js-yaml/type.js +61 -0
  264. package/node_modules/js-yaml/lib/js-yaml.js +39 -0
  265. package/node_modules/js-yaml/package.json +52 -0
  266. package/node_modules/kind-of/LICENSE +21 -0
  267. package/node_modules/kind-of/README.md +367 -0
  268. package/node_modules/kind-of/index.js +129 -0
  269. package/node_modules/kind-of/package.json +88 -0
  270. package/node_modules/node-addon-api/common 2.gypi +21 -0
  271. package/node_modules/node-addon-api/except 2.gypi +25 -0
  272. package/node_modules/node-addon-api/napi 2.h +3463 -0
  273. package/node_modules/node-addon-api/napi-inl 2.h +7250 -0
  274. package/node_modules/node-addon-api/napi-inl.deprecated 2.h +186 -0
  275. package/node_modules/node-addon-api/node_addon_api 2.gyp +42 -0
  276. package/node_modules/node-addon-api/node_api 2.gyp +9 -0
  277. package/node_modules/node-addon-api/noexcept 2.gypi +26 -0
  278. package/node_modules/node-addon-api/nothing 2.c +0 -0
  279. package/node_modules/pi-toggle-skills/README.md +213 -0
  280. package/node_modules/pi-toggle-skills/package.json +60 -0
  281. package/node_modules/pi-toggle-skills/src/index.ts +112 -0
  282. package/node_modules/pi-toggle-skills/src/skill-discovery.ts +258 -0
  283. package/node_modules/pi-toggle-skills/src/skill-selector.ts +435 -0
  284. package/node_modules/pi-toggle-skills/toggle-skills 2.ts +316 -0
  285. package/node_modules/pi-toggle-skills/toggle-skills.ts +316 -0
  286. package/node_modules/pi-toggle-skills/vitest.config 2.ts +15 -0
  287. package/node_modules/pi-toggle-skills/vitest.config.ts +15 -0
  288. package/node_modules/proper-lockfile/LICENSE +21 -0
  289. package/node_modules/proper-lockfile/README.md +183 -0
  290. package/node_modules/proper-lockfile/index.js +40 -0
  291. package/node_modules/proper-lockfile/lib/adapter.js +85 -0
  292. package/node_modules/proper-lockfile/lib/lockfile.js +342 -0
  293. package/node_modules/proper-lockfile/lib/mtime-precision.js +55 -0
  294. package/node_modules/proper-lockfile/node_modules/retry/.npmignore +3 -0
  295. package/node_modules/proper-lockfile/node_modules/retry/.travis.yml +15 -0
  296. package/node_modules/proper-lockfile/node_modules/retry/License +21 -0
  297. package/node_modules/proper-lockfile/node_modules/retry/Makefile +18 -0
  298. package/node_modules/proper-lockfile/node_modules/retry/README.md +227 -0
  299. package/node_modules/proper-lockfile/node_modules/retry/equation.gif +0 -0
  300. package/node_modules/proper-lockfile/node_modules/retry/example/dns.js +31 -0
  301. package/node_modules/proper-lockfile/node_modules/retry/example/stop.js +40 -0
  302. package/node_modules/proper-lockfile/node_modules/retry/index.js +1 -0
  303. package/node_modules/proper-lockfile/node_modules/retry/lib/retry.js +100 -0
  304. package/node_modules/proper-lockfile/node_modules/retry/lib/retry_operation.js +158 -0
  305. package/node_modules/proper-lockfile/node_modules/retry/package.json +32 -0
  306. package/node_modules/proper-lockfile/node_modules/retry/test/common.js +10 -0
  307. package/node_modules/proper-lockfile/node_modules/retry/test/integration/test-forever.js +24 -0
  308. package/node_modules/proper-lockfile/node_modules/retry/test/integration/test-retry-operation.js +258 -0
  309. package/node_modules/proper-lockfile/node_modules/retry/test/integration/test-retry-wrap.js +101 -0
  310. package/node_modules/proper-lockfile/node_modules/retry/test/integration/test-timeouts.js +69 -0
  311. package/node_modules/proper-lockfile/package.json +71 -0
  312. package/node_modules/section-matter/LICENSE +21 -0
  313. package/node_modules/section-matter/README.md +236 -0
  314. package/node_modules/section-matter/index.js +136 -0
  315. package/node_modules/section-matter/package.json +55 -0
  316. package/node_modules/signal-exit/LICENSE.txt +16 -0
  317. package/node_modules/signal-exit/README.md +39 -0
  318. package/node_modules/signal-exit/index.js +202 -0
  319. package/node_modules/signal-exit/package.json +38 -0
  320. package/node_modules/signal-exit/signals.js +53 -0
  321. package/node_modules/sprintf-js/.npmignore +1 -0
  322. package/node_modules/sprintf-js/.npmignore 2 +1 -0
  323. package/node_modules/sprintf-js/LICENSE +24 -0
  324. package/node_modules/sprintf-js/LICENSE 2 +24 -0
  325. package/node_modules/sprintf-js/README 2.md +88 -0
  326. package/node_modules/sprintf-js/README.md +88 -0
  327. package/node_modules/sprintf-js/bower 2.json +14 -0
  328. package/node_modules/sprintf-js/bower.json +14 -0
  329. package/node_modules/sprintf-js/demo/angular.html +20 -0
  330. package/node_modules/sprintf-js/dist/angular-sprintf.min.js +4 -0
  331. package/node_modules/sprintf-js/dist/angular-sprintf.min.js.map +1 -0
  332. package/node_modules/sprintf-js/dist/angular-sprintf.min.map +1 -0
  333. package/node_modules/sprintf-js/dist/sprintf.min.js +4 -0
  334. package/node_modules/sprintf-js/dist/sprintf.min.js.map +1 -0
  335. package/node_modules/sprintf-js/dist/sprintf.min.map +1 -0
  336. package/node_modules/sprintf-js/gruntfile 2.js +36 -0
  337. package/node_modules/sprintf-js/gruntfile.js +36 -0
  338. package/node_modules/sprintf-js/package 2.json +22 -0
  339. package/node_modules/sprintf-js/package.json +22 -0
  340. package/node_modules/sprintf-js/src/angular-sprintf.js +18 -0
  341. package/node_modules/sprintf-js/src/sprintf.js +208 -0
  342. package/node_modules/sprintf-js/test/test.js +82 -0
  343. package/node_modules/strip-bom-string/LICENSE +21 -0
  344. package/node_modules/strip-bom-string/README.md +66 -0
  345. package/node_modules/strip-bom-string/index.js +15 -0
  346. package/node_modules/strip-bom-string/package.json +60 -0
  347. package/node_modules/tree-sitter-bash/tree-sitter-bash 2.wasm +0 -0
  348. package/node_modules/typebox/license 2 +23 -0
  349. package/node_modules/typebox/package 2.json +87 -0
  350. package/node_modules/typebox/readme 2.md +370 -0
  351. package/node_modules/zod/compile 2.cjs +96 -0
  352. package/node_modules/zod/compile 2.js +52 -0
  353. package/node_modules/zod/index 2.cjs +52 -0
  354. package/node_modules/zod/index 2.js +7 -0
  355. package/package.json +13 -4
@@ -0,0 +1,234 @@
1
+ // Datalab Kit adaptation
2
+
3
+ import type { ExtensionContext, Theme } from "@earendil-works/pi-coding-agent"
4
+ import {
5
+ Input,
6
+ Key,
7
+ matchesKey,
8
+ truncateToWidth,
9
+ type Component,
10
+ type Focusable,
11
+ } from "@earendil-works/pi-tui"
12
+ import {
13
+ formatRecapModelKey,
14
+ type RecapModelPreference,
15
+ } from "./models.js"
16
+
17
+ const MAX_VISIBLE_ITEMS = 10
18
+
19
+ export type ModelPickerResult =
20
+ | { action: "default" }
21
+ | { action: "model"; model: RecapModelPreference }
22
+ | { action: "cancel" }
23
+
24
+ interface ModelPickerItem {
25
+ readonly label: string
26
+ readonly description?: string
27
+ readonly model?: RecapModelPreference
28
+ }
29
+
30
+ class RecapModelPicker implements Component, Focusable {
31
+ private readonly theme: Theme
32
+ private readonly items: ModelPickerItem[]
33
+ private readonly onDone: (result: ModelPickerResult) => void
34
+ private readonly searchInput = new Input()
35
+ private selectedIndex = 0
36
+
37
+ constructor(
38
+ theme: Theme,
39
+ models: readonly RecapModelPreference[],
40
+ onDone: (result: ModelPickerResult) => void,
41
+ ) {
42
+ this.theme = theme
43
+ this.items = [
44
+ {
45
+ label: "Use default",
46
+ description: "Current session model",
47
+ },
48
+ ...models.map((model) => ({
49
+ label: formatRecapModelKey(model),
50
+ model,
51
+ })),
52
+ ]
53
+ this.onDone = onDone
54
+ }
55
+
56
+ get focused(): boolean {
57
+ return this.searchInput.focused
58
+ }
59
+
60
+ set focused(value: boolean) {
61
+ this.searchInput.focused = value
62
+ }
63
+
64
+ invalidate(): void {
65
+ this.searchInput.invalidate()
66
+ }
67
+
68
+ render(width: number): string[] {
69
+ const filteredItems = this.getFilteredItems()
70
+ const startIndex = getVisibleStartIndex(
71
+ this.selectedIndex,
72
+ filteredItems.length,
73
+ )
74
+ const visibleItems = filteredItems.slice(
75
+ startIndex,
76
+ startIndex + MAX_VISIBLE_ITEMS,
77
+ )
78
+ const lines = [
79
+ this.theme.fg("accent", this.theme.bold("Recap model")),
80
+ this.theme.fg("dim", "Search"),
81
+ ...this.searchInput.render(width),
82
+ "",
83
+ ]
84
+
85
+ if (visibleItems.length === 0) {
86
+ lines.push(this.theme.fg("warning", "No matching models"))
87
+ } else {
88
+ for (const [index, item] of visibleItems.entries()) {
89
+ lines.push(
90
+ this.renderItem(item, startIndex + index === this.selectedIndex),
91
+ )
92
+ }
93
+ }
94
+
95
+ if (filteredItems.length > MAX_VISIBLE_ITEMS) {
96
+ lines.push(
97
+ this.theme.fg(
98
+ "dim",
99
+ truncateToWidth(
100
+ `${this.selectedIndex + 1}/${filteredItems.length}`,
101
+ width,
102
+ ),
103
+ ),
104
+ )
105
+ }
106
+
107
+ lines.push(
108
+ "",
109
+ this.theme.fg("dim", "↑↓ navigate • enter select • esc cancel"),
110
+ )
111
+ return lines.map((line) => truncateToWidth(line, width))
112
+ }
113
+
114
+ handleInput(data: string): void {
115
+ if (matchesKey(data, Key.escape) || matchesKey(data, Key.ctrl("c"))) {
116
+ this.onDone({ action: "cancel" })
117
+ return
118
+ }
119
+
120
+ if (matchesKey(data, Key.enter)) {
121
+ this.selectCurrent()
122
+ return
123
+ }
124
+
125
+ if (matchesKey(data, Key.up)) {
126
+ this.moveSelection(-1)
127
+ return
128
+ }
129
+
130
+ if (matchesKey(data, Key.down)) {
131
+ this.moveSelection(1)
132
+ return
133
+ }
134
+
135
+ const previousFilter = this.getFilter()
136
+ this.searchInput.handleInput(data)
137
+ if (this.getFilter() !== previousFilter) {
138
+ this.selectedIndex = 0
139
+ }
140
+ }
141
+
142
+ private renderItem(item: ModelPickerItem, isSelected: boolean): string {
143
+ const prefix = isSelected ? "→ " : " "
144
+ const label = isSelected
145
+ ? this.theme.fg("accent", item.label)
146
+ : this.theme.fg("text", item.label)
147
+ const description = item.description
148
+ ? this.theme.fg("dim", ` ${item.description}`)
149
+ : ""
150
+ return `${prefix}${label}${description}`
151
+ }
152
+
153
+ private moveSelection(delta: number): void {
154
+ const count = this.getFilteredItems().length
155
+ if (count === 0) return
156
+ this.selectedIndex = (this.selectedIndex + delta + count) % count
157
+ }
158
+
159
+ private selectCurrent(): void {
160
+ const item = this.getFilteredItems()[this.selectedIndex]
161
+ if (!item) return
162
+
163
+ const model = item.model
164
+ if (!model) {
165
+ this.onDone({ action: "default" })
166
+ return
167
+ }
168
+
169
+ this.onDone({ action: "model", model })
170
+ }
171
+
172
+ private getFilter(): string {
173
+ return this.searchInput.getValue().trim().toLowerCase()
174
+ }
175
+
176
+ private getFilteredItems(): ModelPickerItem[] {
177
+ const filter = this.getFilter()
178
+ if (!filter) return this.items
179
+ return this.items.filter(
180
+ (item) =>
181
+ item.label.toLowerCase().includes(filter) ||
182
+ item.description?.toLowerCase().includes(filter),
183
+ )
184
+ }
185
+ }
186
+
187
+ function getVisibleStartIndex(
188
+ selectedIndex: number,
189
+ itemCount: number,
190
+ ): number {
191
+ return Math.max(
192
+ 0,
193
+ Math.min(
194
+ selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2),
195
+ itemCount - MAX_VISIBLE_ITEMS,
196
+ ),
197
+ )
198
+ }
199
+
200
+ class HiddenFooter implements Component {
201
+ invalidate(): void {}
202
+
203
+ render(): string[] {
204
+ return []
205
+ }
206
+ }
207
+
208
+ export async function pickRecapModel(
209
+ ctx: ExtensionContext,
210
+ models: readonly RecapModelPreference[],
211
+ ): Promise<ModelPickerResult> {
212
+ if (!ctx.hasUI) return { action: "cancel" }
213
+
214
+ ctx.ui.setFooter(() => new HiddenFooter())
215
+ return ctx.ui
216
+ .custom<ModelPickerResult>((tui, theme, _keybindings, done) => {
217
+ const picker = new RecapModelPicker(theme, models, done)
218
+ return {
219
+ get focused() {
220
+ return picker.focused
221
+ },
222
+ set focused(value: boolean) {
223
+ picker.focused = value
224
+ },
225
+ render: (width) => picker.render(width),
226
+ invalidate: () => picker.invalidate(),
227
+ handleInput: (data) => {
228
+ picker.handleInput(data)
229
+ tui.requestRender()
230
+ },
231
+ }
232
+ })
233
+ .finally(() => ctx.ui.setFooter(undefined))
234
+ }
@@ -0,0 +1,180 @@
1
+ // Datalab Kit adaptation
2
+
3
+ import {
4
+ existsSync,
5
+ mkdirSync,
6
+ readFileSync,
7
+ rmSync,
8
+ writeFileSync,
9
+ } from "node:fs"
10
+ import path from "node:path"
11
+ import type { Api, Model } from "@earendil-works/pi-ai"
12
+ import {
13
+ getAgentDir,
14
+ type ExtensionContext,
15
+ } from "@earendil-works/pi-coding-agent"
16
+
17
+ const CONFIG_PATH = path.join(getAgentDir(), "extensions", "pi-recap.json")
18
+ const CONFIG_DIR = path.dirname(CONFIG_PATH)
19
+
20
+ export interface RecapModelPreference {
21
+ readonly provider: string
22
+ readonly id: string
23
+ }
24
+
25
+ export type RecapModelConfig =
26
+ | { readonly kind: "missing" }
27
+ | { readonly kind: "invalid" }
28
+ | { readonly kind: "configured"; readonly model: RecapModelPreference }
29
+
30
+ export type ResolvedRecapModelAuth =
31
+ | {
32
+ readonly status: "ok"
33
+ readonly auth: Model<Api>
34
+ readonly source: "configured" | "default"
35
+ }
36
+ | { readonly status: "invalid-config" }
37
+ | {
38
+ readonly status: "unauthenticated"
39
+ readonly model: RecapModelPreference | undefined
40
+ readonly source: "configured" | "default"
41
+ }
42
+
43
+ interface RecapConfig extends Record<string, unknown> {
44
+ model?: unknown
45
+ }
46
+
47
+ export function formatModelPreference(config: RecapModelConfig): string {
48
+ if (config.kind === "configured") return formatRecapModelKey(config.model)
49
+ if (config.kind === "invalid") return "invalid"
50
+ return "default"
51
+ }
52
+
53
+ export function formatRecapModelKey({
54
+ provider,
55
+ id,
56
+ }: RecapModelPreference): string {
57
+ return `${provider}/${id}`
58
+ }
59
+
60
+ export function formatAuthModelKey(auth: Model<Api>): string {
61
+ return `${auth.provider}/${auth.id}`
62
+ }
63
+
64
+ export function parseModelSpec(
65
+ value: string,
66
+ ): RecapModelPreference | undefined {
67
+ const trimmed = value.trim()
68
+ const separator = trimmed.indexOf("/")
69
+ if (separator <= 0 || separator === trimmed.length - 1) return undefined
70
+
71
+ return {
72
+ provider: trimmed.slice(0, separator),
73
+ id: trimmed.slice(separator + 1),
74
+ }
75
+ }
76
+
77
+ function readConfig(): RecapConfig {
78
+ const content = readFileSync(CONFIG_PATH, "utf-8")
79
+ const config = JSON.parse(content) as unknown
80
+ return config && typeof config === "object" && !Array.isArray(config)
81
+ ? (config as RecapConfig)
82
+ : {}
83
+ }
84
+
85
+ export function saveModelPreference(
86
+ modelPreference: RecapModelPreference,
87
+ ): void {
88
+ const config: RecapConfig = {
89
+ model: formatRecapModelKey(modelPreference),
90
+ }
91
+ mkdirSync(CONFIG_DIR, { recursive: true })
92
+ writeFileSync(CONFIG_PATH, `${JSON.stringify(config, null, 2)}\n`, "utf-8")
93
+ }
94
+
95
+ export function deleteRecapConfig(): void {
96
+ rmSync(CONFIG_PATH, { force: true })
97
+ }
98
+
99
+ export function resolveInitialModelConfig(): RecapModelConfig {
100
+ if (!existsSync(CONFIG_PATH)) return { kind: "missing" }
101
+
102
+ try {
103
+ const config = readConfig()
104
+ if (typeof config.model !== "string") return { kind: "invalid" }
105
+
106
+ const model = parseModelSpec(config.model)
107
+ return model ? { kind: "configured", model } : { kind: "invalid" }
108
+ } catch {
109
+ return { kind: "invalid" }
110
+ }
111
+ }
112
+
113
+ async function getModelAuth(
114
+ ctx: ExtensionContext,
115
+ modelPreference: RecapModelPreference,
116
+ ): Promise<Model<Api> | undefined> {
117
+ const model = ctx.modelRegistry.find(
118
+ modelPreference.provider,
119
+ modelPreference.id,
120
+ )
121
+ if (!model) return undefined
122
+
123
+ const auth = await ctx.modelRegistry.getProviderAuth(model.provider)
124
+ return auth?.auth.apiKey ? model : undefined
125
+ }
126
+
127
+ export async function getRecapModelAuth(
128
+ ctx: ExtensionContext,
129
+ config: RecapModelConfig,
130
+ ): Promise<ResolvedRecapModelAuth> {
131
+ if (config.kind === "invalid") return { status: "invalid-config" }
132
+
133
+ if (config.kind === "configured") {
134
+ const auth = await getModelAuth(ctx, config.model)
135
+ return auth
136
+ ? { status: "ok", auth, source: "configured" }
137
+ : {
138
+ status: "unauthenticated",
139
+ model: config.model,
140
+ source: "configured",
141
+ }
142
+ }
143
+
144
+ const defaultAuth = ctx.model
145
+ ? await getModelAuth(ctx, ctx.model)
146
+ : undefined
147
+ if (defaultAuth) {
148
+ return { status: "ok", auth: defaultAuth, source: "default" }
149
+ }
150
+
151
+ return {
152
+ status: "unauthenticated",
153
+ model: ctx.model,
154
+ source: "default",
155
+ }
156
+ }
157
+
158
+ export async function getAuthenticatedTextModelPreferences(
159
+ ctx: ExtensionContext,
160
+ ): Promise<RecapModelPreference[]> {
161
+ const models = ctx.modelRegistry
162
+ .getAll()
163
+ .filter((model) => model.input.includes("text"))
164
+ const authenticatedModels = await Promise.all(
165
+ models.map(async (model) => {
166
+ const auth = await ctx.modelRegistry.getProviderAuth(model.provider)
167
+ return auth?.auth.apiKey ? toModelPreference(model) : undefined
168
+ }),
169
+ )
170
+
171
+ return authenticatedModels
172
+ .filter((model): model is RecapModelPreference => model !== undefined)
173
+ .toSorted((left, right) =>
174
+ formatRecapModelKey(left).localeCompare(formatRecapModelKey(right)),
175
+ )
176
+ }
177
+
178
+ function toModelPreference(model: Model<Api>): RecapModelPreference {
179
+ return { provider: model.provider, id: model.id }
180
+ }
@@ -0,0 +1,119 @@
1
+ export const MAX_SAFE_RECAP_CHARS = 320
2
+
3
+ const ESC = 0x1b
4
+ const BEL = 0x07
5
+ const ST = 0x9c
6
+
7
+ function isControlCharacter(code: number): boolean {
8
+ return (code >= 0x00 && code <= 0x1f) || (code >= 0x7f && code <= 0x9f)
9
+ }
10
+
11
+ function isWhitespaceControl(code: number): boolean {
12
+ return (
13
+ code === 0x09 ||
14
+ code === 0x0a ||
15
+ code === 0x0b ||
16
+ code === 0x0c ||
17
+ code === 0x0d
18
+ )
19
+ }
20
+
21
+ function skipCsiSequence(text: string, startIndex: number): number {
22
+ for (let index = startIndex; index < text.length; index++) {
23
+ const code = text.charCodeAt(index)
24
+ if (code >= 0x40 && code <= 0x7e) return index + 1
25
+ }
26
+
27
+ return text.length
28
+ }
29
+
30
+ function skipStringControl(text: string, startIndex: number): number {
31
+ for (let index = startIndex; index < text.length; index++) {
32
+ const code = text.charCodeAt(index)
33
+ if (code === BEL || code === ST) return index + 1
34
+ if (code === ESC && text.charCodeAt(index + 1) === 0x5c) {
35
+ return index + 2
36
+ }
37
+ }
38
+
39
+ return text.length
40
+ }
41
+
42
+ function skipEscapeSequence(text: string, escapeIndex: number): number {
43
+ const nextCode = text.charCodeAt(escapeIndex + 1)
44
+ if (Number.isNaN(nextCode)) return escapeIndex + 1
45
+
46
+ switch (nextCode) {
47
+ case 0x5b:
48
+ return skipCsiSequence(text, escapeIndex + 2)
49
+ case 0x5d:
50
+ case 0x50:
51
+ case 0x58:
52
+ case 0x5e:
53
+ case 0x5f:
54
+ return skipStringControl(text, escapeIndex + 2)
55
+ default:
56
+ if (
57
+ nextCode === 0x20 ||
58
+ nextCode === 0x23 ||
59
+ nextCode === 0x25 ||
60
+ (nextCode >= 0x28 && nextCode <= 0x2f)
61
+ ) {
62
+ return Math.min(text.length, escapeIndex + 3)
63
+ }
64
+
65
+ return Math.min(text.length, escapeIndex + 2)
66
+ }
67
+ }
68
+
69
+ function truncatePrintableText(text: string, maxChars: number): string {
70
+ if (maxChars <= 0) return ""
71
+
72
+ const chars = Array.from(text)
73
+ if (chars.length <= maxChars) return text
74
+ if (maxChars === 1) return "…"
75
+ return `${chars.slice(0, maxChars - 1).join("")}…`
76
+ }
77
+
78
+ export function sanitizeRecapText(
79
+ text: string,
80
+ maxChars = MAX_SAFE_RECAP_CHARS,
81
+ ): string {
82
+ let stripped = ""
83
+
84
+ for (let index = 0; index < text.length;) {
85
+ const code = text.charCodeAt(index)
86
+
87
+ if (code === ESC) {
88
+ index = skipEscapeSequence(text, index)
89
+ continue
90
+ }
91
+
92
+ if (code === 0x9b) {
93
+ index = skipCsiSequence(text, index + 1)
94
+ continue
95
+ }
96
+
97
+ if (
98
+ code === 0x90 ||
99
+ code === 0x98 ||
100
+ code === 0x9d ||
101
+ code === 0x9e ||
102
+ code === 0x9f
103
+ ) {
104
+ index = skipStringControl(text, index + 1)
105
+ continue
106
+ }
107
+
108
+ if (isControlCharacter(code)) {
109
+ if (isWhitespaceControl(code)) stripped += " "
110
+ index++
111
+ continue
112
+ }
113
+
114
+ stripped += text[index]
115
+ index++
116
+ }
117
+
118
+ return truncatePrintableText(stripped.replace(/\s+/gu, " ").trim(), maxChars)
119
+ }
@@ -0,0 +1,155 @@
1
+ import type { ExtensionContext, Theme } from "@earendil-works/pi-coding-agent"
2
+ import type { Component, TUI } from "@earendil-works/pi-tui"
3
+ import {
4
+ truncateToWidth,
5
+ visibleWidth,
6
+ wrapTextWithAnsi,
7
+ } from "@earendil-works/pi-tui"
8
+ import { sanitizeRecapText } from "./sanitize.js"
9
+
10
+ const WIDGET_KEY = "pi-recap"
11
+ const MODEL_WARNING_WIDGET_KEY = "pi-recap-model-warning"
12
+ const NO_RECAP_MODEL_AUTH_MESSAGE = "no recap model authenticated"
13
+ const ICON = "※ "
14
+ const LABEL = `${ICON}recap: `
15
+ const LOADING_TEXT = "generating..."
16
+ const LOADING_FRAMES = ["⡿", "⣟", "⣯", "⣷", "⣾", "⣽", "⣻", "⢿"] as const
17
+ const LOADING_INTERVAL_MS = 70
18
+ const MIN_RECAP_WIDTH = 12
19
+
20
+ class WarningLine implements Component {
21
+ private readonly theme: Theme
22
+ private readonly message: string
23
+
24
+ constructor(theme: Theme, message: string) {
25
+ this.theme = theme
26
+ this.message = message
27
+ }
28
+
29
+ invalidate(): void {}
30
+
31
+ render(width: number): string[] {
32
+ return [this.theme.fg("warning", truncateToWidth(this.message, width))]
33
+ }
34
+ }
35
+
36
+ class LoadingRecapLine implements Component {
37
+ private readonly tui: TUI
38
+ private readonly theme: Theme
39
+ private readonly timer: ReturnType<typeof setInterval>
40
+ private frameIndex = 0
41
+
42
+ constructor(tui: TUI, theme: Theme) {
43
+ this.tui = tui
44
+ this.theme = theme
45
+ this.timer = setInterval(() => {
46
+ this.frameIndex++
47
+ this.tui.requestRender()
48
+ }, LOADING_INTERVAL_MS)
49
+ }
50
+
51
+ dispose(): void {
52
+ clearInterval(this.timer)
53
+ }
54
+
55
+ invalidate(): void {}
56
+
57
+ render(width: number): string[] {
58
+ const frame =
59
+ LOADING_FRAMES[this.frameIndex % LOADING_FRAMES.length] ??
60
+ LOADING_FRAMES[0]
61
+ return [
62
+ truncateToWidth(
63
+ this.theme.fg("dim", `${LABEL}${frame} ${LOADING_TEXT}`),
64
+ width,
65
+ ),
66
+ ]
67
+ }
68
+ }
69
+
70
+ class PiRecapLine implements Component {
71
+ private readonly theme: Theme
72
+ private readonly recap: string
73
+
74
+ constructor(theme: Theme, recap: string) {
75
+ this.theme = theme
76
+ this.recap = recap
77
+ }
78
+
79
+ invalidate(): void {}
80
+
81
+ render(width: number): string[] {
82
+ const labelWidth = visibleWidth(LABEL)
83
+ const label = this.renderLabel()
84
+
85
+ if (width < MIN_RECAP_WIDTH) {
86
+ return [
87
+ truncateToWidth(this.theme.fg("muted", `${LABEL}${this.recap}`), width),
88
+ ]
89
+ }
90
+
91
+ const contentWidth = width - labelWidth
92
+ const wrappedLines = wrapTextWithAnsi(this.recap, contentWidth)
93
+ const contentLines = wrappedLines.length === 0 ? [""] : wrappedLines
94
+
95
+ const continuationIndent = " ".repeat(visibleWidth(ICON))
96
+
97
+ return contentLines.map((line, index) => {
98
+ const prefix = index === 0 ? label : continuationIndent
99
+ return truncateToWidth(this.theme.fg("muted", `${prefix}${line}`), width)
100
+ })
101
+ }
102
+
103
+ private renderLabel(): string {
104
+ return `※ ${this.theme.bold("recap:")} `
105
+ }
106
+ }
107
+
108
+ export function clearWidget(ctx: ExtensionContext): void {
109
+ if (!ctx.hasUI) return
110
+ ctx.ui.setWidget(WIDGET_KEY, undefined)
111
+ }
112
+
113
+ export function clearNoModelWarning(ctx: ExtensionContext): void {
114
+ if (!ctx.hasUI) return
115
+ ctx.ui.setWidget(MODEL_WARNING_WIDGET_KEY, undefined)
116
+ }
117
+
118
+ export function showNoModelWarning(ctx: ExtensionContext): void {
119
+ if (!ctx.hasUI) return
120
+ ctx.ui.setWidget(
121
+ MODEL_WARNING_WIDGET_KEY,
122
+ (_tui, theme) => new WarningLine(theme, NO_RECAP_MODEL_AUTH_MESSAGE),
123
+ { placement: "aboveEditor" },
124
+ )
125
+ }
126
+
127
+ export function showLoadingWidget(ctx: ExtensionContext): void {
128
+ if (!ctx.hasUI) return
129
+
130
+ ctx.ui.setWidget(WIDGET_KEY, (tui, theme) => new LoadingRecapLine(tui, theme))
131
+ }
132
+
133
+ export function showWidget(ctx: ExtensionContext, recap: string): void {
134
+ if (!ctx.hasUI) return
135
+
136
+ const safeRecap = sanitizeRecapText(recap)
137
+ if (!safeRecap) {
138
+ clearWidget(ctx)
139
+ return
140
+ }
141
+
142
+ ctx.ui.setWidget(
143
+ WIDGET_KEY,
144
+ (_tui, theme) => new PiRecapLine(theme, safeRecap),
145
+ )
146
+ }
147
+
148
+ export function notifyUser(
149
+ ctx: ExtensionContext,
150
+ message: string,
151
+ level: "info" | "error",
152
+ ): void {
153
+ if (!ctx.hasUI) return
154
+ ctx.ui.notify(message, level)
155
+ }
@@ -0,0 +1,24 @@
1
+ # Pi Extension Internals
2
+
3
+ Shared composition protocols and guarded Pi-internal loading for extensions that patch the same Pi UI internals.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install @zigai/pi-extension-internals
9
+ ```
10
+
11
+ Declare the exact supported version in `dependencies`. Keep Pi host packages in `peerDependencies`.
12
+
13
+ ## API
14
+
15
+ - `registerEditorEnhancer` composes keyed editor transformations.
16
+ - `installLinkedMethodPatch` and `installLinkedRenderPatch` install removable method patches.
17
+ - `installKeyedLinkedMethodPatch` updates an existing keyed patch instead of stacking another wrapper.
18
+ - `loadPiInternalModule` imports and validates a Pi-internal module, returning `undefined` with a scoped warning when unavailable.
19
+
20
+ Use `Symbol.for(...)` for enhancer keys and patch markers so independently installed extensions share the same registration.
21
+
22
+ ## License
23
+
24
+ MIT