@ibgib/web-gib 0.0.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 (372) hide show
  1. package/.ibgibignore +30 -0
  2. package/.vscode/ibgib-snippets.code-snippets +309 -0
  3. package/.vscode/launch.json +25 -0
  4. package/.vscode/settings.json +68 -0
  5. package/.vscode/tasks.json +38 -0
  6. package/CHANGELOG.md +427 -0
  7. package/README.md +66 -0
  8. package/dist/agent-texts/common-agent-texts.d.mts +14 -0
  9. package/dist/agent-texts/common-agent-texts.d.mts.map +1 -0
  10. package/dist/agent-texts/common-agent-texts.mjs +51 -0
  11. package/dist/agent-texts/common-agent-texts.mjs.map +1 -0
  12. package/dist/agent-texts/primary-agent-texts.d.mts +16 -0
  13. package/dist/agent-texts/primary-agent-texts.d.mts.map +1 -0
  14. package/dist/agent-texts/primary-agent-texts.mjs +27 -0
  15. package/dist/agent-texts/primary-agent-texts.mjs.map +1 -0
  16. package/dist/agent-texts/project-agent-texts.d.mts +8 -0
  17. package/dist/agent-texts/project-agent-texts.d.mts.map +1 -0
  18. package/dist/agent-texts/project-agent-texts.mjs +29 -0
  19. package/dist/agent-texts/project-agent-texts.mjs.map +1 -0
  20. package/dist/agent-texts/project-child-text-agent-texts.d.mts +5 -0
  21. package/dist/agent-texts/project-child-text-agent-texts.d.mts.map +1 -0
  22. package/dist/agent-texts/project-child-text-agent-texts.mjs +26 -0
  23. package/dist/agent-texts/project-child-text-agent-texts.mjs.map +1 -0
  24. package/dist/agent-texts/projects-agent-texts.d.mts +4 -0
  25. package/dist/agent-texts/projects-agent-texts.d.mts.map +1 -0
  26. package/dist/agent-texts/projects-agent-texts.mjs +15 -0
  27. package/dist/agent-texts/projects-agent-texts.mjs.map +1 -0
  28. package/dist/agent-texts/raw-agent-texts.d.mts +4 -0
  29. package/dist/agent-texts/raw-agent-texts.d.mts.map +1 -0
  30. package/dist/agent-texts/raw-agent-texts.mjs +17 -0
  31. package/dist/agent-texts/raw-agent-texts.mjs.map +1 -0
  32. package/dist/agent-texts/text-editor-agent-texts.d.mts +6 -0
  33. package/dist/agent-texts/text-editor-agent-texts.d.mts.map +1 -0
  34. package/dist/agent-texts/text-editor-agent-texts.mjs +19 -0
  35. package/dist/agent-texts/text-editor-agent-texts.mjs.map +1 -0
  36. package/dist/api/api-constants.d.mts +9 -0
  37. package/dist/api/api-constants.d.mts.map +1 -0
  38. package/dist/api/api-constants.mjs +9 -0
  39. package/dist/api/api-constants.mjs.map +1 -0
  40. package/dist/api/api-index.d.mts +10 -0
  41. package/dist/api/api-index.d.mts.map +1 -0
  42. package/dist/api/api-index.mjs +121 -0
  43. package/dist/api/api-index.mjs.map +1 -0
  44. package/dist/api/api-types.d.mts +36 -0
  45. package/dist/api/api-types.d.mts.map +1 -0
  46. package/dist/api/api-types.mjs +2 -0
  47. package/dist/api/api-types.mjs.map +1 -0
  48. package/dist/api/commands/chat/chat-index.d.mts +3 -0
  49. package/dist/api/commands/chat/chat-index.d.mts.map +1 -0
  50. package/dist/api/commands/chat/chat-index.mjs +9 -0
  51. package/dist/api/commands/chat/chat-index.mjs.map +1 -0
  52. package/dist/api/commands/chat/get-context-info.d.mts +71 -0
  53. package/dist/api/commands/chat/get-context-info.d.mts.map +1 -0
  54. package/dist/api/commands/chat/get-context-info.mjs +130 -0
  55. package/dist/api/commands/chat/get-context-info.mjs.map +1 -0
  56. package/dist/api/commands/chat/hello-world.d.mts +63 -0
  57. package/dist/api/commands/chat/hello-world.d.mts.map +1 -0
  58. package/dist/api/commands/chat/hello-world.mjs +132 -0
  59. package/dist/api/commands/chat/hello-world.mjs.map +1 -0
  60. package/dist/api/commands/chat/tell-user.d.mts +57 -0
  61. package/dist/api/commands/chat/tell-user.d.mts.map +1 -0
  62. package/dist/api/commands/chat/tell-user.mjs +199 -0
  63. package/dist/api/commands/chat/tell-user.mjs.map +1 -0
  64. package/dist/api/commands/command-constants.d.mts +22 -0
  65. package/dist/api/commands/command-constants.d.mts.map +1 -0
  66. package/dist/api/commands/command-constants.mjs +17 -0
  67. package/dist/api/commands/command-constants.mjs.map +1 -0
  68. package/dist/api/commands/command-helpers.d.mts +47 -0
  69. package/dist/api/commands/command-helpers.d.mts.map +1 -0
  70. package/dist/api/commands/command-helpers.mjs +76 -0
  71. package/dist/api/commands/command-helpers.mjs.map +1 -0
  72. package/dist/api/commands/command-service-v1.d.mts +28 -0
  73. package/dist/api/commands/command-service-v1.d.mts.map +1 -0
  74. package/dist/api/commands/command-service-v1.mjs +122 -0
  75. package/dist/api/commands/command-service-v1.mjs.map +1 -0
  76. package/dist/api/commands/command-service.respec.d.mts +7 -0
  77. package/dist/api/commands/command-service.respec.d.mts.map +1 -0
  78. package/dist/api/commands/command-service.respec.mjs +66 -0
  79. package/dist/api/commands/command-service.respec.mjs.map +1 -0
  80. package/dist/api/commands/command-types.d.mts +48 -0
  81. package/dist/api/commands/command-types.d.mts.map +1 -0
  82. package/dist/api/commands/command-types.mjs +12 -0
  83. package/dist/api/commands/command-types.mjs.map +1 -0
  84. package/dist/api/commands/ibgib/get-ibgibs.d.mts +94 -0
  85. package/dist/api/commands/ibgib/get-ibgibs.d.mts.map +1 -0
  86. package/dist/api/commands/ibgib/get-ibgibs.mjs +219 -0
  87. package/dist/api/commands/ibgib/get-ibgibs.mjs.map +1 -0
  88. package/dist/api/commands/ibgib/ibgib-index.d.mts +3 -0
  89. package/dist/api/commands/ibgib/ibgib-index.d.mts.map +1 -0
  90. package/dist/api/commands/ibgib/ibgib-index.mjs +7 -0
  91. package/dist/api/commands/ibgib/ibgib-index.mjs.map +1 -0
  92. package/dist/api/commands/ibgib/mut8-ibgib.d.mts +135 -0
  93. package/dist/api/commands/ibgib/mut8-ibgib.d.mts.map +1 -0
  94. package/dist/api/commands/ibgib/mut8-ibgib.mjs +318 -0
  95. package/dist/api/commands/ibgib/mut8-ibgib.mjs.map +1 -0
  96. package/dist/api/commands/templates/api-function-info.template.d.mts +73 -0
  97. package/dist/api/commands/templates/api-function-info.template.d.mts.map +1 -0
  98. package/dist/api/commands/templates/api-function-info.template.mjs +161 -0
  99. package/dist/api/commands/templates/api-function-info.template.mjs.map +1 -0
  100. package/dist/api/commands/text/text-edit.d.mts +54 -0
  101. package/dist/api/commands/text/text-edit.d.mts.map +1 -0
  102. package/dist/api/commands/text/text-edit.mjs +170 -0
  103. package/dist/api/commands/text/text-edit.mjs.map +1 -0
  104. package/dist/api/commands/text/text-index.d.mts +3 -0
  105. package/dist/api/commands/text/text-index.d.mts.map +1 -0
  106. package/dist/api/commands/text/text-index.mjs +5 -0
  107. package/dist/api/commands/text/text-index.mjs.map +1 -0
  108. package/dist/api/commands/ui/ui-index.d.mts +3 -0
  109. package/dist/api/commands/ui/ui-index.d.mts.map +1 -0
  110. package/dist/api/commands/ui/ui-index.mjs +5 -0
  111. package/dist/api/commands/ui/ui-index.mjs.map +1 -0
  112. package/dist/api/commands/ui/update-css-variables.d.mts +48 -0
  113. package/dist/api/commands/ui/update-css-variables.d.mts.map +1 -0
  114. package/dist/api/commands/ui/update-css-variables.mjs +145 -0
  115. package/dist/api/commands/ui/update-css-variables.mjs.map +1 -0
  116. package/dist/api/function-infos.web.d.mts +15 -0
  117. package/dist/api/function-infos.web.d.mts.map +1 -0
  118. package/dist/api/function-infos.web.mjs +63 -0
  119. package/dist/api/function-infos.web.mjs.map +1 -0
  120. package/dist/assumptions.respec.d.mts +2 -0
  121. package/dist/assumptions.respec.d.mts.map +1 -0
  122. package/dist/assumptions.respec.mjs +41 -0
  123. package/dist/assumptions.respec.mjs.map +1 -0
  124. package/dist/common/project/project-constants.d.mts +38 -0
  125. package/dist/common/project/project-constants.d.mts.map +1 -0
  126. package/dist/common/project/project-constants.mjs +71 -0
  127. package/dist/common/project/project-constants.mjs.map +1 -0
  128. package/dist/common/project/project-helper.d.mts +127 -0
  129. package/dist/common/project/project-helper.d.mts.map +1 -0
  130. package/dist/common/project/project-helper.mjs +683 -0
  131. package/dist/common/project/project-helper.mjs.map +1 -0
  132. package/dist/common/project/project-types.d.mts +91 -0
  133. package/dist/common/project/project-types.d.mts.map +1 -0
  134. package/dist/common/project/project-types.mjs +31 -0
  135. package/dist/common/project/project-types.mjs.map +1 -0
  136. package/dist/common/prompt-functions.web.d.mts +90 -0
  137. package/dist/common/prompt-functions.web.d.mts.map +1 -0
  138. package/dist/common/prompt-functions.web.mjs +426 -0
  139. package/dist/common/prompt-functions.web.mjs.map +1 -0
  140. package/dist/common/settings/settings-constants.d.mts +33 -0
  141. package/dist/common/settings/settings-constants.d.mts.map +1 -0
  142. package/dist/common/settings/settings-constants.mjs +54 -0
  143. package/dist/common/settings/settings-constants.mjs.map +1 -0
  144. package/dist/common/settings/settings-helpers.d.mts +59 -0
  145. package/dist/common/settings/settings-helpers.d.mts.map +1 -0
  146. package/dist/common/settings/settings-helpers.mjs +253 -0
  147. package/dist/common/settings/settings-helpers.mjs.map +1 -0
  148. package/dist/common/settings/settings-types.d.mts +118 -0
  149. package/dist/common/settings/settings-types.d.mts.map +1 -0
  150. package/dist/common/settings/settings-types.mjs +13 -0
  151. package/dist/common/settings/settings-types.mjs.map +1 -0
  152. package/dist/constants.d.mts +34 -0
  153. package/dist/constants.d.mts.map +1 -0
  154. package/dist/constants.mjs +35 -0
  155. package/dist/constants.mjs.map +1 -0
  156. package/dist/foo.d.mts +2 -0
  157. package/dist/foo.d.mts.map +1 -0
  158. package/dist/foo.mjs +19 -0
  159. package/dist/foo.mjs.map +1 -0
  160. package/dist/helpers.d.mts +137 -0
  161. package/dist/helpers.d.mts.map +1 -0
  162. package/dist/helpers.mjs +514 -0
  163. package/dist/helpers.mjs.map +1 -0
  164. package/dist/helpers.web.d.mts +324 -0
  165. package/dist/helpers.web.d.mts.map +1 -0
  166. package/dist/helpers.web.mjs +1133 -0
  167. package/dist/helpers.web.mjs.map +1 -0
  168. package/dist/helpers.web.respec.d.mts +2 -0
  169. package/dist/helpers.web.respec.d.mts.map +1 -0
  170. package/dist/helpers.web.respec.mjs +12 -0
  171. package/dist/helpers.web.respec.mjs.map +1 -0
  172. package/dist/index.d.mts +2 -0
  173. package/dist/index.d.mts.map +1 -0
  174. package/dist/index.mjs +3 -0
  175. package/dist/index.mjs.map +1 -0
  176. package/dist/respec-gib.node.d.mts +2 -0
  177. package/dist/respec-gib.node.d.mts.map +1 -0
  178. package/dist/respec-gib.node.mjs +211 -0
  179. package/dist/respec-gib.node.mjs.map +1 -0
  180. package/dist/spec-helper.node.respec.d.mts +13 -0
  181. package/dist/spec-helper.node.respec.d.mts.map +1 -0
  182. package/dist/spec-helper.node.respec.mjs +50 -0
  183. package/dist/spec-helper.node.respec.mjs.map +1 -0
  184. package/dist/storage/storage-helpers.web.d.mts +108 -0
  185. package/dist/storage/storage-helpers.web.d.mts.map +1 -0
  186. package/dist/storage/storage-helpers.web.mjs +757 -0
  187. package/dist/storage/storage-helpers.web.mjs.map +1 -0
  188. package/dist/storage/storage-types.web.d.mts +30 -0
  189. package/dist/storage/storage-types.web.d.mts.map +1 -0
  190. package/dist/storage/storage-types.web.mjs +2 -0
  191. package/dist/storage/storage-types.web.mjs.map +1 -0
  192. package/dist/types.web.d.mts +42 -0
  193. package/dist/types.web.d.mts.map +1 -0
  194. package/dist/types.web.mjs +2 -0
  195. package/dist/types.web.mjs.map +1 -0
  196. package/dist/ui/component/component-types.d.mts +225 -0
  197. package/dist/ui/component/component-types.d.mts.map +1 -0
  198. package/dist/ui/component/component-types.mjs +2 -0
  199. package/dist/ui/component/component-types.mjs.map +1 -0
  200. package/dist/ui/component/ibgib-component-service.d.mts +70 -0
  201. package/dist/ui/component/ibgib-component-service.d.mts.map +1 -0
  202. package/dist/ui/component/ibgib-component-service.mjs +201 -0
  203. package/dist/ui/component/ibgib-component-service.mjs.map +1 -0
  204. package/dist/ui/component/ibgib-dynamic-component-bases.d.mts +338 -0
  205. package/dist/ui/component/ibgib-dynamic-component-bases.d.mts.map +1 -0
  206. package/dist/ui/component/ibgib-dynamic-component-bases.mjs +1304 -0
  207. package/dist/ui/component/ibgib-dynamic-component-bases.mjs.map +1 -0
  208. package/dist/ui/ui-constants.d.mts +12 -0
  209. package/dist/ui/ui-constants.d.mts.map +1 -0
  210. package/dist/ui/ui-constants.mjs +93 -0
  211. package/dist/ui/ui-constants.mjs.map +1 -0
  212. package/dist/ui/ui-helpers.d.mts +42 -0
  213. package/dist/ui/ui-helpers.d.mts.map +1 -0
  214. package/dist/ui/ui-helpers.mjs +198 -0
  215. package/dist/ui/ui-helpers.mjs.map +1 -0
  216. package/dist/ui/ui-types.d.mts +13 -0
  217. package/dist/ui/ui-types.d.mts.map +1 -0
  218. package/dist/ui/ui-types.mjs +2 -0
  219. package/dist/ui/ui-types.mjs.map +1 -0
  220. package/dist/witness/agent/agent-constants.d.mts +97 -0
  221. package/dist/witness/agent/agent-constants.d.mts.map +1 -0
  222. package/dist/witness/agent/agent-constants.mjs +98 -0
  223. package/dist/witness/agent/agent-constants.mjs.map +1 -0
  224. package/dist/witness/agent/agent-helpers.d.mts +106 -0
  225. package/dist/witness/agent/agent-helpers.d.mts.map +1 -0
  226. package/dist/witness/agent/agent-helpers.mjs +601 -0
  227. package/dist/witness/agent/agent-helpers.mjs.map +1 -0
  228. package/dist/witness/agent/agent-one-file.app.d.mts +2 -0
  229. package/dist/witness/agent/agent-one-file.app.d.mts.map +1 -0
  230. package/dist/witness/agent/agent-one-file.app.mjs +8 -0
  231. package/dist/witness/agent/agent-one-file.app.mjs.map +1 -0
  232. package/dist/witness/agent/agent-one-file.d.mts +478 -0
  233. package/dist/witness/agent/agent-one-file.d.mts.map +1 -0
  234. package/dist/witness/agent/agent-one-file.mjs +1462 -0
  235. package/dist/witness/agent/agent-one-file.mjs.map +1 -0
  236. package/dist/witness/agent/agent-types.d.mts +83 -0
  237. package/dist/witness/agent/agent-types.d.mts.map +1 -0
  238. package/dist/witness/agent/agent-types.mjs +2 -0
  239. package/dist/witness/agent/agent-types.mjs.map +1 -0
  240. package/dist/witness/agent/agents-service-v1.d.mts +99 -0
  241. package/dist/witness/agent/agents-service-v1.d.mts.map +1 -0
  242. package/dist/witness/agent/agents-service-v1.mjs +453 -0
  243. package/dist/witness/agent/agents-service-v1.mjs.map +1 -0
  244. package/dist/witness/agent/function-info/function-info-one-file.d.mts +192 -0
  245. package/dist/witness/agent/function-info/function-info-one-file.d.mts.map +1 -0
  246. package/dist/witness/agent/function-info/function-info-one-file.mjs +192 -0
  247. package/dist/witness/agent/function-info/function-info-one-file.mjs.map +1 -0
  248. package/dist/witness/agent/gemini/agent-witness-gemini-v1.d.mts +51 -0
  249. package/dist/witness/agent/gemini/agent-witness-gemini-v1.d.mts.map +1 -0
  250. package/dist/witness/agent/gemini/agent-witness-gemini-v1.mjs +928 -0
  251. package/dist/witness/agent/gemini/agent-witness-gemini-v1.mjs.map +1 -0
  252. package/dist/witness/agent/gemini/gemini-agent-factory.d.mts +27 -0
  253. package/dist/witness/agent/gemini/gemini-agent-factory.d.mts.map +1 -0
  254. package/dist/witness/agent/gemini/gemini-agent-factory.mjs +144 -0
  255. package/dist/witness/agent/gemini/gemini-agent-factory.mjs.map +1 -0
  256. package/dist/witness/agent/gemini/gemini-constants.d.mts +36 -0
  257. package/dist/witness/agent/gemini/gemini-constants.d.mts.map +1 -0
  258. package/dist/witness/agent/gemini/gemini-constants.mjs +47 -0
  259. package/dist/witness/agent/gemini/gemini-constants.mjs.map +1 -0
  260. package/dist/witness/agent/gemini/gemini-helpers.d.mts +58 -0
  261. package/dist/witness/agent/gemini/gemini-helpers.d.mts.map +1 -0
  262. package/dist/witness/agent/gemini/gemini-helpers.mjs +210 -0
  263. package/dist/witness/agent/gemini/gemini-helpers.mjs.map +1 -0
  264. package/dist/witness/agent/gemini/gemini-types.d.mts +82 -0
  265. package/dist/witness/agent/gemini/gemini-types.d.mts.map +1 -0
  266. package/dist/witness/agent/gemini/gemini-types.mjs +3 -0
  267. package/dist/witness/agent/gemini/gemini-types.mjs.map +1 -0
  268. package/dist/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.d.mts +136 -0
  269. package/dist/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.d.mts.map +1 -0
  270. package/dist/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.mjs +334 -0
  271. package/dist/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.mjs.map +1 -0
  272. package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace-helper.d.mts +35 -0
  273. package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace-helper.d.mts.map +1 -0
  274. package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace-helper.mjs +267 -0
  275. package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace-helper.mjs.map +1 -0
  276. package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.d.mts +134 -0
  277. package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.d.mts.map +1 -0
  278. package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.mjs +389 -0
  279. package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.mjs.map +1 -0
  280. package/dist/witness/space/web-filesystem-space/web-filesystem-space-constants.d.mts +2 -0
  281. package/dist/witness/space/web-filesystem-space/web-filesystem-space-constants.d.mts.map +1 -0
  282. package/dist/witness/space/web-filesystem-space/web-filesystem-space-constants.mjs +2 -0
  283. package/dist/witness/space/web-filesystem-space/web-filesystem-space-constants.mjs.map +1 -0
  284. package/dist/witness/space/web-filesystem-space/web-filesystem-space-helper.d.mts +104 -0
  285. package/dist/witness/space/web-filesystem-space/web-filesystem-space-helper.d.mts.map +1 -0
  286. package/dist/witness/space/web-filesystem-space/web-filesystem-space-helper.mjs +457 -0
  287. package/dist/witness/space/web-filesystem-space/web-filesystem-space-helper.mjs.map +1 -0
  288. package/dist/witness/space/web-filesystem-space/web-filesystem-space-types.d.mts +93 -0
  289. package/dist/witness/space/web-filesystem-space/web-filesystem-space-types.d.mts.map +1 -0
  290. package/dist/witness/space/web-filesystem-space/web-filesystem-space-types.mjs +98 -0
  291. package/dist/witness/space/web-filesystem-space/web-filesystem-space-types.mjs.map +1 -0
  292. package/dist/witness/space/web-filesystem-space/web-filesystem-space-v1.d.mts +73 -0
  293. package/dist/witness/space/web-filesystem-space/web-filesystem-space-v1.d.mts.map +1 -0
  294. package/dist/witness/space/web-filesystem-space/web-filesystem-space-v1.mjs +650 -0
  295. package/dist/witness/space/web-filesystem-space/web-filesystem-space-v1.mjs.map +1 -0
  296. package/generate-version-file.js +29 -0
  297. package/package.json +60 -0
  298. package/src/agent-texts/common-agent-texts.mts +61 -0
  299. package/src/agent-texts/primary-agent-texts.mts +32 -0
  300. package/src/agent-texts/project-agent-texts.mts +29 -0
  301. package/src/agent-texts/project-child-text-agent-texts.mts +30 -0
  302. package/src/agent-texts/projects-agent-texts.mts +17 -0
  303. package/src/agent-texts/raw-agent-texts.mts +18 -0
  304. package/src/agent-texts/text-editor-agent-texts.mts +20 -0
  305. package/src/api/api-constants.mts +8 -0
  306. package/src/api/api-index.mts +110 -0
  307. package/src/api/api-types.mts +36 -0
  308. package/src/api/commands/chat/chat-index.mts +10 -0
  309. package/src/api/commands/chat/get-context-info.mts +196 -0
  310. package/src/api/commands/chat/hello-world.mts +183 -0
  311. package/src/api/commands/chat/tell-user.mts +241 -0
  312. package/src/api/commands/command-constants.mts +17 -0
  313. package/src/api/commands/command-helpers.mts +105 -0
  314. package/src/api/commands/command-service-v1.mts +136 -0
  315. package/src/api/commands/command-service.respec.mts +72 -0
  316. package/src/api/commands/command-types.mts +71 -0
  317. package/src/api/commands/ibgib/get-ibgibs.mts +269 -0
  318. package/src/api/commands/ibgib/ibgib-index.mts +8 -0
  319. package/src/api/commands/ibgib/mut8-ibgib.mts +418 -0
  320. package/src/api/commands/templates/api-function-info.template.mts +212 -0
  321. package/src/api/commands/text/text-edit.mts +217 -0
  322. package/src/api/commands/text/text-index.mts +6 -0
  323. package/src/api/commands/ui/ui-index.mts +6 -0
  324. package/src/api/commands/ui/update-css-variables.mts +187 -0
  325. package/src/api/function-infos.web.mts +66 -0
  326. package/src/assets/fullscreen-dialog.html +18 -0
  327. package/src/assumptions.respec.mts +51 -0
  328. package/src/common/project/project-constants.mts +83 -0
  329. package/src/common/project/project-helper.mts +730 -0
  330. package/src/common/project/project-types.mts +121 -0
  331. package/src/common/prompt-functions.web.mts +447 -0
  332. package/src/common/settings/settings-constants.mts +72 -0
  333. package/src/common/settings/settings-helpers.mts +280 -0
  334. package/src/common/settings/settings-types.mts +137 -0
  335. package/src/constants.mts +39 -0
  336. package/src/foo.mts +13 -0
  337. package/src/helpers.mts +574 -0
  338. package/src/helpers.web.mts +1277 -0
  339. package/src/helpers.web.respec.mts +16 -0
  340. package/src/index.mts +3 -0
  341. package/src/respec-gib.node.mts +199 -0
  342. package/src/spec-helper.node.respec.mts +50 -0
  343. package/src/storage/storage-helpers.web.mts +728 -0
  344. package/src/storage/storage-types.web.mts +29 -0
  345. package/src/types.web.mts +42 -0
  346. package/src/ui/component/component-types.mts +241 -0
  347. package/src/ui/component/ibgib-component-service.mts +201 -0
  348. package/src/ui/component/ibgib-dynamic-component-bases.mts +1369 -0
  349. package/src/ui/ui-constants.mts +101 -0
  350. package/src/ui/ui-helpers.mts +222 -0
  351. package/src/ui/ui-types.mts +11 -0
  352. package/src/witness/agent/agent-constants.mts +122 -0
  353. package/src/witness/agent/agent-helpers.mts +681 -0
  354. package/src/witness/agent/agent-one-file.app.mts +8 -0
  355. package/src/witness/agent/agent-one-file.mts +1665 -0
  356. package/src/witness/agent/agent-types.mts +92 -0
  357. package/src/witness/agent/agents-service-v1.mts +482 -0
  358. package/src/witness/agent/function-info/function-info-one-file.mts +362 -0
  359. package/src/witness/agent/gemini/agent-witness-gemini-v1.mts +910 -0
  360. package/src/witness/agent/gemini/gemini-agent-factory.mts +135 -0
  361. package/src/witness/agent/gemini/gemini-constants.mts +79 -0
  362. package/src/witness/agent/gemini/gemini-helpers.mts +216 -0
  363. package/src/witness/agent/gemini/gemini-types.mts +88 -0
  364. package/src/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.mts +321 -0
  365. package/src/witness/space/metaspace/metaspace-webspace/metaspace-webspace-helper.mts +290 -0
  366. package/src/witness/space/metaspace/metaspace-webspace/metaspace-webspace.mts +407 -0
  367. package/src/witness/space/web-filesystem-space/web-filesystem-space-constants.mts +1 -0
  368. package/src/witness/space/web-filesystem-space/web-filesystem-space-helper.mts +491 -0
  369. package/src/witness/space/web-filesystem-space/web-filesystem-space-types.mts +172 -0
  370. package/src/witness/space/web-filesystem-space/web-filesystem-space-v1.mts +670 -0
  371. package/tsconfig.json +17 -0
  372. package/tsconfig.test.json +10 -0
@@ -0,0 +1,1277 @@
1
+ /**
2
+ * @module helpers.web
3
+ *
4
+ * helper functions specific to the web version.
5
+ */
6
+
7
+ import { delay, extractErrorMsg, pretty, } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
8
+ import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
9
+ import { Gib, IbGibAddr } from "@ibgib/ts-gib/dist/types.mjs";
10
+ import { getIbAndGib, getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
11
+ import { GIB } from "@ibgib/ts-gib/dist/V1/constants.mjs";
12
+ import { getGibInfo, isPrimitive } from "@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs";
13
+ import { validateIbGibIntrinsically } from "@ibgib/ts-gib/dist/V1/validate-helper.mjs";
14
+ import { MetaspaceService } from "@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs";
15
+ import { RawExportIbGib_V1 } from "@ibgib/core-gib/dist/common/import-export/import-export-types.mjs";
16
+ import { FlatIbGibGraph } from "@ibgib/core-gib/dist/common/other/graph-types.mjs";
17
+ import { decompressIbGibGraphFromString, deserializeStringToGraph } from "@ibgib/core-gib/dist/common/other/other-helper.web.mjs";
18
+ import { getRawExportIbGib } from "@ibgib/core-gib/dist/common/import-export/import-export-helper.web.mjs";
19
+ import { IbGibSpaceAny } from "@ibgib/core-gib/dist/witness/space/space-base-v1.mjs";
20
+ import { ZERO_SPACE_ID } from "@ibgib/core-gib/dist/witness/space/space-constants.mjs";
21
+
22
+ import {
23
+ GLOBAL_LOG_A_LOT,
24
+ DEFAULT_IBGIB_COLOR, DEFAULT_IBGIB_COLOR_CONTRAST,
25
+ DEFAULT_IBGIB_TRANSLUCENT,
26
+ GEMINI_API_KEY_REGEXP,
27
+ CONFIG_OPTION_GEMINI_API_KEY_LOCATION_HELP
28
+ } from "./constants.mjs";
29
+ import { showFullscreenDialog } from "./ui/ui-helpers.mjs";
30
+ import { initializeStorage, storageCreateStoreIfNotExist, storageDBExists, storageGet, storagePut } from "./storage/storage-helpers.web.mjs";
31
+ import { GibColorInfo } from "./types.web.mjs";
32
+
33
+
34
+ /**
35
+ * used in verbose logging
36
+ */
37
+ const logalot = GLOBAL_LOG_A_LOT;
38
+
39
+
40
+ /**
41
+ * converts string to Uint8Array.
42
+ * @param str to convert
43
+ * @returns array
44
+ */
45
+ export function stringToUint8Array(str: string): Uint8Array {
46
+ const encoder = new TextEncoder();
47
+ return encoder.encode(str);
48
+ }
49
+
50
+ /**
51
+ * converts Uint8Array to string.
52
+ * @param array to convert
53
+ * @returns string
54
+ */
55
+ export function uint8ArrayToString(array: Uint8Array) {
56
+ const decoder = new TextDecoder();
57
+ return decoder.decode(array);
58
+ }
59
+
60
+ /**
61
+ * I'm pulling out node from @ibgib/ibgib rcli code. This interface is just to
62
+ * aid in that transition.
63
+ */
64
+ export interface PathUtilsHelper {
65
+ isAbsolute(path: string): boolean;
66
+ isRelative(path: string): boolean;
67
+
68
+ // for now I'm taking out resolve since it requires being stateful and isn't
69
+ // used AFAICT in the code I'm porting over
70
+ // resolve(path: string): string;
71
+
72
+ join(...paths: string[]): string;
73
+ dirname(path: string): string;
74
+ basename(path: string, ext?: string): string;
75
+ }
76
+
77
+ /**
78
+ * Helper class that exposes pathUtils functions. Note that this is relative to
79
+ * an individual space.
80
+ */
81
+ export class PathUtilsHelper implements PathUtilsHelper {
82
+ /** class-level log context */
83
+ lc: string = `[${PathUtilsHelper.name}]`;
84
+
85
+ // /**
86
+ // * this path utils helper is per space, so this is the id of that space.
87
+ // */
88
+ // spaceId: SpaceId;
89
+ /**
90
+ *
91
+ */
92
+ // constructor({ spaceId, initialCwd, }: { spaceId: SpaceId, initialCwd: string }) {
93
+ // const lc = `${this.lc}[ctor]`;
94
+ // this.spaceId = spaceId;
95
+ // let ibGibGlobalThis = getIbGibGlobalThis();
96
+ // if (!ibGibGlobalThis.spaceShim[spaceId]) {
97
+ // console.log(`${lc} initializing IbGibGlobalThis data`);
98
+ // // initialize
99
+ // ibGibGlobalThis.spaceShim[spaceId] = {
100
+ // cwd: initialCwd,
101
+ // initialCwd,
102
+ // };
103
+ // } else {
104
+ // if (logalot) { console.log(`${lc} ibgib global this already initialized (I: e48b0cb4075e536d150919e87ddc1f24)`); }
105
+ // }
106
+ // }
107
+ /**
108
+ *
109
+ */
110
+ constructor() { }
111
+
112
+ isAbsolute(path: string): boolean {
113
+ if (!path) { throw new Error(`(UNEXPECTED) path falsy? (E: dcb92e11770ba06205c0afe3e6560b24)`); }
114
+ return path.startsWith('/');
115
+ }
116
+
117
+ isRelative(path: string): boolean {
118
+ return !this.isAbsolute(path);
119
+ }
120
+
121
+ // resolve(path: string): string {
122
+ // const lc = `${this.lc}[${this.resolve.name}]`;
123
+ // if (!path) { throw new Error(`(UNEXPECTED) path falsy? (E: 76161b12dbd446a0c2a9e18f4847fc24)`); }
124
+
125
+ // // for our implementation, we will throw if there is a relative path
126
+ // // specifier (. or ..) in the middle of the path. the proper
127
+ // // implementation probably resolves these concretely.
128
+
129
+ // if (this.isAbsolute(path)) {
130
+ // if (path.includes('/../') || path.endsWith('/..')) { throw new Error(`path is absolute but contains "/../" in it or ends with "../"? (E: 16145bf37d874abc886111c32c035124)`); }
131
+ // return path;
132
+ // }
133
+
134
+ // // we have a relative path. get the cwd from global for this particular space. If this space has no
135
+ // let ibGibGlobalThis = getIbGibGlobalThis();
136
+ // let info = ibGibGlobalThis.spaceShim[this.spaceId];
137
+ // if (!info) { throw new Error(`(UNEXPECTED) no info for spaceId in ibgibglobalthis? (E: c063f34ed784e70ccd19a6b2026eb924)`); }
138
+
139
+ // const { cwd } = info;
140
+ // if (!cwd) { throw new Error(`(UNEXPECTED) cwd falsy? (E: 91cbd7418a51d9d152ae53d4f87b3a24)`); }
141
+ // if (path.startsWith(cwd)) {
142
+ // console.log(`${lc} path already resolved (starts with cwd). path: ${path} (I: 1d99a4bad47398174fe127b85088fb24)`);
143
+ // }
144
+ // if (cwd.endsWith('/')) {
145
+ // // cwd does end with slash, so slice off initial if needed
146
+ // return cwd + (path.startsWith('/') ? path.slice(1) : path);
147
+ // } else {
148
+ // // cwd does NOT end with slash, so add if needed
149
+ // return cwd + (path.startsWith('/') ? path : `/${path}`);
150
+ // }
151
+ // }
152
+
153
+ join(...paths: string[]): string {
154
+ const lc = `${this.lc}[${this.join.name}]`;
155
+
156
+ if (paths.length === 0) {
157
+ console.log(`${lc} paths.length === 0. returning '.' per node convention. (I: 153da80765ff6160675fae895ebac225)`);
158
+ return '.'; /* <<<< returns early */
159
+ }
160
+ if (paths.length === 1 && paths[0] === '..') {
161
+ console.log(`${lc} paths.length === 1 && paths[0] === '..'. returning '..' per node convention. (I: 9af242b7615430a8c6899b1a332e9925)`);
162
+ return '..'; /* <<<< returns early */
163
+ }
164
+
165
+ let joined = '';
166
+ for (let i = 0; i < paths.length; i++) {
167
+ let path = paths[i];
168
+ if (path === '..') {
169
+ joined = joined.split('/').slice(0, -1).join('/');
170
+ } else {
171
+ if (path.startsWith('/')) { path = path.slice(1); }
172
+ if (path.endsWith('/')) {
173
+ path = path.slice(0, -1);
174
+ }
175
+ joined += (i > 0 ? '/' : '') + path;
176
+ }
177
+ }
178
+
179
+ return joined;
180
+ }
181
+
182
+ dirname(path: string): string {
183
+ return path.split('/').slice(0, -1).join('/');
184
+ }
185
+
186
+ basename(path: string, ext?: string): string {
187
+ return path.split('/').pop() ?? '';
188
+ }
189
+ }
190
+
191
+
192
+ export async function copyToClipboard({
193
+ data,
194
+ logalot,
195
+ }: {
196
+ data: { title?: string, text?: string, url?: string },
197
+ logalot?: boolean,
198
+ }): Promise<void> {
199
+ const lc = `[${copyToClipboard.name}]`;
200
+ try {
201
+ if (logalot) { console.log(`${lc} starting... (I: 37d6a4e3c3ee9fa46a0b1cd5c8a5cf24)`); }
202
+ let { title, text, url } = data;
203
+ const textToCopy = [
204
+ `${data.title || ''}`,
205
+ `${data.text || ''}`,
206
+ `${data.url || ''}`,
207
+ ].join('\n').trim();
208
+ await navigator.clipboard.writeText(textToCopy);
209
+ console.log('Content copied to clipboard!');
210
+ } catch (error) {
211
+ console.error(`${lc} ${extractErrorMsg(error)}`);
212
+ throw error;
213
+ } finally {
214
+ if (logalot) { console.log(`${lc} complete.`); }
215
+ }
216
+ }
217
+
218
+ /**
219
+ * helper to trigger browser's share functionality (or fallback).
220
+ */
221
+ export async function shareContent({
222
+ data,
223
+ logalot,
224
+ }: {
225
+ data: { title?: string, text?: string, url?: string },
226
+ logalot?: boolean,
227
+ }): Promise<void> {
228
+ const lc = `[${shareContent.name}]`;
229
+ try {
230
+ if (logalot) { console.log(`${lc} starting... (I: bfc7e484eba91f9126c3f5fc381e6424)`); }
231
+
232
+ if (navigator.share) {
233
+ await navigator.share(data);
234
+ console.log('Content shared successfully!');
235
+ } else {
236
+ console.warn('Web Share API not supported. Copying to clipboard instead.');
237
+ alert(`Share info copied to clipboard!`);
238
+ await copyToClipboard({ data, logalot });
239
+ }
240
+ } catch (error) {
241
+ console.error(`${lc} ${extractErrorMsg(error)}`);
242
+ throw error;
243
+ } finally {
244
+ if (logalot) { console.log(`${lc} complete.`); }
245
+ }
246
+ }
247
+
248
+ /**
249
+ * useful for knowing if we are executing in our website or within an iframe.
250
+ *
251
+ * ## driving use case
252
+ *
253
+ * When we are loading an embedded iframe for link-gib, it is trying to trigger
254
+ * the router which is no bueno.
255
+ *
256
+ * This is causing a problem though when testing inside an iframe in Project
257
+ * IDX...I guess I'll have to whitelist embedded sites like link-gib
258
+ *
259
+ * @returns true if we are executing in an iframe, false otherwise.
260
+ */
261
+ export function isExecutingInBlankGibWebAppProper({
262
+ metaName_appId,
263
+ metaContent_appId
264
+ }: {
265
+ /**
266
+ * this runs code:
267
+ *
268
+ * `const metaElement = document.querySelector(`meta[name=${metaName_appId}]`) as (HTMLMetaElement | null);`
269
+ *
270
+ * in the index, you should tag the meta tag with attribute of this.
271
+ */
272
+ metaName_appId: string,
273
+ /**
274
+ * this is an appId on the `metaElement.content`
275
+ */
276
+ metaContent_appId: string,
277
+ }): boolean {
278
+ const metaElement =
279
+ document.querySelector(`meta[name=${metaName_appId}]`) as (HTMLMetaElement | null);
280
+ return !!metaElement && metaElement.content === metaContent_appId;
281
+ }
282
+
283
+ /**
284
+ * Low-level plumbing for prompting the user for some text.
285
+ *
286
+ * ## notes
287
+ *
288
+ * * if an empty string is entered, confirm is automatic/always happens.
289
+ * * if confirm is true, will confirm on any entry
290
+ * * can just hit ENTER to confirm anything
291
+ * * this should be parameterized
292
+ *
293
+ * @returns the text the user entered.
294
+ */
295
+ export async function promptForText({
296
+ msg,
297
+ title,
298
+ confirm,
299
+ noNewLine,
300
+ rl,
301
+ defaultValue,
302
+ dontCloseRl,
303
+ cancelable,
304
+ }: {
305
+ msg: string,
306
+ title?: string,
307
+ confirm?: boolean,
308
+ noNewLine?: boolean,
309
+ /**
310
+ * ignored in web version. used in node version. this is after all, a hack
311
+ * port
312
+ */
313
+ rl?: any,
314
+ defaultValue?: string,
315
+ /**
316
+ * ignored in web version. used in node version. this is after all, a hack
317
+ * port
318
+ */
319
+ dontCloseRl?: boolean,
320
+ /**
321
+ * if true, cancel will show and an empty string will be returned
322
+ */
323
+ cancelable?: boolean,
324
+ }): Promise<string> {
325
+ const lc = `[${promptForText.name}]`;
326
+ try {
327
+ if (!msg) { throw new Error(`msg required (E: 7f4d67bca4cf98ea95fa110aabc98924)`); }
328
+
329
+ let result: string | undefined;
330
+
331
+ let attempts = 0;
332
+ let maxAttempts = 5;
333
+ do {
334
+ attempts++;
335
+ if (attempts >= maxAttempts) {
336
+ throw new Error(`max attempts reached (E: 1ef20ae955622d4b39479f3da91a1d25)`);
337
+ }
338
+ await delay(50);
339
+ result = await showFullscreenDialog({
340
+ title: title || 'Prompt for Info',
341
+ msg,
342
+ prompt: true,
343
+ showInput: true,
344
+ isPassword: false,
345
+ defaultValue,
346
+ });
347
+
348
+ } while (result === undefined && !cancelable);
349
+
350
+ return result ?? '';
351
+
352
+ // let userText: string | undefined = undefined;
353
+ // try {
354
+ // do {
355
+ // title = title ? `[${title}] ` : '';
356
+ // let promptMessage = `${title}${msg}${noNewLine ? ' ' : '\n'}`;
357
+ // let prompt = window.prompt;
358
+
359
+ // // Handle default value (Note: `prompt` can't pre-fill like readline.write)
360
+ // if (defaultValue) {
361
+ // if (defaultValue.includes('\n')) {
362
+ // if (logalot) { console.log(`defaultValue includes newline. (I: 147d4ea942995d0f92a19c3534c18a24)`); }
363
+ // // We can't pre-fill with newline in prompt, so we'll just inform if needed
364
+ // }
365
+ // promptMessage += ` (Default: ${defaultValue})`;
366
+ // }
367
+
368
+ // let userText1 = prompt(promptMessage);
369
+
370
+ // // Check for cancellation (prompt returns null on cancel)
371
+ // if (userText1 === null) {
372
+ // // return null; // User cancelled
373
+ // throw new Error(`user cancelled (E: bf3a221626f8cd14b2a945bfe661cb24)`);
374
+ // }
375
+
376
+ // if (userText1 === "") {
377
+ // let userText2 = prompt(`empty string entered. confirm:${noNewLine ? ' ' : '\n'}`);
378
+ // if (userText2 === userText1) {
379
+ // userText = userText1;
380
+ // break;
381
+ // } else {
382
+ // console.log(`confirm failed. please try again.`);
383
+ // }
384
+ // } else if (confirm) {
385
+ // let userText2 = prompt(`confirm by either hitting ENTER (empty string) or retype input:${noNewLine ? ' ' : '\n'}`);
386
+ // if (userText2 === '' || userText2 === userText1) {
387
+ // userText = userText1;
388
+ // } else {
389
+ // console.log(`confirm failed. please try again.`);
390
+ // }
391
+ // } else {
392
+ // userText = userText1;
393
+ // }
394
+
395
+ // } while (userText === undefined);
396
+
397
+ // return userText;
398
+
399
+ // } catch (error) {
400
+ // throw error;
401
+ // }
402
+ } catch (error) {
403
+ debugger; // in error block promptForText
404
+ console.error(`${lc} ${extractErrorMsg(error)}`);
405
+ throw error;
406
+ }
407
+ }
408
+
409
+ /**
410
+ * not implemented atow (12/2024). I think we'll have perhaps a modal dialog
411
+ * with a known name and get at it that way.
412
+ */
413
+ export async function promptForSecret({
414
+ msg,
415
+ confirm,
416
+ }: {
417
+ msg?: string,
418
+ confirm: boolean,
419
+ }): Promise<string> {
420
+ const lc = `[${promptForSecret.name}]`;
421
+ try {
422
+ if (logalot) { console.log(`${lc} starting... (I: 795a4ce348ddb9a5119770f4c572ac24)`); }
423
+
424
+ let result: string | undefined = undefined;
425
+
426
+ let firstTry = true;
427
+ let attempts = 0;
428
+ let maxAttempts = 5;
429
+
430
+ do {
431
+ attempts++;
432
+ if (attempts >= maxAttempts) {
433
+ throw new Error(`max attempts reached (E: d4166b4bf37aff0c6d44567792e9ad25)`);
434
+ }
435
+ await delay(50);
436
+ result = await showFullscreenDialog({
437
+ title: firstTry ? 'Shh...' : 'Secrets didn\'t match, try again...',
438
+ msg: msg || 'Enter Your Secret...',
439
+ prompt: true,
440
+ showInput: true,
441
+ isPassword: true,
442
+ defaultValue: undefined,
443
+ });
444
+ if (result === undefined) { throw new Error(`user cancelled (E: 91519d04378e84106f3df8eb36d99725)`); }
445
+
446
+ if (confirm) {
447
+ await delay(250);
448
+ let result2 = await showFullscreenDialog({
449
+ title: 'Shh...',
450
+ msg: 'Confirm...',
451
+ prompt: true,
452
+ showInput: true,
453
+ isPassword: true,
454
+ defaultValue: undefined,
455
+ });
456
+ if (result2 === undefined) { result = undefined; }
457
+ if (result !== result2) {
458
+ result = undefined;
459
+ firstTry = false;
460
+ await delay(250);
461
+ }
462
+ }
463
+
464
+
465
+ } while (result === undefined);
466
+
467
+ return result;
468
+ } catch (error) {
469
+ console.error(`${lc} ${extractErrorMsg(error)}`);
470
+ throw error;
471
+ } finally {
472
+ if (logalot) { console.log(`${lc} complete.`); }
473
+ }
474
+ }
475
+
476
+ /**
477
+ * prompt specifically looking to confirm something. if "cancelled", returns
478
+ * false.
479
+ */
480
+ export async function promptForConfirm({
481
+ msg,
482
+ yesLabel,
483
+ noLabel,
484
+ }: {
485
+ /**
486
+ * if provided, this is the message displayed when confirming.
487
+ */
488
+ msg?: string,
489
+ yesLabel?: string,
490
+ noLabel?: string,
491
+ }): Promise<boolean> {
492
+ const lc = `[${promptForConfirm.name}]`;
493
+ try {
494
+ await delay(50);
495
+ let result = await showFullscreenDialog({
496
+ title: 'Confirm?',
497
+ msg: msg ?? 'Confirm?',
498
+ okButtonTitle: yesLabel || undefined,
499
+ cancelButtonTitle: noLabel || undefined,
500
+ prompt: true,
501
+ });
502
+ return !!result;
503
+ // msg ||= 'confirm?';
504
+ // yesLabel ||= '(y)es';
505
+ // noLabel ||= '(n)o';
506
+ // try {
507
+ // const fnAnswerMatchesLabel = (answer: string, label: string) => {
508
+ // if (answer === label.replace(/[\(\)]/g, '').toLowerCase()) {
509
+ // // matched full label
510
+ // return true; /* <<<< returns early */
511
+ // } else {
512
+ // // check for short answers
513
+ // const regexCaptureCharsInsideParens = /\((\w+)\)/;
514
+ // const shortLabel = label.match(regexCaptureCharsInsideParens);
515
+ // if ((shortLabel ?? []).length >= 2) {
516
+ // if (answer === shortLabel![1].toLowerCase()) {
517
+ // // matched short label
518
+ // return true; /* <<<< returns early */
519
+ // }
520
+ // }
521
+ // }
522
+ // // if got this far, nothing positive matched
523
+ // return false;
524
+ // };
525
+
526
+ // const prompt = window.prompt;
527
+
528
+ // // try up to three times. if match found, either way, return early.
529
+ // const maxTries = 3;
530
+ // for (let i = 0; i < maxTries; i++) {
531
+ // let answer = prompt(`${msg} [${yesLabel}, ${noLabel}]\n`);
532
+ // if (answer) {
533
+ // answer = answer.toLowerCase();
534
+ // const matchesYesLabel = fnAnswerMatchesLabel(answer, yesLabel);
535
+ // if (matchesYesLabel) { return true; /* <<<< returns early */ }
536
+ // const matchesNoLabel = fnAnswerMatchesLabel(answer, noLabel);
537
+ // if (matchesNoLabel) { return false; /* <<<< returns early */ }
538
+ // } else {
539
+ // `no answer provided. defaulting to no...`;
540
+ // console.log('huh?');
541
+ // }
542
+ // }
543
+
544
+ // // max tries reached
545
+ // throw new Error(`could not confirm (E: ebbd2f642bde103c41d0102cf7e38d24)`);
546
+ // } catch (error) {
547
+ // throw error;
548
+ // }
549
+ } catch (error) {
550
+ console.error(`${lc} ${error.message}`);
551
+ throw error;
552
+ } finally {
553
+ if (logalot) { console.log(`${lc} complete.`); }
554
+ }
555
+ }
556
+
557
+ export async function alertUser({
558
+ msg,
559
+ title,
560
+ skipHitEnterToContinue,
561
+ }: {
562
+ msg: string,
563
+ title?: string,
564
+ /**
565
+ * ignored in web version atow (12/2024)
566
+ */
567
+ skipHitEnterToContinue?: boolean,
568
+ }): Promise<void> {
569
+ const lc = `[${alertUser.name}]`;
570
+ try {
571
+
572
+ if (!msg) { throw new Error(`msg required (E: ffcf7dd00324df7cea2792223d229524)`); }
573
+ try {
574
+ title ??= '';
575
+ await delay(50);
576
+ await showFullscreenDialog({
577
+ title,
578
+ msg,
579
+ });
580
+ } catch (error) {
581
+ throw error;
582
+ }
583
+ } catch (error) {
584
+ console.error(`${lc} ${extractErrorMsg(error)}`);
585
+ throw error;
586
+ }
587
+ }
588
+
589
+ export function getUserPreferredColorScheme(): 'light' | 'dark' {
590
+ const lc = `[${getUserPreferredColorScheme.name}]`;
591
+ try {
592
+ if (logalot) { console.log(`${lc} starting... (I: 196286d17b656bce5ce16f358f386525)`); }
593
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
594
+ return prefersDark ? 'dark' : 'light';
595
+ } catch (error) {
596
+ console.error(`${lc} ${extractErrorMsg(error)}`);
597
+ throw error;
598
+ } finally {
599
+ if (logalot) { console.log(`${lc} complete.`); }
600
+ }
601
+ }
602
+
603
+ /**
604
+ * helper function to get a query param in the current url.
605
+ *
606
+ * # ONLY IN BROWSER
607
+ *
608
+ * not for use in node.js
609
+ *
610
+ * @returns raw
611
+ */
612
+ export function getQueryParam<TValue>({ paramName, parseJSON, logalot, }: {
613
+ paramName: string, parseJSON?: boolean, logalot?: boolean,
614
+ }): TValue | undefined {
615
+ const lc = `[${getQueryParam.name}]`;
616
+ try {
617
+ if (logalot) { console.log(`${lc} starting... (I: f1a61ecdbb52cff1b958d1ceaea85f24)`); }
618
+
619
+ const url = new URL(window.location.href);
620
+ const rawValue = url.searchParams.get(paramName);
621
+ if (rawValue) {
622
+ const decodedValue = decodeURIComponent(rawValue);
623
+ if (parseJSON) {
624
+ try {
625
+ return JSON.parse(decodedValue) as TValue;
626
+ } catch (parseError) {
627
+ console.error(`${lc} Error parsing JSON from query parameter ${paramName}: ${parseError} (E: fa8128dbe8ed41fc9fdf57a8146d88de)`);
628
+ throw parseError;
629
+ }
630
+ } else {
631
+ return decodedValue as TValue;
632
+ }
633
+ } else {
634
+ return undefined;
635
+ }
636
+ } catch (error) {
637
+ console.error(`${lc} ${extractErrorMsg(error)}`);
638
+ throw error;
639
+ } finally {
640
+ if (logalot) { console.log(`${lc} complete.`); }
641
+ }
642
+ }
643
+
644
+ /**
645
+ * helper function to set a query param in the current url.
646
+ *
647
+ * # ONLY IN BROWSER
648
+ *
649
+ * not for use in node.js
650
+ */
651
+ export function setQueryParam<TValue>({
652
+ paramName, paramValue, rmParam, logalot,
653
+ }: {
654
+ paramName: string,
655
+ paramValue?: TValue,
656
+ /**
657
+ * if true, we will remove the param from the URL.
658
+ */
659
+ rmParam?: boolean,
660
+ logalot?: boolean,
661
+ }): void {
662
+ const lc = `[${setQueryParam.name}]`;
663
+ try {
664
+ if (logalot) { console.log(`${lc} starting... (I: f3c557d19f5b3a723611c59aa4a20324)`); }
665
+ const url = new URL(window.location.href);
666
+
667
+ if (rmParam) {
668
+ url.searchParams.delete(paramName);
669
+ } else {
670
+ const actualValue = typeof paramValue === 'string' ?
671
+ paramValue :
672
+ JSON.stringify(paramValue);
673
+ url.searchParams.set(paramName, actualValue);
674
+ }
675
+
676
+ // Update the URL without reloading the page
677
+ window.history.replaceState({}, '', url.toString());
678
+ } catch (error) {
679
+ console.error(`${lc} ${extractErrorMsg(error)}`);
680
+ throw error;
681
+ } finally {
682
+ if (logalot) { console.log(`${lc} complete.`); }
683
+ }
684
+ }
685
+
686
+ /**
687
+ * helper to highlight an element with border/background.
688
+ *
689
+ * ## requires
690
+ *
691
+ * .highlight and .unhighlight classes
692
+ *
693
+ * The unhighlight is for correctly showing the transition/animation.
694
+ *
695
+ * ## intent
696
+ *
697
+ * Just making this to make highlighting things (drawing the user's eye)
698
+ * easier and more consistent.
699
+ *
700
+ * @see {@link unhighlightElement}
701
+ */
702
+ export async function highlightElement({
703
+ el,
704
+ magicHighlightTimingMs,
705
+ scrollIntoView,
706
+ }: {
707
+ el: HTMLElement,
708
+ /**
709
+ * if provided, will unhighlight the element after this delay in ms
710
+ */
711
+ magicHighlightTimingMs?: number,
712
+ scrollIntoView?: boolean,
713
+ }): Promise<void> {
714
+ const lc = `[${highlightElement.name}]`;
715
+ try {
716
+ if (logalot) { console.log(`${lc} starting... (I: 1820329f88bb937b21ff98e624c03e25)`); }
717
+
718
+ if (scrollIntoView) { el.scrollIntoView({ behavior: 'smooth' }); }
719
+
720
+ el.classList.add('highlight');
721
+ if (magicHighlightTimingMs) {
722
+ await delay(magicHighlightTimingMs);
723
+ el.classList.add('unhighlight');
724
+ el.classList.remove('highlight');
725
+ await delay(magicHighlightTimingMs);
726
+ el.classList.remove('unhighlight');
727
+ }
728
+ } catch (error) {
729
+ console.error(`${lc} ${extractErrorMsg(error)}`);
730
+ throw error;
731
+ } finally {
732
+ if (logalot) { console.log(`${lc} complete.`); }
733
+ }
734
+ }
735
+
736
+ /**
737
+ * @see {@link highlightElement}
738
+ */
739
+ export async function unhighlightElement({
740
+ el,
741
+ }: {
742
+ el: HTMLElement,
743
+ }): Promise<void> {
744
+ const lc = `[${unhighlightElement.name}]`;
745
+ try {
746
+ if (logalot) { console.log(`${lc} starting... (I: ee5894b05ec31085883098cc512e1c25)`); }
747
+
748
+ el.classList.add('unhighlight');
749
+ el.classList.remove('highlight');
750
+ await delay(500);
751
+ el.classList.remove('unhighlight');
752
+ } catch (error) {
753
+ console.error(`${lc} ${extractErrorMsg(error)}`);
754
+ throw error;
755
+ } finally {
756
+ if (logalot) { console.log(`${lc} complete.`); }
757
+ }
758
+ }
759
+
760
+ /**
761
+ * builds a color schema based on the gib.
762
+ *
763
+ * note that the alpha drives the translucent property, but the solid color is
764
+ * always built
765
+ */
766
+ export function getDeterministicColorInfo({
767
+ ibGibAddr,
768
+ gib,
769
+ ibGib,
770
+ translucentAlpha = 10,
771
+ }: {
772
+ ibGibAddr?: IbGibAddr,
773
+ gib?: Gib,
774
+ ibGib?: IbGib_V1,
775
+ /**
776
+ * drives the translucent color.
777
+ *
778
+ * @default 10
779
+ */
780
+ translucentAlpha?: number
781
+ }): GibColorInfo {
782
+ const lc = `[${getDeterministicColorInfo.name}]`;
783
+ try {
784
+ if (logalot) { console.log(`${lc} starting... (I: 3b70af42d1c4f6ae91870f3a15c6c625)`); }
785
+ if (!ibGibAddr && !gib && !ibGib) { gib = GIB; }
786
+ gib ??= ibGib?.gib ?? getIbAndGib({ ibGibAddr }).gib;
787
+ const gibInfo = getGibInfo({ gib });
788
+ translucentAlpha ??= 10;
789
+ /**
790
+ * we want to color coordinate according to timeline if possible, i.e.,
791
+ * by tjpGib.
792
+ */
793
+ let drivingHash = '';
794
+ if (gibInfo.isPrimitive) {
795
+ return {
796
+ gib,
797
+ gibInfo,
798
+ punctiliarColor: DEFAULT_IBGIB_COLOR,
799
+ punctiliarColorTranslucent: DEFAULT_IBGIB_TRANSLUCENT,
800
+ punctiliarColorContrast: DEFAULT_IBGIB_COLOR_CONTRAST,
801
+ }; /* <<<< returns early */
802
+ } else {
803
+ drivingHash = gibInfo.tjpGib ?? gibInfo.punctiliarHash ?? gib; // hmm, gib should be punctiliar but meh
804
+ }
805
+
806
+
807
+
808
+ /**
809
+ * gets the color string
810
+ */
811
+ // const fnGetColorStr = (drivingHash: string) => {
812
+ // function getContrastColor(hexcolor: string) {
813
+ // const c = hexcolor.concat().replace("#", "");
814
+ // var r = parseInt(c.substr(0, 2), 16);
815
+ // var g = parseInt(c.substr(2, 2), 16);
816
+ // var b = parseInt(c.substr(4, 2), 16);
817
+ // var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
818
+ // return (yiq >= 128) ? '#000000' : '#FFFFFF';
819
+ // }
820
+ // let alphaStr = '';
821
+ // if (translucentAlpha || translucentAlpha === 0) {
822
+ // if (translucentAlpha < 0 || translucentAlpha > 100) {
823
+ // throw new Error(`alpha must be between 0 and 100 (E: c78faeb1477482c739b03dd32d2e1825)`);
824
+ // }
825
+ // if (translucentAlpha === 100) {
826
+ // alphaStr = '';
827
+ // } else if (translucentAlpha >= 0 && translucentAlpha < 10) {
828
+ // // single digit
829
+ // alphaStr = `0${translucentAlpha}`;
830
+ // } else {
831
+ // alphaStr = translucentAlpha.toString();
832
+ // }
833
+ // }
834
+ // const color = `#${drivingHash.substring(0, 6)}`;
835
+ // const colorTranslucent = `#${drivingHash.substring(0, 6)}${alphaStr}`;
836
+ // const colorContrast = getContrastColor(color);
837
+ // return [color, colorTranslucent, colorContrast];
838
+ // };
839
+
840
+ const [punctiliarColor, punctiliarColorTranslucent, punctiliarColorContrast] = getColorStrings(translucentAlpha, gibInfo.punctiliarHash ?? gib);
841
+ const [tjpColor, tjpColorTranslucent, tjpColorContrast] = !!gibInfo.tjpGib ?
842
+ getColorStrings(translucentAlpha, gibInfo.tjpGib) :
843
+ [undefined, undefined, undefined];
844
+
845
+ return {
846
+ gib,
847
+ gibInfo,
848
+ punctiliarColor, punctiliarColorTranslucent, punctiliarColorContrast,
849
+ tjpColor, tjpColorTranslucent, tjpColorContrast,
850
+ };
851
+ } catch (error) {
852
+ const errorMsg = `${lc} ${extractErrorMsg(error)}`;
853
+ console.error(errorMsg);
854
+ return {
855
+ gib: gib ?? GIB,
856
+ gibInfo: { isPrimitive: true },
857
+ punctiliarColor: '#ff0000', // red
858
+ punctiliarColorTranslucent: '#ff000010', // translucent red
859
+ punctiliarColorContrast: '#ffffff', // black
860
+ errorMsg,
861
+ };
862
+ } finally {
863
+ if (logalot) { console.log(`${lc} complete.`); }
864
+ }
865
+ }
866
+
867
+ /**
868
+ * gets the color, colorTranslucent and colorContrast
869
+ */
870
+ export function getColorStrings(translucentAlpha: number, drivingHash: string): [string, string, string] {
871
+ function getContrastColor(hexcolor: string) {
872
+ const c = hexcolor.concat().replace("#", "");
873
+ var r = parseInt(c.substr(0, 2), 16);
874
+ var g = parseInt(c.substr(2, 2), 16);
875
+ var b = parseInt(c.substr(4, 2), 16);
876
+ var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
877
+ return (yiq >= 128) ? '#000000' : '#FFFFFF';
878
+ }
879
+ let alphaStr = '';
880
+ if (translucentAlpha || translucentAlpha === 0) {
881
+ if (translucentAlpha < 0 || translucentAlpha > 100) {
882
+ throw new Error(`alpha must be between 0 and 100 (E: c78faeb1477482c739b03dd32d2e1825)`);
883
+ }
884
+ if (translucentAlpha === 100) {
885
+ alphaStr = '';
886
+ } else if (translucentAlpha >= 0 && translucentAlpha < 10) {
887
+ // single digit
888
+ alphaStr = `0${translucentAlpha}`;
889
+ } else {
890
+ alphaStr = translucentAlpha.toString();
891
+ }
892
+ }
893
+ const color = `#${drivingHash.substring(0, 6)}`;
894
+ const colorTranslucent = `#${drivingHash.substring(0, 6)}${alphaStr}`;
895
+ const colorContrast = getContrastColor(color);
896
+ return [color, colorTranslucent, colorContrast];
897
+ };
898
+
899
+ /**
900
+ * Takes an incoming string. Assumes it's invalid. Does best effort at validating this.
901
+ * Gets the raw export ibgib if it can. If so, and if it is compressed, decompresses the
902
+ * compressed graph contained in the export ibgib.
903
+ *
904
+ * @returns RawExportIbGib_V1 and its decompressed graph
905
+ */
906
+ export async function getRawExportIbGibAndGraphFromJsonString({
907
+ exportIbGibJsonString,
908
+ metaspace,
909
+ }: {
910
+ exportIbGibJsonString: string,
911
+ metaspace: MetaspaceService,
912
+ }): Promise<[RawExportIbGib_V1, FlatIbGibGraph]> {
913
+ const lc = `[${getRawExportIbGibAndGraphFromJsonString.name}]`;
914
+ try {
915
+ debugger; // walk thru getRawExportIbGibAndGraphFromJsonString
916
+ if (logalot) { console.log(`${lc} starting... (I: genuuid)`); }
917
+ if (!metaspace) { throw new Error(`(UNEXPECTED) metaspace falsy? (E: genuuid)`); }
918
+
919
+ const space = await metaspace.getLocalUserSpace({ lock: false });
920
+ if (!space) { throw new Error(`(UNEXPECTED) couldn't get default local user space? (E: genuuid)`); }
921
+
922
+ let parsedIbGib_notYetValidated: IbGib_V1;
923
+ let parsedExportIbGib_dependenciesNotValidated: RawExportIbGib_V1;
924
+ try {
925
+ parsedIbGib_notYetValidated = JSON.parse(exportIbGibJsonString) as IbGib_V1;
926
+ } catch (error) {
927
+ const emsg = `Error during parse JSON. error: ${extractErrorMsg(error)} (E: genuuid)`;
928
+ const errorHack = new Error(emsg);
929
+ (errorHack as any).cause = error;
930
+ throw errorHack;
931
+ }
932
+ try {
933
+ const validationErrors = await validateIbGibIntrinsically({ ibGib: parsedIbGib_notYetValidated }) ?? [];
934
+ if (validationErrors.length > 0) {
935
+ throw new Error(`validation errors when validating the parsed ibgib that should be a RawExportIbGib_V1: ${validationErrors} (E: 8ba178d3b26e8eca28a67c182fe16825)`);
936
+ }
937
+ // todo: other validation raw export ibgib, maybe to see if it's a full dependency graph, etc.
938
+
939
+ parsedExportIbGib_dependenciesNotValidated = parsedIbGib_notYetValidated as RawExportIbGib_V1;
940
+ if (!parsedExportIbGib_dependenciesNotValidated.data) { throw new Error(`(UNEXPECTED) rawExportIbGib.data falsy? (E: ef1824d1cca5584ab8e34288346e9825)`); }
941
+ } catch (error) {
942
+ const emsg = `Error during parse JSON. error: ${extractErrorMsg(error)} (E: genuuid)`;
943
+ const errorHack = new Error(emsg);
944
+ (errorHack as any).cause = error;
945
+ throw errorHack;
946
+ }
947
+
948
+
949
+
950
+ // at this point, we have a possibly quite large ibGib whose data
951
+ // includes a dependencyGraphAsString. this could possibly be
952
+ // compressed.
953
+ let payloadGraph: FlatIbGibGraph;
954
+ if (!!parsedExportIbGib_dependenciesNotValidated.data.compression) {
955
+ switch (parsedExportIbGib_dependenciesNotValidated.data.compression) {
956
+ case 'gzip':
957
+ payloadGraph = await decompressIbGibGraphFromString({
958
+ compressedBase64: parsedExportIbGib_dependenciesNotValidated.data.dependencyGraphAsString,
959
+ });
960
+ break;
961
+ default:
962
+ throw new Error(`unknown value of rawExportIbGib.data.compression: ${parsedExportIbGib_dependenciesNotValidated.data.compression} (E: 784672fae568312d887ddbb841199925)`);
963
+ }
964
+ } else {
965
+ payloadGraph = await deserializeStringToGraph({
966
+ jsonString: parsedExportIbGib_dependenciesNotValidated.data.dependencyGraphAsString
967
+ });
968
+ }
969
+
970
+ const validationErrorMap: { [addr: string]: string[] } = {};
971
+ for (const [addr, payloadIbGib] of Object.entries(payloadGraph)) {
972
+ const validationErrors = await validateIbGibIntrinsically({ ibGib: payloadIbGib }) ?? [];
973
+ if (validationErrors.length > 0) { validationErrorMap[addr] = validationErrors; }
974
+ }
975
+ if (Object.keys(validationErrorMap).length > 0) {
976
+ throw new Error(`there were validation errors for the RawExportIbGib_V1.data payload (contained in data.dependencyGraphAsString). Here is the validationErrorMap:\n${pretty({ validationErrorMap })} (E: e63f38b182a84122d83a55befb369825)`);
977
+ }
978
+ const exportIbGib_validated = parsedExportIbGib_dependenciesNotValidated;
979
+
980
+ return [exportIbGib_validated, payloadGraph];
981
+ } catch (error) {
982
+ console.error(`${lc} ${extractErrorMsg(error)}`);
983
+ throw error;
984
+ } finally {
985
+ if (logalot) { console.log(`${lc} complete.`); }
986
+ }
987
+ }
988
+
989
+ /**
990
+ * exports a given ibgib to the default local userspace in the metaspace.
991
+ */
992
+ export async function exportIbGib({
993
+ ibGib,
994
+ compress,
995
+ // downloadAnchorEl,
996
+ metaspace,
997
+ space,
998
+ }: {
999
+ ibGib: IbGib_V1,
1000
+ compress: boolean,
1001
+ // downloadAnchorEl: HTMLAnchorElement,
1002
+ metaspace: MetaspaceService,
1003
+ space: IbGibSpaceAny,
1004
+ }): Promise<void> {
1005
+ const lc = `[${exportIbGib.name}]`;
1006
+ try {
1007
+ if (logalot) { console.log(`${lc} starting... (I: 623d9463d919683be81f749821a95825)`); }
1008
+ if (isPrimitive({ ibGib })) { throw new Error(`ibGib is primitive. Can't export primitive. (E: dd42c42e9fda0707e81c692af1a2a225)`); }
1009
+
1010
+ const resGetExport = await getRawExportIbGib({
1011
+ ibGib,
1012
+ live: true,
1013
+ compress,
1014
+ metaspace: metaspace,
1015
+ space,
1016
+ });
1017
+
1018
+ const { rawExportIbGib: exportIbGib, errors: exportErrors } = resGetExport;
1019
+ if ((exportErrors ?? []).length > 0) { throw new Error(`Export had errors: ${exportErrors!} (E: 05faf83f25d3449ab809dfd24eeaf825)`); }
1020
+
1021
+ // at this point, we have a possibly quite large ibGib whose data includes
1022
+ // every single other ibgib that ibGib relates to (its dependency graph). This
1023
+ // so now we can save this file and later import from it.
1024
+
1025
+ /**
1026
+ * exportIbGib is guaranteed to have a serializable structure, i.e.,
1027
+ * the data has only primitives. (there are no Uint8Array)
1028
+ */
1029
+ const exportIbGibAsString = JSON.stringify(exportIbGib);
1030
+
1031
+ // thank you SO, OP and volzotan at https://stackoverflow.com/questions/19721439/download-json-object-as-a-file-from-browser
1032
+ // set the anchor's href to a data stream
1033
+ const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(exportIbGibAsString);
1034
+
1035
+ // get the filename for the anchor to suggest for the "download"
1036
+ const exportAddr = getIbGibAddr({ ibGib: exportIbGib });
1037
+ const filename = `${exportAddr}.json`;
1038
+
1039
+ // trigger the click
1040
+ const downloadAnchorEl = document.createElement('a');
1041
+ downloadAnchorEl.setAttribute("style", "none");
1042
+ downloadAnchorEl.setAttribute("href", dataStr);
1043
+ downloadAnchorEl.setAttribute("download", filename);
1044
+ const div = document.getElementsByTagName('div')[0]; // just append to the first div then remove it
1045
+ div.appendChild(downloadAnchorEl);
1046
+ downloadAnchorEl.click();
1047
+ div.removeChild(downloadAnchorEl);
1048
+ } catch (error) {
1049
+ console.error(`${lc} ${extractErrorMsg(error)}`);
1050
+ throw error;
1051
+ } finally {
1052
+ if (logalot) { console.log(`${lc} complete.`); }
1053
+ }
1054
+ }
1055
+
1056
+ export async function promptForAPIKey({
1057
+ msg,
1058
+ }: {
1059
+ /**
1060
+ * msg to tell the user when prompting for the API key (secret)
1061
+ *
1062
+ * originally in blankgib, this is CHAT_WITH_AGENT_NEED_API_KEY
1063
+ */
1064
+ msg: string,
1065
+ }): Promise<string | undefined> {
1066
+ const lc = `[${promptForAPIKey.name}]`;
1067
+ try {
1068
+ if (logalot) { console.log(`${lc} starting... (I: genuuid)`); }
1069
+ let resAPIKey = '';
1070
+ let tryAgain = false;
1071
+ let attempts = 0;
1072
+ let maxAttempts = 5;
1073
+ do {
1074
+ attempts++;
1075
+ if (attempts >= maxAttempts) { throw new Error(`too many attempts (E: genuuid)`); }
1076
+ resAPIKey = await promptForSecret({
1077
+ msg,
1078
+ confirm: false,
1079
+ });
1080
+ if (resAPIKey) {
1081
+ if (resAPIKey.match(GEMINI_API_KEY_REGEXP)) {
1082
+ tryAgain = false;
1083
+ // return resAPIKey; /* <<<< returns early */
1084
+ } else {
1085
+ await alertUser({
1086
+ title: `That's an API Key?`,
1087
+ msg: `That doesn't look like a valid API key, please try again, or hit cancel if you don't want to at this time.`,
1088
+ });
1089
+ tryAgain = true;
1090
+ }
1091
+ } else {
1092
+ console.log(`${lc} user cancelled entering API key. (I: genuuid)`);
1093
+ tryAgain = false;
1094
+ }
1095
+ } while (tryAgain);
1096
+
1097
+ return resAPIKey;
1098
+ } catch (error) {
1099
+ console.error(`${lc} ${extractErrorMsg(error)}`);
1100
+ throw error;
1101
+ } finally {
1102
+ if (logalot) { console.log(`${lc} complete.`); }
1103
+ }
1104
+ }
1105
+
1106
+ /**
1107
+ * updates the given {@link apiKey}. if {@link force} is true and `apiKey` is
1108
+ * empty, then this will set an empty string for the apiKey, effectively
1109
+ * deleting it.
1110
+ */
1111
+ export async function updateAPIKeyInStorage({
1112
+ dbName,
1113
+ storeName,
1114
+ key,
1115
+ apiKey,
1116
+ force,
1117
+ }: {
1118
+ dbName: string,
1119
+ storeName: string,
1120
+ key: string,
1121
+ apiKey: string,
1122
+ force: boolean,
1123
+ }): Promise<void> {
1124
+ const lc = `[${updateAPIKeyInStorage.name}]`;
1125
+ try {
1126
+ if (logalot) { console.log(`${lc} starting... (I: 64951b38da35ec5ff847004d53b2d425)`); }
1127
+
1128
+ const matches = apiKey.match(GEMINI_API_KEY_REGEXP);
1129
+ if (matches || force) {
1130
+ await storagePut({
1131
+ dbName, storeName,
1132
+ key,
1133
+ value: apiKey,
1134
+ });
1135
+ if (apiKey) {
1136
+ // set a new truthy key
1137
+ await alertUser({ title: `need to reload...`, msg: `Cool! We successfully SAVED your Gemini API key in your browser's IndexedDB.\n\nIf you'd like to remove it later, you can clear it out by using the ${CONFIG_OPTION_GEMINI_API_KEY_LOCATION_HELP}.\n\nWe must now reload the page to use the new API key... (investment would be a good thing to improve this UX workflow!)` });
1138
+ } else {
1139
+ // cleared out the key
1140
+ await alertUser({ title: `need to reload...`, msg: `Cool! We successfully CLEARED your Gemini API key from your browser's IndexedDB.\n\nIf you'd like to set a new key, use the ${CONFIG_OPTION_GEMINI_API_KEY_LOCATION_HELP}.\n\nThe API key is already removed, but we must now reload the page for this to propagate throughout the web page... (investment would be a good thing to improve this UX workflow!)` });
1141
+ }
1142
+ window.location.reload();
1143
+ } else {
1144
+ throw new Error(`apiKey does not match apiKeyRegex (${GEMINI_API_KEY_REGEXP.source}) and force is false. (E: 2d6c798803e6b71bf6aa70bd60170825)`);
1145
+ }
1146
+ } catch (error) {
1147
+ console.error(`${lc} ${extractErrorMsg(error)}`);
1148
+ throw error;
1149
+ } finally {
1150
+ if (logalot) { console.log(`${lc} complete.`); }
1151
+ }
1152
+
1153
+ }
1154
+
1155
+ /**
1156
+ * wrapper for simplifying/asserting an element that is expected to exist.
1157
+ *
1158
+ * ## intent
1159
+ *
1160
+ * This avoids using TypeScript truthy assertions (!) or excessive
1161
+ * falsy/exception checks.
1162
+ */
1163
+ export function getElementById_throwsIfFalsy<TElement extends Element>({
1164
+ id,
1165
+ shadowRoot,
1166
+ }: {
1167
+ id: string;
1168
+ /**
1169
+ * If set, will get element here, else will use document
1170
+ */
1171
+ shadowRoot?: ShadowRoot;
1172
+ }): TElement {
1173
+ const lc = `[${getElementById_throwsIfFalsy.name}]`;
1174
+ try {
1175
+ if (logalot) { console.log(`${lc} starting... (I: 18a338c6dab8690c72b8759b8d952925)`); }
1176
+ let resElement = !!shadowRoot ?
1177
+ shadowRoot.getElementById(id) as TElement | null :
1178
+ document.getElementById(id) as TElement | null;
1179
+
1180
+ if (resElement) {
1181
+ return resElement;
1182
+ } else {
1183
+ throw new Error(`${!!shadowRoot ? 'shadowRoot' : 'document'}.getElementById(${id}) returned null. So...Element was not found. (E: 5e501f6835cc74cd4c2faf0d9e387825)`);
1184
+ }
1185
+ } catch (error) {
1186
+ console.error(`${lc} ${extractErrorMsg(error)}`);
1187
+ throw error;
1188
+ } finally {
1189
+ if (logalot) { console.log(`${lc} complete.`); }
1190
+ }
1191
+ }
1192
+
1193
+ /**
1194
+ * wrapper that throws if element not found.
1195
+ * @param id of Element
1196
+ * @returns Element of type TElement or throws.
1197
+ * @see {@link shadowRoot_getElementById}
1198
+ *
1199
+ * ## intent
1200
+ *
1201
+ * This avoids using TypeScript truthy assertions (!) or excessive
1202
+ * falsy/exception checks.
1203
+ */
1204
+ export function document_getElementById<TElement extends Element = HTMLElement>(id: string): TElement {
1205
+ return getElementById_throwsIfFalsy<TElement>({ id });
1206
+ }
1207
+
1208
+ /**
1209
+ * wrapper that throws if element not found.
1210
+ * @param shadowRoot in which the element MUST be truthy or throws
1211
+ * @param id of Element
1212
+ * @returns Element of type TElement or throws.
1213
+ * @see {@link document_getElementById}
1214
+ *
1215
+ * ## intent
1216
+ *
1217
+ * This avoids using TypeScript truthy assertions (!) or excessive
1218
+ * falsy/exception checks.
1219
+ */
1220
+ export function shadowRoot_getElementById<TElement extends Element = HTMLElement>(shadowRoot: ShadowRoot, id: string): TElement {
1221
+ return getElementById_throwsIfFalsy<TElement>({ id, shadowRoot });
1222
+ }
1223
+
1224
+
1225
+ export function getGlobalMetaspace_waitIfNeeded(): Promise<MetaspaceService> {
1226
+ const lc = `[${getGlobalMetaspace_waitIfNeeded.name}]`;
1227
+ try {
1228
+ if (logalot) { console.log(`${lc} starting... (I: 96e9b89ef4986c33e819340ec7d05325)`); }
1229
+ throw new Error(`not implemented (E: eb1258f32cb543ce684812845dd28c25)`);
1230
+ } catch (error) {
1231
+ console.error(`${lc} ${extractErrorMsg(error)}`);
1232
+ throw error;
1233
+ } finally {
1234
+ if (logalot) { console.log(`${lc} complete.`); }
1235
+ }
1236
+ }
1237
+
1238
+ export function getGlobalStoreName(): Promise<string> {
1239
+ const lc = `[${getGlobalStoreName.name}]`;
1240
+ try {
1241
+ if (logalot) { console.log(`${lc} starting... (I: 62a29f9982b4b5ecd91ff58ca4dd6825)`); }
1242
+ // ARMY_STORE
1243
+ throw new Error(`not implemented (E: 33bc38b63bb8ab5244c6a0388aadaa25)`);
1244
+ } catch (error) {
1245
+ console.error(`${lc} ${extractErrorMsg(error)}`);
1246
+ throw error;
1247
+ } finally {
1248
+ if (logalot) { console.log(`${lc} complete.`); }
1249
+ }
1250
+ }
1251
+
1252
+ export function getGlobalDbName(): string {
1253
+ const lc = `[${getGlobalDbName.name}]`;
1254
+ try {
1255
+ if (logalot) { console.log(`${lc} starting... (I: 8c8f08728fc7384f87697377358cc825)`); }
1256
+ // BLANK_GIB_DB_NAME
1257
+ throw new Error(`not implemented (E: 6586f8982de8bcea91f922982c3ea825)`);
1258
+ } catch (error) {
1259
+ console.error(`${lc} ${extractErrorMsg(error)}`);
1260
+ throw error;
1261
+ } finally {
1262
+ if (logalot) { console.log(`${lc} complete.`); }
1263
+ }
1264
+ }
1265
+
1266
+ export function getGlobalIndexedDbKey_APIKey(): Promise<string> {
1267
+ const lc = `[${getGlobalIndexedDbKey_APIKey.name}]`;
1268
+ try {
1269
+ if (logalot) { console.log(`${lc} starting... (I: 59a2510a85051f97ed15fbc8825b6825)`); }
1270
+ throw new Error(`not implemented (E: 7e05c81caed719f2a6dcf7824e948825)`);
1271
+ } catch (error) {
1272
+ console.error(`${lc} ${extractErrorMsg(error)}`);
1273
+ throw error;
1274
+ } finally {
1275
+ if (logalot) { console.log(`${lc} complete.`); }
1276
+ }
1277
+ }