nastech-app 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1111) hide show
  1. package/.claude/agents/i18n-translator.md +119 -0
  2. package/.claude/settings.json +8 -0
  3. package/.eas/workflows/ota.yaml +9 -0
  4. package/.eas/workflows/preview.yaml +12 -0
  5. package/.easignore +12 -0
  6. package/.github/workflows/eas-build.yml +24 -0
  7. package/CHANGELOG.md +117 -0
  8. package/CLAUDE.md +413 -0
  9. package/GoogleService-Info.plist +30 -0
  10. package/LICENSE +21 -0
  11. package/NasTechapp.md +383 -0
  12. package/README.md +75 -0
  13. package/Stores.md +85 -0
  14. package/TERMS.md +83 -0
  15. package/app.config.js +153 -0
  16. package/babel.config.js +28 -0
  17. package/deploy/nastech-app.yaml +51 -0
  18. package/docs/marketing/README-creators.md +73 -0
  19. package/eas-build-post-install.sh +11 -0
  20. package/eas-build-pre-install.sh +27 -0
  21. package/eas.json +78 -0
  22. package/google-services.json +67 -0
  23. package/index.ts +3 -0
  24. package/logo.png +0 -0
  25. package/metro.config.js +54 -0
  26. package/nativewind-env.d.ts +1 -0
  27. package/package.json +233 -0
  28. package/patches/.keep +0 -0
  29. package/plugins/withEinkCompatibility.js +156 -0
  30. package/public/.well-known/apple-app-site-association +22 -0
  31. package/public/.well-known/assetlinks.json +12 -0
  32. package/public/canvaskit.wasm +0 -0
  33. package/public/favicon-active.ico +0 -0
  34. package/release-dev.sh +7 -0
  35. package/release-production.sh +3 -0
  36. package/release.cjs +160 -0
  37. package/sources/-session/SessionView.tsx +944 -0
  38. package/sources/-session/sessionOverlayNav.ts +34 -0
  39. package/sources/app/(app)/_layout.tsx +321 -0
  40. package/sources/app/(app)/artifacts/[id].tsx +279 -0
  41. package/sources/app/(app)/artifacts/edit/[id].tsx +318 -0
  42. package/sources/app/(app)/artifacts/index.tsx +264 -0
  43. package/sources/app/(app)/artifacts/new.tsx +219 -0
  44. package/sources/app/(app)/changelog.tsx +113 -0
  45. package/sources/app/(app)/dev/colors.tsx +197 -0
  46. package/sources/app/(app)/dev/device-info.tsx +183 -0
  47. package/sources/app/(app)/dev/expo-constants.tsx +394 -0
  48. package/sources/app/(app)/dev/index.tsx +400 -0
  49. package/sources/app/(app)/dev/input-styles.tsx +1951 -0
  50. package/sources/app/(app)/dev/inverted-list.tsx +295 -0
  51. package/sources/app/(app)/dev/list-demo.tsx +125 -0
  52. package/sources/app/(app)/dev/logs.tsx +160 -0
  53. package/sources/app/(app)/dev/messages-demo-data.ts +479 -0
  54. package/sources/app/(app)/dev/messages-demo.tsx +45 -0
  55. package/sources/app/(app)/dev/modal-demo.tsx +211 -0
  56. package/sources/app/(app)/dev/multi-text-input.tsx +224 -0
  57. package/sources/app/(app)/dev/purchases.tsx +228 -0
  58. package/sources/app/(app)/dev/qr-test.tsx +168 -0
  59. package/sources/app/(app)/dev/session-composer.tsx +812 -0
  60. package/sources/app/(app)/dev/shimmer-demo.tsx +275 -0
  61. package/sources/app/(app)/dev/tests.tsx +203 -0
  62. package/sources/app/(app)/dev/tools2.tsx +556 -0
  63. package/sources/app/(app)/dev/typography.tsx +177 -0
  64. package/sources/app/(app)/dev/unistyles-demo.tsx +376 -0
  65. package/sources/app/(app)/friends/index.tsx +167 -0
  66. package/sources/app/(app)/friends/search.tsx +232 -0
  67. package/sources/app/(app)/inbox/index.tsx +124 -0
  68. package/sources/app/(app)/index.tsx +264 -0
  69. package/sources/app/(app)/machine/[id].tsx +646 -0
  70. package/sources/app/(app)/new/index.tsx +1611 -0
  71. package/sources/app/(app)/restore/index.tsx +167 -0
  72. package/sources/app/(app)/restore/manual.tsx +138 -0
  73. package/sources/app/(app)/server.tsx +234 -0
  74. package/sources/app/(app)/session/[id]/file.tsx +527 -0
  75. package/sources/app/(app)/session/[id]/files.tsx +442 -0
  76. package/sources/app/(app)/session/[id]/info.tsx +655 -0
  77. package/sources/app/(app)/session/[id]/message/[messageId].tsx +125 -0
  78. package/sources/app/(app)/session/[id].tsx +10 -0
  79. package/sources/app/(app)/session/recent.tsx +270 -0
  80. package/sources/app/(app)/settings/account.tsx +600 -0
  81. package/sources/app/(app)/settings/agents.tsx +180 -0
  82. package/sources/app/(app)/settings/appearance.tsx +259 -0
  83. package/sources/app/(app)/settings/connect/claude.tsx +178 -0
  84. package/sources/app/(app)/settings/features.tsx +177 -0
  85. package/sources/app/(app)/settings/index.tsx +3 -0
  86. package/sources/app/(app)/settings/language.tsx +106 -0
  87. package/sources/app/(app)/settings/usage.tsx +11 -0
  88. package/sources/app/(app)/settings/voice/language.tsx +114 -0
  89. package/sources/app/(app)/settings/voice.tsx +274 -0
  90. package/sources/app/(app)/terminal/connect.tsx +241 -0
  91. package/sources/app/(app)/terminal/index.tsx +184 -0
  92. package/sources/app/(app)/text-selection.tsx +149 -0
  93. package/sources/app/(app)/user/[id].tsx +314 -0
  94. package/sources/app/+html.tsx +39 -0
  95. package/sources/app/_layout.tsx +402 -0
  96. package/sources/assets/animations/game.json +1 -0
  97. package/sources/assets/animations/owl.json +1 -0
  98. package/sources/assets/animations/popcorn.json +1 -0
  99. package/sources/assets/animations/robot.json +1 -0
  100. package/sources/assets/animations/sparkles.json +1 -0
  101. package/sources/assets/animations/stone.json +1 -0
  102. package/sources/assets/fonts/BricolageGrotesque-Bold.ttf +0 -0
  103. package/sources/assets/fonts/IBMPlexMono-Italic.ttf +0 -0
  104. package/sources/assets/fonts/IBMPlexMono-Regular.ttf +0 -0
  105. package/sources/assets/fonts/IBMPlexMono-SemiBold.ttf +0 -0
  106. package/sources/assets/fonts/IBMPlexSans-Italic.ttf +0 -0
  107. package/sources/assets/fonts/IBMPlexSans-Regular.ttf +0 -0
  108. package/sources/assets/fonts/IBMPlexSans-SemiBold.ttf +0 -0
  109. package/sources/assets/fonts/SpaceMono-Regular.ttf +0 -0
  110. package/sources/assets/images/brutalist/Abstract-1.png +0 -0
  111. package/sources/assets/images/brutalist/Abstract-10.png +0 -0
  112. package/sources/assets/images/brutalist/Abstract-100.png +0 -0
  113. package/sources/assets/images/brutalist/Abstract-101.png +0 -0
  114. package/sources/assets/images/brutalist/Abstract-102.png +0 -0
  115. package/sources/assets/images/brutalist/Abstract-103.png +0 -0
  116. package/sources/assets/images/brutalist/Abstract-104.png +0 -0
  117. package/sources/assets/images/brutalist/Abstract-105.png +0 -0
  118. package/sources/assets/images/brutalist/Abstract-106.png +0 -0
  119. package/sources/assets/images/brutalist/Abstract-107.png +0 -0
  120. package/sources/assets/images/brutalist/Abstract-108.png +0 -0
  121. package/sources/assets/images/brutalist/Abstract-109.png +0 -0
  122. package/sources/assets/images/brutalist/Abstract-11.png +0 -0
  123. package/sources/assets/images/brutalist/Abstract-110.png +0 -0
  124. package/sources/assets/images/brutalist/Abstract-111.png +0 -0
  125. package/sources/assets/images/brutalist/Abstract-112.png +0 -0
  126. package/sources/assets/images/brutalist/Abstract-113.png +0 -0
  127. package/sources/assets/images/brutalist/Abstract-114.png +0 -0
  128. package/sources/assets/images/brutalist/Abstract-115.png +0 -0
  129. package/sources/assets/images/brutalist/Abstract-116.png +0 -0
  130. package/sources/assets/images/brutalist/Abstract-117.png +0 -0
  131. package/sources/assets/images/brutalist/Abstract-118.png +0 -0
  132. package/sources/assets/images/brutalist/Abstract-119.png +0 -0
  133. package/sources/assets/images/brutalist/Abstract-12.png +0 -0
  134. package/sources/assets/images/brutalist/Abstract-120.png +0 -0
  135. package/sources/assets/images/brutalist/Abstract-121.png +0 -0
  136. package/sources/assets/images/brutalist/Abstract-122.png +0 -0
  137. package/sources/assets/images/brutalist/Abstract-123.png +0 -0
  138. package/sources/assets/images/brutalist/Abstract-124.png +0 -0
  139. package/sources/assets/images/brutalist/Abstract-125.png +0 -0
  140. package/sources/assets/images/brutalist/Abstract-126.png +0 -0
  141. package/sources/assets/images/brutalist/Abstract-127.png +0 -0
  142. package/sources/assets/images/brutalist/Abstract-128.png +0 -0
  143. package/sources/assets/images/brutalist/Abstract-129.png +0 -0
  144. package/sources/assets/images/brutalist/Abstract-13.png +0 -0
  145. package/sources/assets/images/brutalist/Abstract-130.png +0 -0
  146. package/sources/assets/images/brutalist/Abstract-131.png +0 -0
  147. package/sources/assets/images/brutalist/Abstract-132.png +0 -0
  148. package/sources/assets/images/brutalist/Abstract-133.png +0 -0
  149. package/sources/assets/images/brutalist/Abstract-134.png +0 -0
  150. package/sources/assets/images/brutalist/Abstract-135.png +0 -0
  151. package/sources/assets/images/brutalist/Abstract-136.png +0 -0
  152. package/sources/assets/images/brutalist/Abstract-137.png +0 -0
  153. package/sources/assets/images/brutalist/Abstract-138.png +0 -0
  154. package/sources/assets/images/brutalist/Abstract-139.png +0 -0
  155. package/sources/assets/images/brutalist/Abstract-14.png +0 -0
  156. package/sources/assets/images/brutalist/Abstract-140.png +0 -0
  157. package/sources/assets/images/brutalist/Abstract-141.png +0 -0
  158. package/sources/assets/images/brutalist/Abstract-142.png +0 -0
  159. package/sources/assets/images/brutalist/Abstract-143.png +0 -0
  160. package/sources/assets/images/brutalist/Abstract-144.png +0 -0
  161. package/sources/assets/images/brutalist/Abstract-145.png +0 -0
  162. package/sources/assets/images/brutalist/Abstract-146.png +0 -0
  163. package/sources/assets/images/brutalist/Abstract-147.png +0 -0
  164. package/sources/assets/images/brutalist/Abstract-148.png +0 -0
  165. package/sources/assets/images/brutalist/Abstract-149.png +0 -0
  166. package/sources/assets/images/brutalist/Abstract-15.png +0 -0
  167. package/sources/assets/images/brutalist/Abstract-150.png +0 -0
  168. package/sources/assets/images/brutalist/Abstract-151.png +0 -0
  169. package/sources/assets/images/brutalist/Abstract-152.png +0 -0
  170. package/sources/assets/images/brutalist/Abstract-153.png +0 -0
  171. package/sources/assets/images/brutalist/Abstract-154.png +0 -0
  172. package/sources/assets/images/brutalist/Abstract-155.png +0 -0
  173. package/sources/assets/images/brutalist/Abstract-156.png +0 -0
  174. package/sources/assets/images/brutalist/Abstract-157.png +0 -0
  175. package/sources/assets/images/brutalist/Abstract-158.png +0 -0
  176. package/sources/assets/images/brutalist/Abstract-159.png +0 -0
  177. package/sources/assets/images/brutalist/Abstract-16.png +0 -0
  178. package/sources/assets/images/brutalist/Abstract-160.png +0 -0
  179. package/sources/assets/images/brutalist/Abstract-161.png +0 -0
  180. package/sources/assets/images/brutalist/Abstract-162.png +0 -0
  181. package/sources/assets/images/brutalist/Abstract-163.png +0 -0
  182. package/sources/assets/images/brutalist/Abstract-164.png +0 -0
  183. package/sources/assets/images/brutalist/Abstract-165.png +0 -0
  184. package/sources/assets/images/brutalist/Abstract-166.png +0 -0
  185. package/sources/assets/images/brutalist/Abstract-167.png +0 -0
  186. package/sources/assets/images/brutalist/Abstract-168.png +0 -0
  187. package/sources/assets/images/brutalist/Abstract-169.png +0 -0
  188. package/sources/assets/images/brutalist/Abstract-17.png +0 -0
  189. package/sources/assets/images/brutalist/Abstract-170.png +0 -0
  190. package/sources/assets/images/brutalist/Abstract-171.png +0 -0
  191. package/sources/assets/images/brutalist/Abstract-172.png +0 -0
  192. package/sources/assets/images/brutalist/Abstract-173.png +0 -0
  193. package/sources/assets/images/brutalist/Abstract-174.png +0 -0
  194. package/sources/assets/images/brutalist/Abstract-175.png +0 -0
  195. package/sources/assets/images/brutalist/Abstract-176.png +0 -0
  196. package/sources/assets/images/brutalist/Abstract-177.png +0 -0
  197. package/sources/assets/images/brutalist/Abstract-178.png +0 -0
  198. package/sources/assets/images/brutalist/Abstract-179.png +0 -0
  199. package/sources/assets/images/brutalist/Abstract-18.png +0 -0
  200. package/sources/assets/images/brutalist/Abstract-180.png +0 -0
  201. package/sources/assets/images/brutalist/Abstract-181.png +0 -0
  202. package/sources/assets/images/brutalist/Abstract-182.png +0 -0
  203. package/sources/assets/images/brutalist/Abstract-183.png +0 -0
  204. package/sources/assets/images/brutalist/Abstract-184.png +0 -0
  205. package/sources/assets/images/brutalist/Abstract-185.png +0 -0
  206. package/sources/assets/images/brutalist/Abstract-186.png +0 -0
  207. package/sources/assets/images/brutalist/Abstract-187.png +0 -0
  208. package/sources/assets/images/brutalist/Abstract-188.png +0 -0
  209. package/sources/assets/images/brutalist/Abstract-189.png +0 -0
  210. package/sources/assets/images/brutalist/Abstract-19.png +0 -0
  211. package/sources/assets/images/brutalist/Abstract-190.png +0 -0
  212. package/sources/assets/images/brutalist/Abstract-191.png +0 -0
  213. package/sources/assets/images/brutalist/Abstract-192.png +0 -0
  214. package/sources/assets/images/brutalist/Abstract-193.png +0 -0
  215. package/sources/assets/images/brutalist/Abstract-194.png +0 -0
  216. package/sources/assets/images/brutalist/Abstract-195.png +0 -0
  217. package/sources/assets/images/brutalist/Abstract-196.png +0 -0
  218. package/sources/assets/images/brutalist/Abstract-197.png +0 -0
  219. package/sources/assets/images/brutalist/Abstract-198.png +0 -0
  220. package/sources/assets/images/brutalist/Abstract-199.png +0 -0
  221. package/sources/assets/images/brutalist/Abstract-2.png +0 -0
  222. package/sources/assets/images/brutalist/Abstract-20.png +0 -0
  223. package/sources/assets/images/brutalist/Abstract-200.png +0 -0
  224. package/sources/assets/images/brutalist/Abstract-201.png +0 -0
  225. package/sources/assets/images/brutalist/Abstract-202.png +0 -0
  226. package/sources/assets/images/brutalist/Abstract-203.png +0 -0
  227. package/sources/assets/images/brutalist/Abstract-204.png +0 -0
  228. package/sources/assets/images/brutalist/Abstract-205.png +0 -0
  229. package/sources/assets/images/brutalist/Abstract-206.png +0 -0
  230. package/sources/assets/images/brutalist/Abstract-207.png +0 -0
  231. package/sources/assets/images/brutalist/Abstract-208.png +0 -0
  232. package/sources/assets/images/brutalist/Abstract-209.png +0 -0
  233. package/sources/assets/images/brutalist/Abstract-21.png +0 -0
  234. package/sources/assets/images/brutalist/Abstract-210.png +0 -0
  235. package/sources/assets/images/brutalist/Abstract-211.png +0 -0
  236. package/sources/assets/images/brutalist/Abstract-212.png +0 -0
  237. package/sources/assets/images/brutalist/Abstract-213.png +0 -0
  238. package/sources/assets/images/brutalist/Abstract-214.png +0 -0
  239. package/sources/assets/images/brutalist/Abstract-215.png +0 -0
  240. package/sources/assets/images/brutalist/Abstract-216.png +0 -0
  241. package/sources/assets/images/brutalist/Abstract-217.png +0 -0
  242. package/sources/assets/images/brutalist/Abstract-218.png +0 -0
  243. package/sources/assets/images/brutalist/Abstract-219.png +0 -0
  244. package/sources/assets/images/brutalist/Abstract-22.png +0 -0
  245. package/sources/assets/images/brutalist/Abstract-220.png +0 -0
  246. package/sources/assets/images/brutalist/Abstract-221.png +0 -0
  247. package/sources/assets/images/brutalist/Abstract-222.png +0 -0
  248. package/sources/assets/images/brutalist/Abstract-223.png +0 -0
  249. package/sources/assets/images/brutalist/Abstract-224.png +0 -0
  250. package/sources/assets/images/brutalist/Abstract-225.png +0 -0
  251. package/sources/assets/images/brutalist/Abstract-226.png +0 -0
  252. package/sources/assets/images/brutalist/Abstract-227.png +0 -0
  253. package/sources/assets/images/brutalist/Abstract-228.png +0 -0
  254. package/sources/assets/images/brutalist/Abstract-229.png +0 -0
  255. package/sources/assets/images/brutalist/Abstract-23.png +0 -0
  256. package/sources/assets/images/brutalist/Abstract-230.png +0 -0
  257. package/sources/assets/images/brutalist/Abstract-231.png +0 -0
  258. package/sources/assets/images/brutalist/Abstract-232.png +0 -0
  259. package/sources/assets/images/brutalist/Abstract-233.png +0 -0
  260. package/sources/assets/images/brutalist/Abstract-234.png +0 -0
  261. package/sources/assets/images/brutalist/Abstract-235.png +0 -0
  262. package/sources/assets/images/brutalist/Abstract-236.png +0 -0
  263. package/sources/assets/images/brutalist/Abstract-237.png +0 -0
  264. package/sources/assets/images/brutalist/Abstract-238.png +0 -0
  265. package/sources/assets/images/brutalist/Abstract-239.png +0 -0
  266. package/sources/assets/images/brutalist/Abstract-24.png +0 -0
  267. package/sources/assets/images/brutalist/Abstract-240.png +0 -0
  268. package/sources/assets/images/brutalist/Abstract-241.png +0 -0
  269. package/sources/assets/images/brutalist/Abstract-242.png +0 -0
  270. package/sources/assets/images/brutalist/Abstract-243.png +0 -0
  271. package/sources/assets/images/brutalist/Abstract-244.png +0 -0
  272. package/sources/assets/images/brutalist/Abstract-245.png +0 -0
  273. package/sources/assets/images/brutalist/Abstract-246.png +0 -0
  274. package/sources/assets/images/brutalist/Abstract-247.png +0 -0
  275. package/sources/assets/images/brutalist/Abstract-248.png +0 -0
  276. package/sources/assets/images/brutalist/Abstract-249.png +0 -0
  277. package/sources/assets/images/brutalist/Abstract-25.png +0 -0
  278. package/sources/assets/images/brutalist/Abstract-250.png +0 -0
  279. package/sources/assets/images/brutalist/Abstract-251.png +0 -0
  280. package/sources/assets/images/brutalist/Abstract-252.png +0 -0
  281. package/sources/assets/images/brutalist/Abstract-253.png +0 -0
  282. package/sources/assets/images/brutalist/Abstract-254.png +0 -0
  283. package/sources/assets/images/brutalist/Abstract-255.png +0 -0
  284. package/sources/assets/images/brutalist/Abstract-256.png +0 -0
  285. package/sources/assets/images/brutalist/Abstract-257.png +0 -0
  286. package/sources/assets/images/brutalist/Abstract-258.png +0 -0
  287. package/sources/assets/images/brutalist/Abstract-259.png +0 -0
  288. package/sources/assets/images/brutalist/Abstract-26.png +0 -0
  289. package/sources/assets/images/brutalist/Abstract-260.png +0 -0
  290. package/sources/assets/images/brutalist/Abstract-261.png +0 -0
  291. package/sources/assets/images/brutalist/Abstract-262.png +0 -0
  292. package/sources/assets/images/brutalist/Abstract-27.png +0 -0
  293. package/sources/assets/images/brutalist/Abstract-28.png +0 -0
  294. package/sources/assets/images/brutalist/Abstract-29.png +0 -0
  295. package/sources/assets/images/brutalist/Abstract-3.png +0 -0
  296. package/sources/assets/images/brutalist/Abstract-30.png +0 -0
  297. package/sources/assets/images/brutalist/Abstract-31.png +0 -0
  298. package/sources/assets/images/brutalist/Abstract-32.png +0 -0
  299. package/sources/assets/images/brutalist/Abstract-33.png +0 -0
  300. package/sources/assets/images/brutalist/Abstract-34.png +0 -0
  301. package/sources/assets/images/brutalist/Abstract-35.png +0 -0
  302. package/sources/assets/images/brutalist/Abstract-36.png +0 -0
  303. package/sources/assets/images/brutalist/Abstract-37.png +0 -0
  304. package/sources/assets/images/brutalist/Abstract-38.png +0 -0
  305. package/sources/assets/images/brutalist/Abstract-39.png +0 -0
  306. package/sources/assets/images/brutalist/Abstract-4.png +0 -0
  307. package/sources/assets/images/brutalist/Abstract-40.png +0 -0
  308. package/sources/assets/images/brutalist/Abstract-41.png +0 -0
  309. package/sources/assets/images/brutalist/Abstract-42.png +0 -0
  310. package/sources/assets/images/brutalist/Abstract-43.png +0 -0
  311. package/sources/assets/images/brutalist/Abstract-44.png +0 -0
  312. package/sources/assets/images/brutalist/Abstract-45.png +0 -0
  313. package/sources/assets/images/brutalist/Abstract-46.png +0 -0
  314. package/sources/assets/images/brutalist/Abstract-47.png +0 -0
  315. package/sources/assets/images/brutalist/Abstract-48.png +0 -0
  316. package/sources/assets/images/brutalist/Abstract-49.png +0 -0
  317. package/sources/assets/images/brutalist/Abstract-5.png +0 -0
  318. package/sources/assets/images/brutalist/Abstract-50.png +0 -0
  319. package/sources/assets/images/brutalist/Abstract-51.png +0 -0
  320. package/sources/assets/images/brutalist/Abstract-52.png +0 -0
  321. package/sources/assets/images/brutalist/Abstract-53.png +0 -0
  322. package/sources/assets/images/brutalist/Abstract-54.png +0 -0
  323. package/sources/assets/images/brutalist/Abstract-55.png +0 -0
  324. package/sources/assets/images/brutalist/Abstract-56.png +0 -0
  325. package/sources/assets/images/brutalist/Abstract-57.png +0 -0
  326. package/sources/assets/images/brutalist/Abstract-58.png +0 -0
  327. package/sources/assets/images/brutalist/Abstract-59.png +0 -0
  328. package/sources/assets/images/brutalist/Abstract-6.png +0 -0
  329. package/sources/assets/images/brutalist/Abstract-60.png +0 -0
  330. package/sources/assets/images/brutalist/Abstract-61.png +0 -0
  331. package/sources/assets/images/brutalist/Abstract-62.png +0 -0
  332. package/sources/assets/images/brutalist/Abstract-63.png +0 -0
  333. package/sources/assets/images/brutalist/Abstract-64.png +0 -0
  334. package/sources/assets/images/brutalist/Abstract-65.png +0 -0
  335. package/sources/assets/images/brutalist/Abstract-66.png +0 -0
  336. package/sources/assets/images/brutalist/Abstract-67.png +0 -0
  337. package/sources/assets/images/brutalist/Abstract-68.png +0 -0
  338. package/sources/assets/images/brutalist/Abstract-69.png +0 -0
  339. package/sources/assets/images/brutalist/Abstract-7.png +0 -0
  340. package/sources/assets/images/brutalist/Abstract-70.png +0 -0
  341. package/sources/assets/images/brutalist/Abstract-71.png +0 -0
  342. package/sources/assets/images/brutalist/Abstract-72.png +0 -0
  343. package/sources/assets/images/brutalist/Abstract-73.png +0 -0
  344. package/sources/assets/images/brutalist/Abstract-74.png +0 -0
  345. package/sources/assets/images/brutalist/Abstract-75.png +0 -0
  346. package/sources/assets/images/brutalist/Abstract-76.png +0 -0
  347. package/sources/assets/images/brutalist/Abstract-77.png +0 -0
  348. package/sources/assets/images/brutalist/Abstract-78.png +0 -0
  349. package/sources/assets/images/brutalist/Abstract-79.png +0 -0
  350. package/sources/assets/images/brutalist/Abstract-8.png +0 -0
  351. package/sources/assets/images/brutalist/Abstract-80.png +0 -0
  352. package/sources/assets/images/brutalist/Abstract-81.png +0 -0
  353. package/sources/assets/images/brutalist/Abstract-82.png +0 -0
  354. package/sources/assets/images/brutalist/Abstract-83.png +0 -0
  355. package/sources/assets/images/brutalist/Abstract-84.png +0 -0
  356. package/sources/assets/images/brutalist/Abstract-85.png +0 -0
  357. package/sources/assets/images/brutalist/Abstract-86.png +0 -0
  358. package/sources/assets/images/brutalist/Abstract-87.png +0 -0
  359. package/sources/assets/images/brutalist/Abstract-88.png +0 -0
  360. package/sources/assets/images/brutalist/Abstract-89.png +0 -0
  361. package/sources/assets/images/brutalist/Abstract-9.png +0 -0
  362. package/sources/assets/images/brutalist/Abstract-90.png +0 -0
  363. package/sources/assets/images/brutalist/Abstract-91.png +0 -0
  364. package/sources/assets/images/brutalist/Abstract-92.png +0 -0
  365. package/sources/assets/images/brutalist/Abstract-93.png +0 -0
  366. package/sources/assets/images/brutalist/Abstract-94.png +0 -0
  367. package/sources/assets/images/brutalist/Abstract-95.png +0 -0
  368. package/sources/assets/images/brutalist/Abstract-96.png +0 -0
  369. package/sources/assets/images/brutalist/Abstract-97.png +0 -0
  370. package/sources/assets/images/brutalist/Abstract-98.png +0 -0
  371. package/sources/assets/images/brutalist/Abstract-99.png +0 -0
  372. package/sources/assets/images/brutalist/Bauhaus-1.png +0 -0
  373. package/sources/assets/images/brutalist/Bauhaus-10.png +0 -0
  374. package/sources/assets/images/brutalist/Bauhaus-11.png +0 -0
  375. package/sources/assets/images/brutalist/Bauhaus-12.png +0 -0
  376. package/sources/assets/images/brutalist/Bauhaus-13.png +0 -0
  377. package/sources/assets/images/brutalist/Bauhaus-14.png +0 -0
  378. package/sources/assets/images/brutalist/Bauhaus-15.png +0 -0
  379. package/sources/assets/images/brutalist/Bauhaus-16.png +0 -0
  380. package/sources/assets/images/brutalist/Bauhaus-17.png +0 -0
  381. package/sources/assets/images/brutalist/Bauhaus-18.png +0 -0
  382. package/sources/assets/images/brutalist/Bauhaus-19.png +0 -0
  383. package/sources/assets/images/brutalist/Bauhaus-2.png +0 -0
  384. package/sources/assets/images/brutalist/Bauhaus-20.png +0 -0
  385. package/sources/assets/images/brutalist/Bauhaus-21.png +0 -0
  386. package/sources/assets/images/brutalist/Bauhaus-22.png +0 -0
  387. package/sources/assets/images/brutalist/Bauhaus-23.png +0 -0
  388. package/sources/assets/images/brutalist/Bauhaus-24.png +0 -0
  389. package/sources/assets/images/brutalist/Bauhaus-25.png +0 -0
  390. package/sources/assets/images/brutalist/Bauhaus-26.png +0 -0
  391. package/sources/assets/images/brutalist/Bauhaus-27.png +0 -0
  392. package/sources/assets/images/brutalist/Bauhaus-28.png +0 -0
  393. package/sources/assets/images/brutalist/Bauhaus-29.png +0 -0
  394. package/sources/assets/images/brutalist/Bauhaus-3.png +0 -0
  395. package/sources/assets/images/brutalist/Bauhaus-30.png +0 -0
  396. package/sources/assets/images/brutalist/Bauhaus-31.png +0 -0
  397. package/sources/assets/images/brutalist/Bauhaus-32.png +0 -0
  398. package/sources/assets/images/brutalist/Bauhaus-33.png +0 -0
  399. package/sources/assets/images/brutalist/Bauhaus-34.png +0 -0
  400. package/sources/assets/images/brutalist/Bauhaus-35.png +0 -0
  401. package/sources/assets/images/brutalist/Bauhaus-36.png +0 -0
  402. package/sources/assets/images/brutalist/Bauhaus-37.png +0 -0
  403. package/sources/assets/images/brutalist/Bauhaus-38.png +0 -0
  404. package/sources/assets/images/brutalist/Bauhaus-39.png +0 -0
  405. package/sources/assets/images/brutalist/Bauhaus-4.png +0 -0
  406. package/sources/assets/images/brutalist/Bauhaus-40.png +0 -0
  407. package/sources/assets/images/brutalist/Bauhaus-5.png +0 -0
  408. package/sources/assets/images/brutalist/Bauhaus-6.png +0 -0
  409. package/sources/assets/images/brutalist/Bauhaus-7.png +0 -0
  410. package/sources/assets/images/brutalist/Bauhaus-8.png +0 -0
  411. package/sources/assets/images/brutalist/Bauhaus-9.png +0 -0
  412. package/sources/assets/images/brutalist/Brutalism-1.png +0 -0
  413. package/sources/assets/images/brutalist/Brutalism-10.png +0 -0
  414. package/sources/assets/images/brutalist/Brutalism-100.png +0 -0
  415. package/sources/assets/images/brutalist/Brutalism-101.png +0 -0
  416. package/sources/assets/images/brutalist/Brutalism-102.png +0 -0
  417. package/sources/assets/images/brutalist/Brutalism-103.png +0 -0
  418. package/sources/assets/images/brutalist/Brutalism-104.png +0 -0
  419. package/sources/assets/images/brutalist/Brutalism-105.png +0 -0
  420. package/sources/assets/images/brutalist/Brutalism-106.png +0 -0
  421. package/sources/assets/images/brutalist/Brutalism-107.png +0 -0
  422. package/sources/assets/images/brutalist/Brutalism-108.png +0 -0
  423. package/sources/assets/images/brutalist/Brutalism-109.png +0 -0
  424. package/sources/assets/images/brutalist/Brutalism-11.png +0 -0
  425. package/sources/assets/images/brutalist/Brutalism-110.png +0 -0
  426. package/sources/assets/images/brutalist/Brutalism-111.png +0 -0
  427. package/sources/assets/images/brutalist/Brutalism-112.png +0 -0
  428. package/sources/assets/images/brutalist/Brutalism-113.png +0 -0
  429. package/sources/assets/images/brutalist/Brutalism-114.png +0 -0
  430. package/sources/assets/images/brutalist/Brutalism-115.png +0 -0
  431. package/sources/assets/images/brutalist/Brutalism-116.png +0 -0
  432. package/sources/assets/images/brutalist/Brutalism-117.png +0 -0
  433. package/sources/assets/images/brutalist/Brutalism-118.png +0 -0
  434. package/sources/assets/images/brutalist/Brutalism-12.png +0 -0
  435. package/sources/assets/images/brutalist/Brutalism-13.png +0 -0
  436. package/sources/assets/images/brutalist/Brutalism-14.png +0 -0
  437. package/sources/assets/images/brutalist/Brutalism-15.png +0 -0
  438. package/sources/assets/images/brutalist/Brutalism-16.png +0 -0
  439. package/sources/assets/images/brutalist/Brutalism-17.png +0 -0
  440. package/sources/assets/images/brutalist/Brutalism-18.png +0 -0
  441. package/sources/assets/images/brutalist/Brutalism-19.png +0 -0
  442. package/sources/assets/images/brutalist/Brutalism-2.png +0 -0
  443. package/sources/assets/images/brutalist/Brutalism-20.png +0 -0
  444. package/sources/assets/images/brutalist/Brutalism-21.png +0 -0
  445. package/sources/assets/images/brutalist/Brutalism-22.png +0 -0
  446. package/sources/assets/images/brutalist/Brutalism-23.png +0 -0
  447. package/sources/assets/images/brutalist/Brutalism-24.png +0 -0
  448. package/sources/assets/images/brutalist/Brutalism-25.png +0 -0
  449. package/sources/assets/images/brutalist/Brutalism-26.png +0 -0
  450. package/sources/assets/images/brutalist/Brutalism-27.png +0 -0
  451. package/sources/assets/images/brutalist/Brutalism-28.png +0 -0
  452. package/sources/assets/images/brutalist/Brutalism-29.png +0 -0
  453. package/sources/assets/images/brutalist/Brutalism-3.png +0 -0
  454. package/sources/assets/images/brutalist/Brutalism-30.png +0 -0
  455. package/sources/assets/images/brutalist/Brutalism-31.png +0 -0
  456. package/sources/assets/images/brutalist/Brutalism-32.png +0 -0
  457. package/sources/assets/images/brutalist/Brutalism-33.png +0 -0
  458. package/sources/assets/images/brutalist/Brutalism-34.png +0 -0
  459. package/sources/assets/images/brutalist/Brutalism-35.png +0 -0
  460. package/sources/assets/images/brutalist/Brutalism-36.png +0 -0
  461. package/sources/assets/images/brutalist/Brutalism-37.png +0 -0
  462. package/sources/assets/images/brutalist/Brutalism-38.png +0 -0
  463. package/sources/assets/images/brutalist/Brutalism-39.png +0 -0
  464. package/sources/assets/images/brutalist/Brutalism-4.png +0 -0
  465. package/sources/assets/images/brutalist/Brutalism-40.png +0 -0
  466. package/sources/assets/images/brutalist/Brutalism-41.png +0 -0
  467. package/sources/assets/images/brutalist/Brutalism-42.png +0 -0
  468. package/sources/assets/images/brutalist/Brutalism-43.png +0 -0
  469. package/sources/assets/images/brutalist/Brutalism-44.png +0 -0
  470. package/sources/assets/images/brutalist/Brutalism-45.png +0 -0
  471. package/sources/assets/images/brutalist/Brutalism-46.png +0 -0
  472. package/sources/assets/images/brutalist/Brutalism-47.png +0 -0
  473. package/sources/assets/images/brutalist/Brutalism-48.png +0 -0
  474. package/sources/assets/images/brutalist/Brutalism-49.png +0 -0
  475. package/sources/assets/images/brutalist/Brutalism-5.png +0 -0
  476. package/sources/assets/images/brutalist/Brutalism-50.png +0 -0
  477. package/sources/assets/images/brutalist/Brutalism-51.png +0 -0
  478. package/sources/assets/images/brutalist/Brutalism-52.png +0 -0
  479. package/sources/assets/images/brutalist/Brutalism-53.png +0 -0
  480. package/sources/assets/images/brutalist/Brutalism-54.png +0 -0
  481. package/sources/assets/images/brutalist/Brutalism-55.png +0 -0
  482. package/sources/assets/images/brutalist/Brutalism-56.png +0 -0
  483. package/sources/assets/images/brutalist/Brutalism-57.png +0 -0
  484. package/sources/assets/images/brutalist/Brutalism-58.png +0 -0
  485. package/sources/assets/images/brutalist/Brutalism-59.png +0 -0
  486. package/sources/assets/images/brutalist/Brutalism-6.png +0 -0
  487. package/sources/assets/images/brutalist/Brutalism-60.png +0 -0
  488. package/sources/assets/images/brutalist/Brutalism-61.png +0 -0
  489. package/sources/assets/images/brutalist/Brutalism-62.png +0 -0
  490. package/sources/assets/images/brutalist/Brutalism-63.png +0 -0
  491. package/sources/assets/images/brutalist/Brutalism-64.png +0 -0
  492. package/sources/assets/images/brutalist/Brutalism-65.png +0 -0
  493. package/sources/assets/images/brutalist/Brutalism-66.png +0 -0
  494. package/sources/assets/images/brutalist/Brutalism-67.png +0 -0
  495. package/sources/assets/images/brutalist/Brutalism-68.png +0 -0
  496. package/sources/assets/images/brutalist/Brutalism-69.png +0 -0
  497. package/sources/assets/images/brutalist/Brutalism-7.png +0 -0
  498. package/sources/assets/images/brutalist/Brutalism-70.png +0 -0
  499. package/sources/assets/images/brutalist/Brutalism-71.png +0 -0
  500. package/sources/assets/images/brutalist/Brutalism-72.png +0 -0
  501. package/sources/assets/images/brutalist/Brutalism-73.png +0 -0
  502. package/sources/assets/images/brutalist/Brutalism-74.png +0 -0
  503. package/sources/assets/images/brutalist/Brutalism-75.png +0 -0
  504. package/sources/assets/images/brutalist/Brutalism-76.png +0 -0
  505. package/sources/assets/images/brutalist/Brutalism-77.png +0 -0
  506. package/sources/assets/images/brutalist/Brutalism-78.png +0 -0
  507. package/sources/assets/images/brutalist/Brutalism-79.png +0 -0
  508. package/sources/assets/images/brutalist/Brutalism-8.png +0 -0
  509. package/sources/assets/images/brutalist/Brutalism-80.png +0 -0
  510. package/sources/assets/images/brutalist/Brutalism-81.png +0 -0
  511. package/sources/assets/images/brutalist/Brutalism-82.png +0 -0
  512. package/sources/assets/images/brutalist/Brutalism-83.png +0 -0
  513. package/sources/assets/images/brutalist/Brutalism-84.png +0 -0
  514. package/sources/assets/images/brutalist/Brutalism-85.png +0 -0
  515. package/sources/assets/images/brutalist/Brutalism-86.png +0 -0
  516. package/sources/assets/images/brutalist/Brutalism-87.png +0 -0
  517. package/sources/assets/images/brutalist/Brutalism-88.png +0 -0
  518. package/sources/assets/images/brutalist/Brutalism-89.png +0 -0
  519. package/sources/assets/images/brutalist/Brutalism-9.png +0 -0
  520. package/sources/assets/images/brutalist/Brutalism-90.png +0 -0
  521. package/sources/assets/images/brutalist/Brutalism-91.png +0 -0
  522. package/sources/assets/images/brutalist/Brutalism-92.png +0 -0
  523. package/sources/assets/images/brutalist/Brutalism-93.png +0 -0
  524. package/sources/assets/images/brutalist/Brutalism-94.png +0 -0
  525. package/sources/assets/images/brutalist/Brutalism-95.png +0 -0
  526. package/sources/assets/images/brutalist/Brutalism-96.png +0 -0
  527. package/sources/assets/images/brutalist/Brutalism-97.png +0 -0
  528. package/sources/assets/images/brutalist/Brutalism-98.png +0 -0
  529. package/sources/assets/images/brutalist/Brutalism-99.png +0 -0
  530. package/sources/assets/images/favicon-active.png +0 -0
  531. package/sources/assets/images/favicon.png +0 -0
  532. package/sources/assets/images/gradients/01.png +0 -0
  533. package/sources/assets/images/gradients/02.png +0 -0
  534. package/sources/assets/images/gradients/03.png +0 -0
  535. package/sources/assets/images/gradients/04.png +0 -0
  536. package/sources/assets/images/gradients/05.png +0 -0
  537. package/sources/assets/images/gradients/06.png +0 -0
  538. package/sources/assets/images/gradients/07.png +0 -0
  539. package/sources/assets/images/gradients/08.png +0 -0
  540. package/sources/assets/images/gradients/09.png +0 -0
  541. package/sources/assets/images/gradients/10.png +0 -0
  542. package/sources/assets/images/gradients/100.png +0 -0
  543. package/sources/assets/images/gradients/11.png +0 -0
  544. package/sources/assets/images/gradients/12.png +0 -0
  545. package/sources/assets/images/gradients/13.png +0 -0
  546. package/sources/assets/images/gradients/14.png +0 -0
  547. package/sources/assets/images/gradients/15.png +0 -0
  548. package/sources/assets/images/gradients/16.png +0 -0
  549. package/sources/assets/images/gradients/17.png +0 -0
  550. package/sources/assets/images/gradients/18.png +0 -0
  551. package/sources/assets/images/gradients/19.png +0 -0
  552. package/sources/assets/images/gradients/20.png +0 -0
  553. package/sources/assets/images/gradients/21.png +0 -0
  554. package/sources/assets/images/gradients/22.png +0 -0
  555. package/sources/assets/images/gradients/23.png +0 -0
  556. package/sources/assets/images/gradients/24.png +0 -0
  557. package/sources/assets/images/gradients/25.png +0 -0
  558. package/sources/assets/images/gradients/26.png +0 -0
  559. package/sources/assets/images/gradients/27.png +0 -0
  560. package/sources/assets/images/gradients/28.png +0 -0
  561. package/sources/assets/images/gradients/29.png +0 -0
  562. package/sources/assets/images/gradients/30.png +0 -0
  563. package/sources/assets/images/gradients/31.png +0 -0
  564. package/sources/assets/images/gradients/32.png +0 -0
  565. package/sources/assets/images/gradients/33.png +0 -0
  566. package/sources/assets/images/gradients/34.png +0 -0
  567. package/sources/assets/images/gradients/35.png +0 -0
  568. package/sources/assets/images/gradients/36.png +0 -0
  569. package/sources/assets/images/gradients/37.png +0 -0
  570. package/sources/assets/images/gradients/38.png +0 -0
  571. package/sources/assets/images/gradients/39.png +0 -0
  572. package/sources/assets/images/gradients/40.png +0 -0
  573. package/sources/assets/images/gradients/41.png +0 -0
  574. package/sources/assets/images/gradients/42.png +0 -0
  575. package/sources/assets/images/gradients/43.png +0 -0
  576. package/sources/assets/images/gradients/44.png +0 -0
  577. package/sources/assets/images/gradients/45.png +0 -0
  578. package/sources/assets/images/gradients/46.png +0 -0
  579. package/sources/assets/images/gradients/47.png +0 -0
  580. package/sources/assets/images/gradients/48.png +0 -0
  581. package/sources/assets/images/gradients/49.png +0 -0
  582. package/sources/assets/images/gradients/50.png +0 -0
  583. package/sources/assets/images/gradients/51.png +0 -0
  584. package/sources/assets/images/gradients/52.png +0 -0
  585. package/sources/assets/images/gradients/53.png +0 -0
  586. package/sources/assets/images/gradients/54.png +0 -0
  587. package/sources/assets/images/gradients/55.png +0 -0
  588. package/sources/assets/images/gradients/56.png +0 -0
  589. package/sources/assets/images/gradients/57.png +0 -0
  590. package/sources/assets/images/gradients/58.png +0 -0
  591. package/sources/assets/images/gradients/59.png +0 -0
  592. package/sources/assets/images/gradients/60.png +0 -0
  593. package/sources/assets/images/gradients/61.png +0 -0
  594. package/sources/assets/images/gradients/62.png +0 -0
  595. package/sources/assets/images/gradients/63.png +0 -0
  596. package/sources/assets/images/gradients/64.png +0 -0
  597. package/sources/assets/images/gradients/65.png +0 -0
  598. package/sources/assets/images/gradients/66.png +0 -0
  599. package/sources/assets/images/gradients/67.png +0 -0
  600. package/sources/assets/images/gradients/68.png +0 -0
  601. package/sources/assets/images/gradients/69.png +0 -0
  602. package/sources/assets/images/gradients/70.png +0 -0
  603. package/sources/assets/images/gradients/71.png +0 -0
  604. package/sources/assets/images/gradients/72.png +0 -0
  605. package/sources/assets/images/gradients/73.png +0 -0
  606. package/sources/assets/images/gradients/74.png +0 -0
  607. package/sources/assets/images/gradients/75.png +0 -0
  608. package/sources/assets/images/gradients/76.png +0 -0
  609. package/sources/assets/images/gradients/77.png +0 -0
  610. package/sources/assets/images/gradients/78.png +0 -0
  611. package/sources/assets/images/gradients/79.png +0 -0
  612. package/sources/assets/images/gradients/80.png +0 -0
  613. package/sources/assets/images/gradients/81.png +0 -0
  614. package/sources/assets/images/gradients/82.png +0 -0
  615. package/sources/assets/images/gradients/83.png +0 -0
  616. package/sources/assets/images/gradients/84.png +0 -0
  617. package/sources/assets/images/gradients/85.png +0 -0
  618. package/sources/assets/images/gradients/86.png +0 -0
  619. package/sources/assets/images/gradients/87.png +0 -0
  620. package/sources/assets/images/gradients/88.png +0 -0
  621. package/sources/assets/images/gradients/89.png +0 -0
  622. package/sources/assets/images/gradients/90.png +0 -0
  623. package/sources/assets/images/gradients/91.png +0 -0
  624. package/sources/assets/images/gradients/92.png +0 -0
  625. package/sources/assets/images/gradients/93.png +0 -0
  626. package/sources/assets/images/gradients/94.png +0 -0
  627. package/sources/assets/images/gradients/95.png +0 -0
  628. package/sources/assets/images/gradients/96.png +0 -0
  629. package/sources/assets/images/gradients/97.png +0 -0
  630. package/sources/assets/images/gradients/98.png +0 -0
  631. package/sources/assets/images/gradients/99.png +0 -0
  632. package/sources/assets/images/icon-adaptive.png +0 -0
  633. package/sources/assets/images/icon-claude.png +0 -0
  634. package/sources/assets/images/icon-claude@2x.png +0 -0
  635. package/sources/assets/images/icon-claude@3x.png +0 -0
  636. package/sources/assets/images/icon-gemini.png +0 -0
  637. package/sources/assets/images/icon-gemini@2x.png +0 -0
  638. package/sources/assets/images/icon-gemini@3x.png +0 -0
  639. package/sources/assets/images/icon-gpt.png +0 -0
  640. package/sources/assets/images/icon-gpt@2x.png +0 -0
  641. package/sources/assets/images/icon-gpt@3x.png +0 -0
  642. package/sources/assets/images/icon-monochrome.png +0 -0
  643. package/sources/assets/images/icon-notification.png +0 -0
  644. package/sources/assets/images/icon-openclaw.png +0 -0
  645. package/sources/assets/images/icon-openclaw@2x.png +0 -0
  646. package/sources/assets/images/icon-openclaw@3x.png +0 -0
  647. package/sources/assets/images/icon-tauri.png +0 -0
  648. package/sources/assets/images/icon-voice-white.png +0 -0
  649. package/sources/assets/images/icon-voice.png +0 -0
  650. package/sources/assets/images/icon-voice@2x.png +0 -0
  651. package/sources/assets/images/icon-voice@3x.png +0 -0
  652. package/sources/assets/images/icon.png +0 -0
  653. package/sources/assets/images/logo-black.png +0 -0
  654. package/sources/assets/images/logo-white.png +0 -0
  655. package/sources/assets/images/logotype-dark.png +0 -0
  656. package/sources/assets/images/logotype-dark@2x.png +0 -0
  657. package/sources/assets/images/logotype-dark@3x.png +0 -0
  658. package/sources/assets/images/logotype-light.png +0 -0
  659. package/sources/assets/images/logotype-light@2x.png +0 -0
  660. package/sources/assets/images/logotype-light@3x.png +0 -0
  661. package/sources/assets/images/logotype.png +0 -0
  662. package/sources/assets/images/logotype@2x.png +0 -0
  663. package/sources/assets/images/logotype@3x.png +0 -0
  664. package/sources/assets/images/splash-android-dark.png +0 -0
  665. package/sources/assets/images/splash-android-light.png +0 -0
  666. package/sources/assets/images/transparent.png +0 -0
  667. package/sources/assets/images/zen-icon.png +0 -0
  668. package/sources/auth/AuthContext.tsx +100 -0
  669. package/sources/auth/authAccountApprove.ts +2 -0
  670. package/sources/auth/authApprove.ts +2 -0
  671. package/sources/auth/authChallenge.ts +8 -0
  672. package/sources/auth/authGetToken.ts +4 -0
  673. package/sources/auth/authQRStart.ts +17 -0
  674. package/sources/auth/authQRWait.ts +13 -0
  675. package/sources/auth/secretKeyBackup.spec.ts +465 -0
  676. package/sources/auth/secretKeyBackup.ts +179 -0
  677. package/sources/auth/tokenStorage.ts +27 -0
  678. package/sources/changelog/changelog.json +60 -0
  679. package/sources/changelog/index.ts +3 -0
  680. package/sources/changelog/parser.ts +23 -0
  681. package/sources/changelog/storage.ts +17 -0
  682. package/sources/changelog/types.ts +10 -0
  683. package/sources/components/ActiveSessionsGroupCompact.tsx +567 -0
  684. package/sources/components/AgentContentView.ios.tsx +70 -0
  685. package/sources/components/AgentContentView.tsx +48 -0
  686. package/sources/components/AgentInput.tsx +1468 -0
  687. package/sources/components/AgentInputAttachmentStrip.tsx +122 -0
  688. package/sources/components/AgentInputAutocomplete.tsx +96 -0
  689. package/sources/components/AgentInputSuggestionView.tsx +106 -0
  690. package/sources/components/AllFilesDiffView.tsx +515 -0
  691. package/sources/components/Avatar.tsx +149 -0
  692. package/sources/components/AvatarBrutalist.tsx +501 -0
  693. package/sources/components/AvatarGradient.tsx +147 -0
  694. package/sources/components/AvatarSkia.tsx +111 -0
  695. package/sources/components/AvatarSkia.web.tsx +113 -0
  696. package/sources/components/ChatFooter.tsx +50 -0
  697. package/sources/components/ChatHeaderView.tsx +180 -0
  698. package/sources/components/ChatList.tsx +283 -0
  699. package/sources/components/CodeEditor.tsx +22 -0
  700. package/sources/components/CodeEditor.web.tsx +180 -0
  701. package/sources/components/CodeView.tsx +33 -0
  702. package/sources/components/CommandPalette/CommandPalette.tsx +72 -0
  703. package/sources/components/CommandPalette/CommandPaletteInput.tsx +65 -0
  704. package/sources/components/CommandPalette/CommandPaletteItem.tsx +141 -0
  705. package/sources/components/CommandPalette/CommandPaletteModal.tsx +148 -0
  706. package/sources/components/CommandPalette/CommandPaletteProvider.tsx +141 -0
  707. package/sources/components/CommandPalette/CommandPaletteResults.tsx +129 -0
  708. package/sources/components/CommandPalette/index.ts +3 -0
  709. package/sources/components/CommandPalette/types.ts +15 -0
  710. package/sources/components/CommandPalette/useCommandPalette.ts +107 -0
  711. package/sources/components/CommandView.tsx +135 -0
  712. package/sources/components/CompactGitStatus.tsx +88 -0
  713. package/sources/components/ConnectButton.tsx +117 -0
  714. package/sources/components/Deferred.tsx +18 -0
  715. package/sources/components/DuplicateSheet.tsx +295 -0
  716. package/sources/components/EmptyMainScreen.tsx +171 -0
  717. package/sources/components/EmptyMessages.tsx +123 -0
  718. package/sources/components/EmptySessionsTablet.tsx +111 -0
  719. package/sources/components/ExternalLink.tsx +22 -0
  720. package/sources/components/FAB.tsx +53 -0
  721. package/sources/components/FABWide.tsx +59 -0
  722. package/sources/components/FeedItemCard.tsx +98 -0
  723. package/sources/components/FileIcon.tsx +63 -0
  724. package/sources/components/FileViewPanel.tsx +673 -0
  725. package/sources/components/FilesSidebar.tsx +739 -0
  726. package/sources/components/FloatingOverlay.tsx +48 -0
  727. package/sources/components/GitStatusBadge.tsx +82 -0
  728. package/sources/components/HeaderLogo.tsx +28 -0
  729. package/sources/components/HomeHeader.tsx +243 -0
  730. package/sources/components/HorizontalScrollView.tsx +88 -0
  731. package/sources/components/InboxView.tsx +260 -0
  732. package/sources/components/InlineFileDiff.tsx +277 -0
  733. package/sources/components/Item.tsx +315 -0
  734. package/sources/components/ItemGroup.tsx +147 -0
  735. package/sources/components/ItemList.tsx +102 -0
  736. package/sources/components/MainView.tsx +324 -0
  737. package/sources/components/MessageView.tsx +299 -0
  738. package/sources/components/MultiTextInput.tsx +285 -0
  739. package/sources/components/MultiTextInput.web.tsx +220 -0
  740. package/sources/components/OAuthView.tsx +374 -0
  741. package/sources/components/PermissionModeSelector.tsx +68 -0
  742. package/sources/components/PlaceholderContainerView.tsx +47 -0
  743. package/sources/components/PlusPlus.tsx +34 -0
  744. package/sources/components/PlusPlus.web.tsx +34 -0
  745. package/sources/components/ProjectGitStatus.tsx +102 -0
  746. package/sources/components/RoundButton.tsx +130 -0
  747. package/sources/components/SearchableListSelector.tsx +675 -0
  748. package/sources/components/SessionActionsNativeMenu.android.tsx +58 -0
  749. package/sources/components/SessionActionsNativeMenu.ios.tsx +55 -0
  750. package/sources/components/SessionActionsNativeMenu.tsx +20 -0
  751. package/sources/components/SessionActionsNativeMenu.web.tsx +13 -0
  752. package/sources/components/SessionActionsPopover.tsx +240 -0
  753. package/sources/components/SessionsList.tsx +471 -0
  754. package/sources/components/SessionsListWrapper.tsx +72 -0
  755. package/sources/components/SettingsView.tsx +470 -0
  756. package/sources/components/SettingsViewWrapper.tsx +21 -0
  757. package/sources/components/Shaker.tsx +42 -0
  758. package/sources/components/Shaker.web.tsx +46 -0
  759. package/sources/components/ShimmerView.tsx +106 -0
  760. package/sources/components/SidebarNavigator.tsx +218 -0
  761. package/sources/components/SidebarView.tsx +104 -0
  762. package/sources/components/SimpleSyntaxHighlighter.tsx +322 -0
  763. package/sources/components/StatusBarProvider.tsx +12 -0
  764. package/sources/components/StatusDot.tsx +49 -0
  765. package/sources/components/StyledText.tsx +35 -0
  766. package/sources/components/Switch.tsx +20 -0
  767. package/sources/components/TabBar.tsx +140 -0
  768. package/sources/components/ToolGroupView.tsx +101 -0
  769. package/sources/components/TransitionStack.tsx +14 -0
  770. package/sources/components/UpdateBanner.tsx +74 -0
  771. package/sources/components/UserCard.tsx +41 -0
  772. package/sources/components/UserSearchResult.tsx +129 -0
  773. package/sources/components/VoiceAssistantStatusBar.tsx +260 -0
  774. package/sources/components/VoiceBars.tsx +95 -0
  775. package/sources/components/autocomplete/applySuggestion.test.ts +194 -0
  776. package/sources/components/autocomplete/applySuggestion.ts +61 -0
  777. package/sources/components/autocomplete/findActiveWord.test.ts +365 -0
  778. package/sources/components/autocomplete/findActiveWord.ts +207 -0
  779. package/sources/components/autocomplete/suggestions.ts +79 -0
  780. package/sources/components/autocomplete/useActiveSuggestions.ts +130 -0
  781. package/sources/components/autocomplete/useActiveWord.ts +19 -0
  782. package/sources/components/diff/DiffView.tsx +188 -0
  783. package/sources/components/diff/PierreDiffView.tsx +253 -0
  784. package/sources/components/diff/calculateDiff.ts +317 -0
  785. package/sources/components/entityColor.ts +51 -0
  786. package/sources/components/haptics.ts +9 -0
  787. package/sources/components/haptics.web.ts +7 -0
  788. package/sources/components/layout.ts +44 -0
  789. package/sources/components/markdown/MarkdownView.tsx +670 -0
  790. package/sources/components/markdown/MermaidRenderer.tsx +233 -0
  791. package/sources/components/markdown/linkUtils.test.ts +17 -0
  792. package/sources/components/markdown/linkUtils.ts +5 -0
  793. package/sources/components/markdown/parseMarkdown.test.ts +64 -0
  794. package/sources/components/markdown/parseMarkdown.ts +46 -0
  795. package/sources/components/markdown/parseMarkdownBlock.test.ts +108 -0
  796. package/sources/components/markdown/parseMarkdownBlock.ts +200 -0
  797. package/sources/components/markdown/parseMarkdownSpans.ts +88 -0
  798. package/sources/components/modelModeOptions.test.ts +114 -0
  799. package/sources/components/modelModeOptions.ts +257 -0
  800. package/sources/components/navigation/Header.tsx +252 -0
  801. package/sources/components/parseLocalCommandMessage.spec.ts +96 -0
  802. package/sources/components/parseLocalCommandMessage.ts +97 -0
  803. package/sources/components/qr/QRCode.tsx +178 -0
  804. package/sources/components/qr/QRCode.web.tsx +229 -0
  805. package/sources/components/qr/index.ts +2 -0
  806. package/sources/components/qr/qrMatrix.ts +48 -0
  807. package/sources/components/tools/PermissionFooter.tsx +527 -0
  808. package/sources/components/tools/ToolDiffView.tsx +60 -0
  809. package/sources/components/tools/ToolError.tsx +49 -0
  810. package/sources/components/tools/ToolFullView.tsx +193 -0
  811. package/sources/components/tools/ToolHeader.tsx +93 -0
  812. package/sources/components/tools/ToolSectionView.tsx +42 -0
  813. package/sources/components/tools/ToolStatusIndicator.tsx +36 -0
  814. package/sources/components/tools/ToolView.tsx +340 -0
  815. package/sources/components/tools/knownTools.tsx +957 -0
  816. package/sources/components/tools/views/AskUserQuestionView.tsx +357 -0
  817. package/sources/components/tools/views/BashView.tsx +47 -0
  818. package/sources/components/tools/views/BashViewFull.tsx +81 -0
  819. package/sources/components/tools/views/CodexBashView.tsx +126 -0
  820. package/sources/components/tools/views/CodexDiffView.tsx +79 -0
  821. package/sources/components/tools/views/CodexPatchView.tsx +186 -0
  822. package/sources/components/tools/views/EditView.tsx +33 -0
  823. package/sources/components/tools/views/EditViewFull.tsx +38 -0
  824. package/sources/components/tools/views/ExitPlanToolView.tsx +21 -0
  825. package/sources/components/tools/views/FileView.tsx +118 -0
  826. package/sources/components/tools/views/GeminiEditView.tsx +75 -0
  827. package/sources/components/tools/views/GeminiExecuteView.tsx +92 -0
  828. package/sources/components/tools/views/MCPToolView.tsx +31 -0
  829. package/sources/components/tools/views/MultiEditView.tsx +41 -0
  830. package/sources/components/tools/views/MultiEditViewFull.tsx +84 -0
  831. package/sources/components/tools/views/TaskView.tsx +129 -0
  832. package/sources/components/tools/views/TodoView.tsx +90 -0
  833. package/sources/components/tools/views/WriteView.tsx +29 -0
  834. package/sources/components/tools/views/_all.tsx +88 -0
  835. package/sources/components/usage/UsageBar.tsx +80 -0
  836. package/sources/components/usage/UsageChart.tsx +164 -0
  837. package/sources/components/usage/UsagePanel.tsx +283 -0
  838. package/sources/components/web/FaviconPermissionIndicator.tsx +44 -0
  839. package/sources/config.ts +3 -0
  840. package/sources/constants/Languages.ts +116 -0
  841. package/sources/constants/Typography.ts +116 -0
  842. package/sources/dev/testRunner.ts +277 -0
  843. package/sources/docs/autocomplete-text-manipulation.md +224 -0
  844. package/sources/encryption/aes.appspec.ts +25 -0
  845. package/sources/encryption/aes.ts +21 -0
  846. package/sources/encryption/aes.web.test.ts +73 -0
  847. package/sources/encryption/aes.web.ts +79 -0
  848. package/sources/encryption/base64.appspec.ts +240 -0
  849. package/sources/encryption/base64.native.ts +12 -0
  850. package/sources/encryption/base64.ts +46 -0
  851. package/sources/encryption/blob.test.ts +120 -0
  852. package/sources/encryption/blob.ts +58 -0
  853. package/sources/encryption/deriveKey.appspec.ts +72 -0
  854. package/sources/encryption/deriveKey.ts +46 -0
  855. package/sources/encryption/hex.ts +17 -0
  856. package/sources/encryption/hmac_sha512.appspec.ts +40 -0
  857. package/sources/encryption/hmac_sha512.ts +42 -0
  858. package/sources/encryption/libsodium.lib.ts +2 -0
  859. package/sources/encryption/libsodium.lib.web.ts +2 -0
  860. package/sources/encryption/libsodium.ts +58 -0
  861. package/sources/encryption/text.test.ts +61 -0
  862. package/sources/encryption/text.ts +11 -0
  863. package/sources/hooks/useAsyncCommand.ts +25 -0
  864. package/sources/hooks/useAttachmentImage.ts +134 -0
  865. package/sources/hooks/useAutocomplete.ts +69 -0
  866. package/sources/hooks/useAutocompleteSession.ts +53 -0
  867. package/sources/hooks/useChangelog.ts +45 -0
  868. package/sources/hooks/useCheckCameraPermissions.ts +25 -0
  869. package/sources/hooks/useConnectAccount.ts +107 -0
  870. package/sources/hooks/useConnectTerminal.ts +112 -0
  871. package/sources/hooks/useDemoMessages.ts +48 -0
  872. package/sources/hooks/useDraft.ts +120 -0
  873. package/sources/hooks/useElapsedTime.ts +36 -0
  874. package/sources/hooks/useGetPath.ts +13 -0
  875. package/sources/hooks/useGitStatusFiles.ts +45 -0
  876. package/sources/hooks/useGlobalKeyboard.ts +29 -0
  877. package/sources/hooks/useGroupedMessages.ts +149 -0
  878. package/sources/hooks/useImagePicker.ts +135 -0
  879. package/sources/hooks/useInboxHasContent.ts +19 -0
  880. package/sources/hooks/useMultiClick.ts +56 -0
  881. package/sources/hooks/useNasTechAction.ts +45 -0
  882. package/sources/hooks/useNativeUpdate.ts +10 -0
  883. package/sources/hooks/useNavigateToSession.ts +20 -0
  884. package/sources/hooks/useNewSessionDraft.ts +70 -0
  885. package/sources/hooks/usePrefetchFileContents.ts +162 -0
  886. package/sources/hooks/useSearch.ts +120 -0
  887. package/sources/hooks/useSessionQuickActions.ts +325 -0
  888. package/sources/hooks/useTauriDrag.ts +76 -0
  889. package/sources/hooks/useTauriZoom.ts +67 -0
  890. package/sources/hooks/useUpdates.ts +84 -0
  891. package/sources/hooks/useVisibleSessionListViewData.ts +65 -0
  892. package/sources/hooks/useWorktreeCleanup.ts +69 -0
  893. package/sources/log.ts +108 -0
  894. package/sources/modal/ModalManager.ts +203 -0
  895. package/sources/modal/ModalProvider.tsx +103 -0
  896. package/sources/modal/components/BaseModal.tsx +122 -0
  897. package/sources/modal/components/CustomModal.tsx +42 -0
  898. package/sources/modal/components/WebAlertModal.tsx +139 -0
  899. package/sources/modal/components/WebPromptModal.tsx +185 -0
  900. package/sources/modal/index.ts +3 -0
  901. package/sources/modal/types.ts +79 -0
  902. package/sources/nastech-wire/index.ts +10 -0
  903. package/sources/nastech-wire/legacyProtocol.ts +27 -0
  904. package/sources/nastech-wire/messageMeta.ts +14 -0
  905. package/sources/nastech-wire/messages.ts +113 -0
  906. package/sources/nastech-wire/sessionProtocol.ts +134 -0
  907. package/sources/nastech-wire/voice.ts +34 -0
  908. package/sources/polyfills/screenOrientation.ts +33 -0
  909. package/sources/realtime/RealtimeProvider.tsx +20 -0
  910. package/sources/realtime/RealtimeProvider.web.tsx +15 -0
  911. package/sources/realtime/RealtimeSession.ts +200 -0
  912. package/sources/realtime/RealtimeVoiceSession.tsx +211 -0
  913. package/sources/realtime/RealtimeVoiceSession.web.tsx +209 -0
  914. package/sources/realtime/hooks/contextFormatters.ts +127 -0
  915. package/sources/realtime/hooks/voiceHooks.ts +232 -0
  916. package/sources/realtime/realtimeClientTools.ts +94 -0
  917. package/sources/realtime/types.ts +19 -0
  918. package/sources/realtime/voiceConfig.ts +31 -0
  919. package/sources/realtime/voiceExperiment.ts +91 -0
  920. package/sources/realtime/voiceSystemPrompt.ts +75 -0
  921. package/sources/scripts/compareTranslations.ts +217 -0
  922. package/sources/scripts/parseChangelog.ts +87 -0
  923. package/sources/sync/__testdata__/trace_0.json +3986 -0
  924. package/sources/sync/__testdata__/trace_1.json +1391 -0
  925. package/sources/sync/__testdata__/trace_2.json +182 -0
  926. package/sources/sync/agentDefaults.ts +108 -0
  927. package/sources/sync/apiArtifacts.ts +143 -0
  928. package/sources/sync/apiAttachments.ts +217 -0
  929. package/sources/sync/apiFeed.ts +60 -0
  930. package/sources/sync/apiFriends.ts +217 -0
  931. package/sources/sync/apiGithub.spec.ts +97 -0
  932. package/sources/sync/apiGithub.ts +103 -0
  933. package/sources/sync/apiKv.ts +270 -0
  934. package/sources/sync/apiPush.ts +83 -0
  935. package/sources/sync/apiServices.ts +64 -0
  936. package/sources/sync/apiSocket.ts +290 -0
  937. package/sources/sync/apiTypes.spec.ts +23 -0
  938. package/sources/sync/apiTypes.ts +213 -0
  939. package/sources/sync/apiUsage.ts +130 -0
  940. package/sources/sync/apiVoice.ts +57 -0
  941. package/sources/sync/appConfig.ts +95 -0
  942. package/sources/sync/artifactTypes.ts +85 -0
  943. package/sources/sync/attachmentTypes.ts +28 -0
  944. package/sources/sync/encryption/artifactEncryption.ts +83 -0
  945. package/sources/sync/encryption/encryption.ts +220 -0
  946. package/sources/sync/encryption/encryptionCache.ts +248 -0
  947. package/sources/sync/encryption/encryptor.appspec.ts +409 -0
  948. package/sources/sync/encryption/encryptor.ts +126 -0
  949. package/sources/sync/encryption/machineEncryption.ts +122 -0
  950. package/sources/sync/encryption/sessionEncryption.ts +207 -0
  951. package/sources/sync/feedTypes.ts +43 -0
  952. package/sources/sync/friendTypes.ts +92 -0
  953. package/sources/sync/git-parsers/LineParser.ts +62 -0
  954. package/sources/sync/git-parsers/parseBranch.ts +97 -0
  955. package/sources/sync/git-parsers/parseDiff.ts +180 -0
  956. package/sources/sync/git-parsers/parseStatus.ts +162 -0
  957. package/sources/sync/git-parsers/parseStatusV2.ts +307 -0
  958. package/sources/sync/gitStatusFiles.ts +185 -0
  959. package/sources/sync/gitStatusSync.ts +282 -0
  960. package/sources/sync/localSettings.ts +67 -0
  961. package/sources/sync/messageMeta.test.ts +87 -0
  962. package/sources/sync/messageMeta.ts +36 -0
  963. package/sources/sync/modeHacks.test.ts +29 -0
  964. package/sources/sync/modeHacks.ts +22 -0
  965. package/sources/sync/nastechApi.ts +124 -0
  966. package/sources/sync/ops.ts +776 -0
  967. package/sources/sync/persistence.ts +322 -0
  968. package/sources/sync/profile.ts +95 -0
  969. package/sources/sync/projectFiles.ts +54 -0
  970. package/sources/sync/prompt/systemPrompt.ts +20 -0
  971. package/sources/sync/purchases.ts +67 -0
  972. package/sources/sync/pushRegistration.ts +229 -0
  973. package/sources/sync/reducer/activityUpdateAccumulator.test.ts +492 -0
  974. package/sources/sync/reducer/activityUpdateAccumulator.ts +96 -0
  975. package/sources/sync/reducer/messageToEvent.ts +85 -0
  976. package/sources/sync/reducer/phase0-skipping.spec.ts +206 -0
  977. package/sources/sync/reducer/reducer.spec.ts +3169 -0
  978. package/sources/sync/reducer/reducer.ts +1214 -0
  979. package/sources/sync/reducer/reducerTracer.spec.ts +502 -0
  980. package/sources/sync/reducer/reducerTracer.ts +310 -0
  981. package/sources/sync/revenueCat/index.ts +21 -0
  982. package/sources/sync/revenueCat/revenueCat.ts +215 -0
  983. package/sources/sync/revenueCat/revenueCat.web.ts +238 -0
  984. package/sources/sync/revenueCat/types.ts +82 -0
  985. package/sources/sync/serverConfig.ts +72 -0
  986. package/sources/sync/settings.spec.ts +456 -0
  987. package/sources/sync/settings.ts +186 -0
  988. package/sources/sync/storage.ts +1653 -0
  989. package/sources/sync/storageTypes.spec.ts +24 -0
  990. package/sources/sync/storageTypes.ts +215 -0
  991. package/sources/sync/suggestionCommands.ts +149 -0
  992. package/sources/sync/suggestionFile.ts +206 -0
  993. package/sources/sync/sync.ts +2555 -0
  994. package/sources/sync/typesMessage.ts +69 -0
  995. package/sources/sync/typesMessageMeta.test.ts +14 -0
  996. package/sources/sync/typesMessageMeta.ts +17 -0
  997. package/sources/sync/typesRaw.spec.ts +2010 -0
  998. package/sources/sync/typesRaw.ts +1183 -0
  999. package/sources/sync/uploadFormFile.ts +29 -0
  1000. package/sources/sync/uploadFormFile.web.ts +14 -0
  1001. package/sources/sync/webTabTitle.ts +58 -0
  1002. package/sources/text/README.md +223 -0
  1003. package/sources/text/_all.ts +104 -0
  1004. package/sources/text/_default.ts +1015 -0
  1005. package/sources/text/index.ts +215 -0
  1006. package/sources/text/translations/ca.ts +993 -0
  1007. package/sources/text/translations/en.ts +1009 -0
  1008. package/sources/text/translations/es.ts +995 -0
  1009. package/sources/text/translations/it.ts +992 -0
  1010. package/sources/text/translations/ja.ts +993 -0
  1011. package/sources/text/translations/pl.ts +1024 -0
  1012. package/sources/text/translations/pt.ts +992 -0
  1013. package/sources/text/translations/ru.ts +1023 -0
  1014. package/sources/text/translations/zh-Hans.ts +992 -0
  1015. package/sources/text/translations/zh-Hant.ts +991 -0
  1016. package/sources/theme.css +72 -0
  1017. package/sources/theme.dark.json +31 -0
  1018. package/sources/theme.figma.json +457 -0
  1019. package/sources/theme.gen.ts +10 -0
  1020. package/sources/theme.light.json +31 -0
  1021. package/sources/theme.ts +452 -0
  1022. package/sources/track/index.ts +171 -0
  1023. package/sources/track/tracking.ts +12 -0
  1024. package/sources/track/useTrackScreens.ts +10 -0
  1025. package/sources/types/react-native-webrtc-web-shim.d.ts +6 -0
  1026. package/sources/unistyles.ts +97 -0
  1027. package/sources/utils/codexUnifiedDiff.spec.ts +43 -0
  1028. package/sources/utils/codexUnifiedDiff.ts +70 -0
  1029. package/sources/utils/consoleLogging.ts +145 -0
  1030. package/sources/utils/copySessionMetadataToClipboard.ts +53 -0
  1031. package/sources/utils/debounce.test.ts +646 -0
  1032. package/sources/utils/debounce.ts +122 -0
  1033. package/sources/utils/deviceCalculations.test.ts +318 -0
  1034. package/sources/utils/deviceCalculations.ts +87 -0
  1035. package/sources/utils/errors.ts +10 -0
  1036. package/sources/utils/formatPermissionParams.ts +23 -0
  1037. package/sources/utils/isTauri.ts +7 -0
  1038. package/sources/utils/loadSkia.ts +3 -0
  1039. package/sources/utils/loadSkia.web.ts +5 -0
  1040. package/sources/utils/lock.ts +40 -0
  1041. package/sources/utils/machineUtils.ts +6 -0
  1042. package/sources/utils/messageUtils.ts +254 -0
  1043. package/sources/utils/microphonePermissions.ts +109 -0
  1044. package/sources/utils/notificationRouting.test.ts +51 -0
  1045. package/sources/utils/notificationRouting.ts +81 -0
  1046. package/sources/utils/oauth.ts +143 -0
  1047. package/sources/utils/openExternalUrl.ts +19 -0
  1048. package/sources/utils/parseToken.ts +23 -0
  1049. package/sources/utils/pasteImages.web.ts +81 -0
  1050. package/sources/utils/pathUtils.spec.ts +226 -0
  1051. package/sources/utils/pathUtils.ts +75 -0
  1052. package/sources/utils/platform.ts +19 -0
  1053. package/sources/utils/readFileBytes.ts +11 -0
  1054. package/sources/utils/readFileBytes.web.ts +12 -0
  1055. package/sources/utils/requestReview.ts +135 -0
  1056. package/sources/utils/responsive.ts +87 -0
  1057. package/sources/utils/resumeCommand.test.ts +78 -0
  1058. package/sources/utils/resumeCommand.ts +70 -0
  1059. package/sources/utils/sessionFileLinks.test.ts +112 -0
  1060. package/sources/utils/sessionFileLinks.ts +388 -0
  1061. package/sources/utils/sessionUtils.ts +226 -0
  1062. package/sources/utils/stringUtils.ts +41 -0
  1063. package/sources/utils/sync.ts +164 -0
  1064. package/sources/utils/thumbhash.ts +17 -0
  1065. package/sources/utils/thumbhash.web.ts +85 -0
  1066. package/sources/utils/time.ts +41 -0
  1067. package/sources/utils/toSnakeCase.test.ts +182 -0
  1068. package/sources/utils/toSnakeCase.ts +40 -0
  1069. package/sources/utils/toolCommand.test.ts +23 -0
  1070. package/sources/utils/toolCommand.ts +35 -0
  1071. package/sources/utils/toolComparison.test.ts +101 -0
  1072. package/sources/utils/toolComparison.ts +73 -0
  1073. package/sources/utils/toolErrorParser.test.ts +126 -0
  1074. package/sources/utils/toolErrorParser.ts +102 -0
  1075. package/sources/utils/trimIdent.ts +27 -0
  1076. package/sources/utils/truncateForLogs.ts +37 -0
  1077. package/sources/utils/versionUtils.test.ts +58 -0
  1078. package/sources/utils/versionUtils.ts +69 -0
  1079. package/sources/utils/web/faviconGenerator.ts +39 -0
  1080. package/sources/utils/worktree.ts +192 -0
  1081. package/sources/wire/index.ts +97 -0
  1082. package/src-tauri/Cargo.lock +5978 -0
  1083. package/src-tauri/Cargo.toml +27 -0
  1084. package/src-tauri/build.rs +3 -0
  1085. package/src-tauri/capabilities/default.json +27 -0
  1086. package/src-tauri/deny.toml +53 -0
  1087. package/src-tauri/entitlements.plist +24 -0
  1088. package/src-tauri/icons/128x128.png +0 -0
  1089. package/src-tauri/icons/128x128@2x.png +0 -0
  1090. package/src-tauri/icons/32x32.png +0 -0
  1091. package/src-tauri/icons/64x64.png +0 -0
  1092. package/src-tauri/icons/Square107x107Logo.png +0 -0
  1093. package/src-tauri/icons/Square142x142Logo.png +0 -0
  1094. package/src-tauri/icons/Square150x150Logo.png +0 -0
  1095. package/src-tauri/icons/Square284x284Logo.png +0 -0
  1096. package/src-tauri/icons/Square30x30Logo.png +0 -0
  1097. package/src-tauri/icons/Square310x310Logo.png +0 -0
  1098. package/src-tauri/icons/Square44x44Logo.png +0 -0
  1099. package/src-tauri/icons/Square71x71Logo.png +0 -0
  1100. package/src-tauri/icons/Square89x89Logo.png +0 -0
  1101. package/src-tauri/icons/StoreLogo.png +0 -0
  1102. package/src-tauri/icons/icon.icns +0 -0
  1103. package/src-tauri/icons/icon.ico +0 -0
  1104. package/src-tauri/icons/icon.png +0 -0
  1105. package/src-tauri/src/lib.rs +18 -0
  1106. package/src-tauri/src/main.rs +6 -0
  1107. package/src-tauri/tauri.conf.json +51 -0
  1108. package/src-tauri/tauri.dev.conf.json +20 -0
  1109. package/src-tauri/tauri.preview.conf.json +20 -0
  1110. package/tsconfig.json +45 -0
  1111. package/vitest.config.ts +26 -0
@@ -0,0 +1,2010 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { createId } from '@paralleldrive/cuid2';
3
+ import { normalizeRawMessage } from './typesRaw';
4
+
5
+ /**
6
+ * WOLOG Content Normalization Tests
7
+ *
8
+ * These tests verify the Zod transform approach handles:
9
+ * 1. Hyphenated types (tool-call, tool-call-result) → Canonical (tool_use, tool_result)
10
+ * 2. Canonical types pass through unchanged (idempotency)
11
+ * 3. Unknown fields are preserved (future API compatibility)
12
+ * 4. Unexpected data formats are handled gracefully
13
+ * 5. Backwards compatibility with old CLI messages
14
+ * 6. Cross-agent compatibility (Claude SDK, Codex, Gemini)
15
+ */
16
+
17
+ // Import the actual schemas from typesRaw.ts
18
+ // Note: We're testing the schemas as black boxes through their public API
19
+ import { RawRecordSchema } from './typesRaw';
20
+
21
+ describe('Zod Transform - WOLOG Content Normalization', () => {
22
+
23
+ describe('Accepts and transforms hyphenated types', () => {
24
+ it('transforms tool-call to tool_use with field remapping', () => {
25
+ const message = {
26
+ role: 'agent',
27
+ content: {
28
+ type: 'output',
29
+ data: {
30
+ type: 'assistant',
31
+ message: {
32
+ role: 'assistant',
33
+ model: 'claude-3',
34
+ content: [{
35
+ type: 'tool-call',
36
+ callId: 'call_abc123',
37
+ name: 'Bash',
38
+ input: { command: 'ls -la' }
39
+ }]
40
+ },
41
+ uuid: 'test-uuid'
42
+ }
43
+ }
44
+ };
45
+
46
+ const result = RawRecordSchema.safeParse(message);
47
+
48
+ expect(result.success).toBe(true);
49
+ if (result.success) {
50
+ const content = result.data.content;
51
+ if (content.type === 'output' && content.data.type === 'assistant') {
52
+ const firstItem = content.data.message.content[0];
53
+ expect(firstItem.type).toBe('tool_use');
54
+ if (firstItem.type === 'tool_use') {
55
+ expect(firstItem.id).toBe('call_abc123'); // callId → id
56
+ expect(firstItem.name).toBe('Bash');
57
+ expect(firstItem.input).toEqual({ command: 'ls -la' });
58
+ }
59
+ }
60
+ }
61
+ });
62
+
63
+ it('transforms tool-call-result to tool_result with field remapping', () => {
64
+ const message = {
65
+ role: 'agent',
66
+ content: {
67
+ type: 'output',
68
+ data: {
69
+ type: 'user',
70
+ message: {
71
+ role: 'user',
72
+ content: [{
73
+ type: 'tool-call-result',
74
+ callId: 'call_abc123',
75
+ output: 'file1.txt\nfile2.txt',
76
+ is_error: false
77
+ }]
78
+ },
79
+ uuid: 'test-uuid'
80
+ }
81
+ }
82
+ };
83
+
84
+ const result = RawRecordSchema.safeParse(message);
85
+
86
+ expect(result.success).toBe(true);
87
+ if (result.success) {
88
+ const content = result.data.content;
89
+ if (content.type === 'output' && content.data.type === 'user') {
90
+ const msgContent = content.data.message.content;
91
+ if (Array.isArray(msgContent) && msgContent[0].type === 'tool_result') {
92
+ expect(msgContent[0].type).toBe('tool_result');
93
+ expect(msgContent[0].tool_use_id).toBe('call_abc123'); // callId → tool_use_id
94
+ expect(msgContent[0].content).toBe('file1.txt\nfile2.txt'); // output → content
95
+ expect(msgContent[0].is_error).toBe(false);
96
+ }
97
+ }
98
+ }
99
+ });
100
+
101
+ it('preserves unknown fields for future compatibility', () => {
102
+ const message = {
103
+ role: 'agent',
104
+ content: {
105
+ type: 'output',
106
+ data: {
107
+ type: 'assistant',
108
+ message: {
109
+ role: 'assistant',
110
+ model: 'claude-3',
111
+ content: [{
112
+ type: 'tool-call',
113
+ callId: 'call_xyz',
114
+ name: 'Read',
115
+ input: {},
116
+ futureField: 'some_value', // Unknown field
117
+ metadata: { timestamp: 123 } // Unknown nested field
118
+ }]
119
+ },
120
+ uuid: 'test-uuid'
121
+ }
122
+ }
123
+ };
124
+
125
+ const result = RawRecordSchema.safeParse(message);
126
+
127
+ expect(result.success).toBe(true);
128
+ if (result.success) {
129
+ const content = result.data.content;
130
+ if (content.type === 'output' && content.data.type === 'assistant') {
131
+ const firstItem: any = content.data.message.content[0];
132
+ expect(firstItem.type).toBe('tool_use');
133
+ expect(firstItem.id).toBe('call_xyz');
134
+ // Verify unknown fields are preserved
135
+ expect(firstItem.futureField).toBe('some_value');
136
+ expect(firstItem.metadata).toEqual({ timestamp: 123 });
137
+ }
138
+ }
139
+ });
140
+ });
141
+
142
+ describe('Accepts canonical underscore types without transformation (idempotency)', () => {
143
+ it('passes through tool_use unchanged', () => {
144
+ const message = {
145
+ role: 'agent',
146
+ content: {
147
+ type: 'output',
148
+ data: {
149
+ type: 'assistant',
150
+ message: {
151
+ role: 'assistant',
152
+ model: 'claude-3',
153
+ content: [{
154
+ type: 'tool_use',
155
+ id: 'call_123',
156
+ name: 'Write',
157
+ input: { file_path: '/test.txt' }
158
+ }]
159
+ },
160
+ uuid: 'test-uuid'
161
+ }
162
+ }
163
+ };
164
+
165
+ const result = RawRecordSchema.safeParse(message);
166
+
167
+ expect(result.success).toBe(true);
168
+ if (result.success) {
169
+ const content = result.data.content;
170
+ if (content.type === 'output' && content.data.type === 'assistant') {
171
+ const firstItem = content.data.message.content[0];
172
+ expect(firstItem.type).toBe('tool_use');
173
+ if (firstItem.type === 'tool_use') {
174
+ expect(firstItem.id).toBe('call_123');
175
+ expect(firstItem.name).toBe('Write');
176
+ }
177
+ }
178
+ }
179
+ });
180
+
181
+ it('passes through tool_result unchanged', () => {
182
+ const message = {
183
+ role: 'agent',
184
+ content: {
185
+ type: 'output',
186
+ data: {
187
+ type: 'user',
188
+ message: {
189
+ role: 'user',
190
+ content: [{
191
+ type: 'tool_result',
192
+ tool_use_id: 'call_123',
193
+ content: 'Success',
194
+ is_error: false
195
+ }]
196
+ },
197
+ uuid: 'test-uuid'
198
+ }
199
+ }
200
+ };
201
+
202
+ const result = RawRecordSchema.safeParse(message);
203
+
204
+ expect(result.success).toBe(true);
205
+ if (result.success) {
206
+ const content = result.data.content;
207
+ if (content.type === 'output' && content.data.type === 'user') {
208
+ const msgContent = content.data.message.content;
209
+ if (Array.isArray(msgContent) && msgContent[0].type === 'tool_result') {
210
+ expect(msgContent[0].type).toBe('tool_result');
211
+ expect(msgContent[0].tool_use_id).toBe('call_123');
212
+ expect(msgContent[0].content).toBe('Success');
213
+ }
214
+ }
215
+ }
216
+ });
217
+
218
+ it('passes through text content unchanged', () => {
219
+ const message = {
220
+ role: 'agent',
221
+ content: {
222
+ type: 'output',
223
+ data: {
224
+ type: 'assistant',
225
+ message: {
226
+ role: 'assistant',
227
+ model: 'claude-3',
228
+ content: [{
229
+ type: 'text',
230
+ text: 'Hello world'
231
+ }]
232
+ },
233
+ uuid: 'test-uuid'
234
+ }
235
+ }
236
+ };
237
+
238
+ const result = RawRecordSchema.safeParse(message);
239
+
240
+ expect(result.success).toBe(true);
241
+ if (result.success) {
242
+ const content = result.data.content;
243
+ if (content.type === 'output' && content.data.type === 'assistant') {
244
+ const firstItem = content.data.message.content[0];
245
+ expect(firstItem.type).toBe('text');
246
+ if (firstItem.type === 'text') {
247
+ expect(firstItem.text).toBe('Hello world');
248
+ }
249
+ }
250
+ }
251
+ });
252
+ });
253
+
254
+ describe('Rejects unknown content types with clear errors', () => {
255
+ it('fails validation for unknown type with clear error message', () => {
256
+ const message = {
257
+ role: 'agent',
258
+ content: {
259
+ type: 'output',
260
+ data: {
261
+ type: 'assistant',
262
+ message: {
263
+ role: 'assistant',
264
+ model: 'claude-3',
265
+ content: [{
266
+ type: 'unknown-type',
267
+ data: 'some data'
268
+ }]
269
+ },
270
+ uuid: 'test-uuid'
271
+ }
272
+ }
273
+ };
274
+
275
+ const result = RawRecordSchema.safeParse(message);
276
+
277
+ expect(result.success).toBe(false);
278
+ if (!result.success) {
279
+ // Verify error includes information about expected types
280
+ expect(result.error.issues).toBeDefined();
281
+ expect(result.error.issues.length).toBeGreaterThan(0);
282
+ // The error should be about invalid union (discriminated union mismatch)
283
+ const firstIssue = result.error.issues[0];
284
+ expect(firstIssue.code).toBe('invalid_union');
285
+ }
286
+ });
287
+ });
288
+
289
+ describe('Handles mixed hyphenated and canonical in same message', () => {
290
+ it('transforms mixed content array correctly', () => {
291
+ const message = {
292
+ role: 'agent',
293
+ content: {
294
+ type: 'output',
295
+ data: {
296
+ type: 'assistant',
297
+ message: {
298
+ role: 'assistant',
299
+ model: 'claude-3',
300
+ content: [
301
+ { type: 'text', text: 'Running command...' },
302
+ { type: 'tool-call', callId: 'call_1', name: 'Bash', input: { command: 'ls' } },
303
+ { type: 'tool_use', id: 'call_2', name: 'Read', input: { file_path: '/test.txt' } }
304
+ ]
305
+ },
306
+ uuid: 'test-uuid'
307
+ }
308
+ }
309
+ };
310
+
311
+ const result = RawRecordSchema.safeParse(message);
312
+
313
+ expect(result.success).toBe(true);
314
+ if (result.success) {
315
+ const content = result.data.content;
316
+ if (content.type === 'output' && content.data.type === 'assistant') {
317
+ const items = content.data.message.content;
318
+
319
+ // Text passes through
320
+ expect(items[0].type).toBe('text');
321
+
322
+ // tool-call transformed to tool_use
323
+ expect(items[1].type).toBe('tool_use');
324
+ if (items[1].type === 'tool_use') {
325
+ expect(items[1].id).toBe('call_1');
326
+ }
327
+
328
+ // tool_use passes through
329
+ expect(items[2].type).toBe('tool_use');
330
+ if (items[2].type === 'tool_use') {
331
+ expect(items[2].id).toBe('call_2');
332
+ }
333
+ }
334
+ }
335
+ });
336
+
337
+ it('handles tool results with both hyphenated and canonical', () => {
338
+ const message = {
339
+ role: 'agent',
340
+ content: {
341
+ type: 'output',
342
+ data: {
343
+ type: 'user',
344
+ message: {
345
+ role: 'user',
346
+ content: [
347
+ { type: 'tool-call-result', callId: 'call_1', output: 'result1' },
348
+ { type: 'tool_result', tool_use_id: 'call_2', content: 'result2' }
349
+ ]
350
+ },
351
+ uuid: 'test-uuid'
352
+ }
353
+ }
354
+ };
355
+
356
+ const result = RawRecordSchema.safeParse(message);
357
+
358
+ expect(result.success).toBe(true);
359
+ if (result.success) {
360
+ const content = result.data.content;
361
+ if (content.type === 'output' && content.data.type === 'user') {
362
+ const items = content.data.message.content;
363
+ if (Array.isArray(items)) {
364
+ // Both normalized to tool_result
365
+ expect(items[0].type).toBe('tool_result');
366
+ if (items[0].type === 'tool_result') {
367
+ expect(items[0].tool_use_id).toBe('call_1');
368
+ expect(items[0].content).toBe('result1');
369
+ }
370
+
371
+ expect(items[1].type).toBe('tool_result');
372
+ if (items[1].type === 'tool_result') {
373
+ expect(items[1].tool_use_id).toBe('call_2');
374
+ expect(items[1].content).toBe('result2');
375
+ }
376
+ }
377
+ }
378
+ }
379
+ });
380
+ });
381
+
382
+ describe('Backwards compatibility with old CLI messages', () => {
383
+ it('handles old CLI with canonical underscore types', () => {
384
+ const oldCliMessage = {
385
+ role: 'agent',
386
+ content: {
387
+ type: 'output',
388
+ data: {
389
+ type: 'assistant',
390
+ message: {
391
+ role: 'assistant',
392
+ model: 'claude-3',
393
+ content: [
394
+ { type: 'tool_use', id: 'call_old', name: 'Read', input: {} }
395
+ ]
396
+ },
397
+ uuid: 'old-uuid'
398
+ }
399
+ }
400
+ };
401
+
402
+ const result = RawRecordSchema.safeParse(oldCliMessage);
403
+
404
+ expect(result.success).toBe(true);
405
+ if (result.success) {
406
+ const content = result.data.content;
407
+ if (content.type === 'output' && content.data.type === 'assistant') {
408
+ const firstItem = content.data.message.content[0];
409
+ expect(firstItem.type).toBe('tool_use');
410
+ if (firstItem.type === 'tool_use') {
411
+ expect(firstItem.id).toBe('call_old');
412
+ }
413
+ }
414
+ }
415
+ });
416
+ });
417
+
418
+ describe('Codex/Gemini messages use native hyphenated schema (no transformation)', () => {
419
+ it('accepts Codex tool-call messages via codex schema path', () => {
420
+ const codexMessage = {
421
+ role: 'agent',
422
+ content: {
423
+ type: 'codex',
424
+ data: {
425
+ type: 'tool-call',
426
+ callId: 'codex_1',
427
+ name: 'Bash',
428
+ input: { command: 'pwd' },
429
+ id: 'codex-id-1'
430
+ }
431
+ }
432
+ };
433
+
434
+ const result = RawRecordSchema.safeParse(codexMessage);
435
+
436
+ expect(result.success).toBe(true);
437
+ if (result.success) {
438
+ const content = result.data.content;
439
+ if (content.type === 'codex' && content.data.type === 'tool-call') {
440
+ // Codex path keeps hyphenated types as-is
441
+ expect(content.data.type).toBe('tool-call');
442
+ expect(content.data.callId).toBe('codex_1');
443
+ }
444
+ }
445
+ });
446
+
447
+ it('accepts Codex tool-call-result messages via codex schema path', () => {
448
+ const codexMessage = {
449
+ role: 'agent',
450
+ content: {
451
+ type: 'codex',
452
+ data: {
453
+ type: 'tool-call-result',
454
+ callId: 'codex_result_1',
455
+ output: 'command output',
456
+ id: 'codex-id-2'
457
+ }
458
+ }
459
+ };
460
+
461
+ const result = RawRecordSchema.safeParse(codexMessage);
462
+
463
+ expect(result.success).toBe(true);
464
+ if (result.success) {
465
+ const content = result.data.content;
466
+ if (content.type === 'codex' && content.data.type === 'tool-call-result') {
467
+ // Codex path keeps hyphenated types as-is
468
+ expect(content.data.type).toBe('tool-call-result');
469
+ expect(content.data.callId).toBe('codex_result_1');
470
+ expect(content.data.output).toBe('command output');
471
+ }
472
+ }
473
+ });
474
+ });
475
+
476
+ describe('Handles unexpected data formats gracefully', () => {
477
+ it('handles tool-call with both callId and id fields (prefers callId)', () => {
478
+ const message = {
479
+ role: 'agent',
480
+ content: {
481
+ type: 'output',
482
+ data: {
483
+ type: 'assistant',
484
+ message: {
485
+ role: 'assistant',
486
+ model: 'claude-3',
487
+ content: [{
488
+ type: 'tool-call',
489
+ callId: 'primary_id',
490
+ id: 'secondary_id', // Both present
491
+ name: 'Edit',
492
+ input: {}
493
+ }]
494
+ },
495
+ uuid: 'test-uuid'
496
+ }
497
+ }
498
+ };
499
+
500
+ const result = RawRecordSchema.safeParse(message);
501
+
502
+ expect(result.success).toBe(true);
503
+ if (result.success) {
504
+ const content = result.data.content;
505
+ if (content.type === 'output' && content.data.type === 'assistant') {
506
+ const firstItem = content.data.message.content[0];
507
+ expect(firstItem.type).toBe('tool_use');
508
+ if (firstItem.type === 'tool_use') {
509
+ // Should use callId as the canonical id
510
+ expect(firstItem.id).toBe('primary_id');
511
+ }
512
+ }
513
+ }
514
+ });
515
+
516
+ it('handles tool-call-result with both output and content fields (prefers output)', () => {
517
+ const message = {
518
+ role: 'agent',
519
+ content: {
520
+ type: 'output',
521
+ data: {
522
+ type: 'user',
523
+ message: {
524
+ role: 'user',
525
+ content: [{
526
+ type: 'tool-call-result',
527
+ callId: 'call_dual',
528
+ output: 'primary_output',
529
+ content: 'secondary_content', // Both present
530
+ is_error: false
531
+ }]
532
+ },
533
+ uuid: 'test-uuid'
534
+ }
535
+ }
536
+ };
537
+
538
+ const result = RawRecordSchema.safeParse(message);
539
+
540
+ expect(result.success).toBe(true);
541
+ if (result.success) {
542
+ const content = result.data.content;
543
+ if (content.type === 'output' && content.data.type === 'user') {
544
+ const msgContent = content.data.message.content;
545
+ if (Array.isArray(msgContent) && msgContent[0].type === 'tool_result') {
546
+ // Should use output as the canonical content
547
+ expect(msgContent[0].content).toBe('primary_output');
548
+ }
549
+ }
550
+ }
551
+ });
552
+
553
+ it('handles missing optional is_error field (defaults to false)', () => {
554
+ const message = {
555
+ role: 'agent',
556
+ content: {
557
+ type: 'output',
558
+ data: {
559
+ type: 'user',
560
+ message: {
561
+ role: 'user',
562
+ content: [{
563
+ type: 'tool-call-result',
564
+ callId: 'call_no_error',
565
+ output: 'success'
566
+ // is_error missing
567
+ }]
568
+ },
569
+ uuid: 'test-uuid'
570
+ }
571
+ }
572
+ };
573
+
574
+ const result = RawRecordSchema.safeParse(message);
575
+
576
+ expect(result.success).toBe(true);
577
+ if (result.success) {
578
+ const content = result.data.content;
579
+ if (content.type === 'output' && content.data.type === 'user') {
580
+ const msgContent = content.data.message.content;
581
+ if (Array.isArray(msgContent) && msgContent[0].type === 'tool_result') {
582
+ // Should default is_error to false
583
+ expect(msgContent[0].is_error).toBe(false);
584
+ }
585
+ }
586
+ }
587
+ });
588
+
589
+ it('rejects tool-call missing required callId field', () => {
590
+ const message = {
591
+ role: 'agent',
592
+ content: {
593
+ type: 'output',
594
+ data: {
595
+ type: 'assistant',
596
+ message: {
597
+ role: 'assistant',
598
+ model: 'claude-3',
599
+ content: [{
600
+ type: 'tool-call',
601
+ // callId missing!
602
+ name: 'Bash',
603
+ input: {}
604
+ }]
605
+ },
606
+ uuid: 'test-uuid'
607
+ }
608
+ }
609
+ };
610
+
611
+ const result = RawRecordSchema.safeParse(message);
612
+
613
+ // Should fail validation
614
+ expect(result.success).toBe(false);
615
+ if (!result.success) {
616
+ // Verify error mentions missing callId
617
+ const errorString = JSON.stringify(result.error.issues);
618
+ expect(errorString).toContain('callId');
619
+ }
620
+ });
621
+
622
+ it('rejects tool_use missing required id field', () => {
623
+ const message = {
624
+ role: 'agent',
625
+ content: {
626
+ type: 'output',
627
+ data: {
628
+ type: 'assistant',
629
+ message: {
630
+ role: 'assistant',
631
+ model: 'claude-3',
632
+ content: [{
633
+ type: 'tool_use',
634
+ // id missing!
635
+ name: 'Read',
636
+ input: {}
637
+ }]
638
+ },
639
+ uuid: 'test-uuid'
640
+ }
641
+ }
642
+ };
643
+
644
+ const result = RawRecordSchema.safeParse(message);
645
+
646
+ // Should fail validation
647
+ expect(result.success).toBe(false);
648
+ if (!result.success) {
649
+ const errorString = JSON.stringify(result.error.issues);
650
+ expect(errorString).toContain('id');
651
+ }
652
+ });
653
+ });
654
+
655
+ describe('Integration: Complete message flow scenarios', () => {
656
+ it('handles real Claude SDK assistant message with tool_use', () => {
657
+ const realMessage = {
658
+ role: 'agent',
659
+ content: {
660
+ type: 'output',
661
+ data: {
662
+ type: 'assistant',
663
+ message: {
664
+ role: 'assistant',
665
+ model: 'claude-sonnet-4-5-20250929',
666
+ content: [
667
+ { type: 'text', text: 'Let me read that file for you.' },
668
+ {
669
+ type: 'tool_use',
670
+ id: 'toolu_01ABC123',
671
+ name: 'Read',
672
+ input: { file_path: '/Users/test/file.ts' }
673
+ }
674
+ ],
675
+ usage: {
676
+ input_tokens: 1000,
677
+ output_tokens: 50
678
+ }
679
+ },
680
+ uuid: 'real-assistant-uuid',
681
+ parentUuid: null
682
+ }
683
+ },
684
+ meta: {
685
+ sentFrom: 'cli'
686
+ }
687
+ };
688
+
689
+ const result = RawRecordSchema.safeParse(realMessage);
690
+
691
+ expect(result.success).toBe(true);
692
+ if (result.success) {
693
+ expect(result.data.role).toBe('agent');
694
+ expect(result.data.content.type).toBe('output');
695
+ if (result.data.content.type === 'output' && result.data.content.data.type === 'assistant') {
696
+ const content = result.data.content.data.message.content;
697
+ expect(content.length).toBe(2);
698
+ expect(content[0].type).toBe('text');
699
+ expect(content[1].type).toBe('tool_use');
700
+ if (content[1].type === 'tool_use') {
701
+ expect(content[1].id).toBe('toolu_01ABC123');
702
+ }
703
+ }
704
+ }
705
+ });
706
+
707
+ it('handles real user message with tool_result', () => {
708
+ const realMessage = {
709
+ role: 'agent',
710
+ content: {
711
+ type: 'output',
712
+ data: {
713
+ type: 'user',
714
+ message: {
715
+ role: 'user',
716
+ content: [{
717
+ type: 'tool_result',
718
+ tool_use_id: 'toolu_01ABC123',
719
+ content: 'File contents here...',
720
+ is_error: false,
721
+ permissions: {
722
+ date: 1736300000000,
723
+ result: 'approved',
724
+ mode: 'default'
725
+ }
726
+ }]
727
+ },
728
+ uuid: 'real-user-uuid',
729
+ parentUuid: 'real-assistant-uuid',
730
+ isSidechain: false
731
+ }
732
+ },
733
+ meta: {
734
+ sentFrom: 'cli'
735
+ }
736
+ };
737
+
738
+ const result = RawRecordSchema.safeParse(realMessage);
739
+
740
+ expect(result.success).toBe(true);
741
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'user') {
742
+ const content = result.data.content.data.message.content;
743
+ if (Array.isArray(content) && content[0].type === 'tool_result') {
744
+ expect(content[0].type).toBe('tool_result');
745
+ expect(content[0].tool_use_id).toBe('toolu_01ABC123');
746
+ expect(content[0].permissions).toBeDefined();
747
+ }
748
+ }
749
+ });
750
+
751
+ it('handles sidechain messages (parent_tool_use_id present)', () => {
752
+ const sidechainMessage = {
753
+ role: 'agent',
754
+ content: {
755
+ type: 'output',
756
+ data: {
757
+ type: 'assistant',
758
+ message: {
759
+ role: 'assistant',
760
+ model: 'claude-3',
761
+ content: [
762
+ { type: 'text', text: 'Sidechain response' }
763
+ ]
764
+ },
765
+ uuid: 'sidechain-uuid',
766
+ parentUuid: 'parent-uuid',
767
+ isSidechain: true,
768
+ parent_tool_use_id: 'toolu_parent'
769
+ }
770
+ },
771
+ meta: {
772
+ sentFrom: 'cli'
773
+ }
774
+ };
775
+
776
+ const result = RawRecordSchema.safeParse(sidechainMessage);
777
+
778
+ expect(result.success).toBe(true);
779
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'assistant') {
780
+ expect(result.data.content.data.isSidechain).toBe(true);
781
+ expect(result.data.content.data.parent_tool_use_id).toBe('toolu_parent');
782
+ }
783
+ });
784
+ });
785
+
786
+ describe('Unexpected data format robustness', () => {
787
+ it('handles tool-call with extra unknown fields from future API', () => {
788
+ const futureMessage = {
789
+ role: 'agent',
790
+ content: {
791
+ type: 'output',
792
+ data: {
793
+ type: 'assistant',
794
+ message: {
795
+ role: 'assistant',
796
+ model: 'claude-4',
797
+ content: [{
798
+ type: 'tool-call',
799
+ callId: 'future_call',
800
+ name: 'FutureTool',
801
+ input: {},
802
+ // Future API fields
803
+ priority: 'high',
804
+ timeout: 30000,
805
+ metadata: { version: '2.0' }
806
+ }]
807
+ },
808
+ uuid: 'future-uuid'
809
+ }
810
+ }
811
+ };
812
+
813
+ const result = RawRecordSchema.safeParse(futureMessage);
814
+
815
+ expect(result.success).toBe(true);
816
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'assistant') {
817
+ const item: any = result.data.content.data.message.content[0];
818
+ expect(item.type).toBe('tool_use');
819
+ // Unknown fields should be preserved
820
+ expect(item.priority).toBe('high');
821
+ expect(item.timeout).toBe(30000);
822
+ expect(item.metadata).toEqual({ version: '2.0' });
823
+ }
824
+ });
825
+
826
+ it('handles empty content array', () => {
827
+ const emptyMessage = {
828
+ role: 'agent',
829
+ content: {
830
+ type: 'output',
831
+ data: {
832
+ type: 'assistant',
833
+ message: {
834
+ role: 'assistant',
835
+ model: 'claude-3',
836
+ content: [] // Empty
837
+ },
838
+ uuid: 'empty-uuid'
839
+ }
840
+ }
841
+ };
842
+
843
+ const result = RawRecordSchema.safeParse(emptyMessage);
844
+
845
+ expect(result.success).toBe(true);
846
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'assistant') {
847
+ expect(result.data.content.data.message.content).toEqual([]);
848
+ }
849
+ });
850
+
851
+ it('handles string content in user messages (not array)', () => {
852
+ const stringContentMessage = {
853
+ role: 'agent',
854
+ content: {
855
+ type: 'output',
856
+ data: {
857
+ type: 'user',
858
+ message: {
859
+ role: 'user',
860
+ content: 'Plain string message' // Not an array
861
+ },
862
+ uuid: 'string-uuid'
863
+ }
864
+ }
865
+ };
866
+
867
+ const result = RawRecordSchema.safeParse(stringContentMessage);
868
+
869
+ expect(result.success).toBe(true);
870
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'user') {
871
+ expect(result.data.content.data.message.content).toBe('Plain string message');
872
+ }
873
+ });
874
+
875
+ it('handles system messages (no transformation needed)', () => {
876
+ const systemMessage = {
877
+ role: 'agent',
878
+ content: {
879
+ type: 'output',
880
+ data: {
881
+ type: 'system'
882
+ }
883
+ }
884
+ };
885
+
886
+ const result = RawRecordSchema.safeParse(systemMessage);
887
+
888
+ expect(result.success).toBe(true);
889
+ if (result.success && result.data.content.type === 'output') {
890
+ expect(result.data.content.data.type).toBe('system');
891
+ }
892
+ });
893
+
894
+ it('handles summary messages', () => {
895
+ const summaryMessage = {
896
+ role: 'agent',
897
+ content: {
898
+ type: 'output',
899
+ data: {
900
+ type: 'summary',
901
+ summary: 'Session summary text'
902
+ }
903
+ }
904
+ };
905
+
906
+ const result = RawRecordSchema.safeParse(summaryMessage);
907
+
908
+ expect(result.success).toBe(true);
909
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'summary') {
910
+ expect(result.data.content.data.summary).toBe('Session summary text');
911
+ }
912
+ });
913
+
914
+ it('handles event messages (no content transformation)', () => {
915
+ const eventMessage = {
916
+ role: 'agent',
917
+ content: {
918
+ type: 'event',
919
+ id: 'event-123',
920
+ data: {
921
+ type: 'switch',
922
+ mode: 'local'
923
+ }
924
+ }
925
+ };
926
+
927
+ const result = RawRecordSchema.safeParse(eventMessage);
928
+
929
+ expect(result.success).toBe(true);
930
+ if (result.success && result.data.content.type === 'event') {
931
+ expect(result.data.content.data.type).toBe('switch');
932
+ if (result.data.content.data.type === 'switch') {
933
+ expect(result.data.content.data.mode).toBe('local');
934
+ }
935
+ }
936
+ });
937
+
938
+ it('handles user role messages with text content', () => {
939
+ const userMessage = {
940
+ role: 'user',
941
+ content: {
942
+ type: 'text',
943
+ text: 'User input message'
944
+ }
945
+ };
946
+
947
+ const result = RawRecordSchema.safeParse(userMessage);
948
+
949
+ expect(result.success).toBe(true);
950
+ if (result.success && result.data.role === 'user') {
951
+ expect(result.data.content.type).toBe('text');
952
+ expect(result.data.content.text).toBe('User input message');
953
+ }
954
+ });
955
+ });
956
+
957
+ describe('Field preservation and edge cases', () => {
958
+ it('preserves permissions object in tool_result', () => {
959
+ const messageWithPermissions = {
960
+ role: 'agent',
961
+ content: {
962
+ type: 'output',
963
+ data: {
964
+ type: 'user',
965
+ message: {
966
+ role: 'user',
967
+ content: [{
968
+ type: 'tool_result',
969
+ tool_use_id: 'perm_call',
970
+ content: 'result',
971
+ is_error: false,
972
+ permissions: {
973
+ date: 1736300000000,
974
+ result: 'approved',
975
+ mode: 'acceptEdits',
976
+ allowedTools: ['Read', 'Write'],
977
+ decision: 'approved_for_session'
978
+ }
979
+ }]
980
+ },
981
+ uuid: 'perm-uuid'
982
+ }
983
+ }
984
+ };
985
+
986
+ const result = RawRecordSchema.safeParse(messageWithPermissions);
987
+
988
+ expect(result.success).toBe(true);
989
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'user') {
990
+ const content = result.data.content.data.message.content;
991
+ if (Array.isArray(content) && content[0].type === 'tool_result') {
992
+ expect(content[0].permissions).toBeDefined();
993
+ expect(content[0].permissions?.result).toBe('approved');
994
+ expect(content[0].permissions?.mode).toBe('acceptEdits');
995
+ expect(content[0].permissions?.allowedTools).toEqual(['Read', 'Write']);
996
+ }
997
+ }
998
+ });
999
+
1000
+ it('handles tool_result with array content (text blocks)', () => {
1001
+ const messageWithArrayContent = {
1002
+ role: 'agent',
1003
+ content: {
1004
+ type: 'output',
1005
+ data: {
1006
+ type: 'user',
1007
+ message: {
1008
+ role: 'user',
1009
+ content: [{
1010
+ type: 'tool_result',
1011
+ tool_use_id: 'array_call',
1012
+ content: [
1013
+ { type: 'text', text: 'First block' },
1014
+ { type: 'text', text: 'Second block' }
1015
+ ],
1016
+ is_error: false
1017
+ }]
1018
+ },
1019
+ uuid: 'array-uuid'
1020
+ }
1021
+ }
1022
+ };
1023
+
1024
+ const result = RawRecordSchema.safeParse(messageWithArrayContent);
1025
+
1026
+ expect(result.success).toBe(true);
1027
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'user') {
1028
+ const content = result.data.content.data.message.content;
1029
+ if (Array.isArray(content) && content[0].type === 'tool_result') {
1030
+ expect(Array.isArray(content[0].content)).toBe(true);
1031
+ if (Array.isArray(content[0].content)) {
1032
+ expect(content[0].content.length).toBe(2);
1033
+ expect(content[0].content[0].text).toBe('First block');
1034
+ }
1035
+ }
1036
+ }
1037
+ });
1038
+
1039
+ it('handles metadata fields (uuid, parentUuid, isSidechain, etc.)', () => {
1040
+ const messageWithMetadata = {
1041
+ role: 'agent',
1042
+ content: {
1043
+ type: 'output',
1044
+ data: {
1045
+ type: 'assistant',
1046
+ message: {
1047
+ role: 'assistant',
1048
+ model: 'claude-3',
1049
+ content: [{ type: 'text', text: 'Test' }]
1050
+ },
1051
+ uuid: 'meta-uuid-123',
1052
+ parentUuid: 'parent-uuid-456',
1053
+ isSidechain: true,
1054
+ isCompactSummary: false,
1055
+ isMeta: false
1056
+ }
1057
+ }
1058
+ };
1059
+
1060
+ const result = RawRecordSchema.safeParse(messageWithMetadata);
1061
+
1062
+ expect(result.success).toBe(true);
1063
+ if (result.success && result.data.content.type === 'output') {
1064
+ expect(result.data.content.data.uuid).toBe('meta-uuid-123');
1065
+ expect(result.data.content.data.parentUuid).toBe('parent-uuid-456');
1066
+ expect(result.data.content.data.isSidechain).toBe(true);
1067
+ }
1068
+ });
1069
+ });
1070
+
1071
+ describe('WOLOG: Cross-agent format handling', () => {
1072
+ it('Claude SDK (underscore) passes through unchanged', () => {
1073
+ const claudeMessage = {
1074
+ role: 'agent',
1075
+ content: {
1076
+ type: 'output',
1077
+ data: {
1078
+ type: 'assistant',
1079
+ message: {
1080
+ role: 'assistant',
1081
+ model: 'claude-3',
1082
+ content: [
1083
+ { type: 'tool_use', id: 'claude_1', name: 'Bash', input: {} }
1084
+ ]
1085
+ },
1086
+ uuid: 'claude-uuid'
1087
+ }
1088
+ }
1089
+ };
1090
+
1091
+ const result = RawRecordSchema.safeParse(claudeMessage);
1092
+
1093
+ expect(result.success).toBe(true);
1094
+ // Verify underscore types remain unchanged (idempotent)
1095
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'assistant') {
1096
+ expect(result.data.content.data.message.content[0].type).toBe('tool_use');
1097
+ }
1098
+ });
1099
+
1100
+ it('Codex (hyphenated via codex path) uses native schema', () => {
1101
+ const codexMessage = {
1102
+ role: 'agent',
1103
+ content: {
1104
+ type: 'codex',
1105
+ data: {
1106
+ type: 'tool-call',
1107
+ callId: 'codex_tool',
1108
+ name: 'Read',
1109
+ input: {},
1110
+ id: 'codex-msg-id'
1111
+ }
1112
+ }
1113
+ };
1114
+
1115
+ const result = RawRecordSchema.safeParse(codexMessage);
1116
+
1117
+ expect(result.success).toBe(true);
1118
+ // Codex path keeps hyphenated types (no transformation)
1119
+ if (result.success && result.data.content.type === 'codex') {
1120
+ expect(result.data.content.data.type).toBe('tool-call');
1121
+ if (result.data.content.data.type === 'tool-call') {
1122
+ expect(result.data.content.data.callId).toBe('codex_tool');
1123
+ }
1124
+ }
1125
+ });
1126
+
1127
+ it('Gemini (uses codex path) works with hyphenated types', () => {
1128
+ // Gemini uses sendCodexMessage() in CLI, so type: 'codex'
1129
+ const geminiMessage = {
1130
+ role: 'agent',
1131
+ content: {
1132
+ type: 'codex',
1133
+ data: {
1134
+ type: 'message',
1135
+ message: 'Gemini reasoning output'
1136
+ }
1137
+ }
1138
+ };
1139
+
1140
+ const result = RawRecordSchema.safeParse(geminiMessage);
1141
+
1142
+ expect(result.success).toBe(true);
1143
+ if (result.success && result.data.content.type === 'codex' && result.data.content.data.type === 'message') {
1144
+ expect(result.data.content.data.message).toBe('Gemini reasoning output');
1145
+ }
1146
+ });
1147
+
1148
+ it('handles hypothetical hyphenated types in output path (defensive)', () => {
1149
+ // This tests the defensive nature of the transform
1150
+ // If CLI ever sends hyphenated in output path, it should work
1151
+ const hypotheticalMessage = {
1152
+ role: 'agent',
1153
+ content: {
1154
+ type: 'output',
1155
+ data: {
1156
+ type: 'assistant',
1157
+ message: {
1158
+ role: 'assistant',
1159
+ model: 'future-model',
1160
+ content: [{
1161
+ type: 'tool-call', // Hyphenated in output path
1162
+ callId: 'defensive_test',
1163
+ name: 'NewTool',
1164
+ input: { param: 'value' }
1165
+ }]
1166
+ },
1167
+ uuid: 'defensive-uuid'
1168
+ }
1169
+ }
1170
+ };
1171
+
1172
+ const result = RawRecordSchema.safeParse(hypotheticalMessage);
1173
+
1174
+ expect(result.success).toBe(true);
1175
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'assistant') {
1176
+ // Should transform to tool_use
1177
+ const item = result.data.content.data.message.content[0];
1178
+ expect(item.type).toBe('tool_use');
1179
+ if (item.type === 'tool_use') {
1180
+ expect(item.id).toBe('defensive_test');
1181
+ }
1182
+ }
1183
+ });
1184
+ });
1185
+
1186
+ describe('Regression prevention: Ensure existing behavior unchanged', () => {
1187
+ it('Zod transform produces same output as old preprocessing for canonical types', () => {
1188
+ const canonicalMessage = {
1189
+ role: 'agent',
1190
+ content: {
1191
+ type: 'output',
1192
+ data: {
1193
+ type: 'assistant',
1194
+ message: {
1195
+ role: 'assistant',
1196
+ model: 'claude-3',
1197
+ content: [
1198
+ { type: 'text', text: 'Hello' },
1199
+ { type: 'tool_use', id: 'c1', name: 'Read', input: {} }
1200
+ ]
1201
+ },
1202
+ uuid: 'regression-test'
1203
+ }
1204
+ }
1205
+ };
1206
+
1207
+ const result = RawRecordSchema.safeParse(canonicalMessage);
1208
+
1209
+ expect(result.success).toBe(true);
1210
+ // Verify output format matches what old preprocessing would produce
1211
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'assistant') {
1212
+ const content = result.data.content.data.message.content;
1213
+ expect(content[0].type).toBe('text');
1214
+ if (content[0].type === 'text') {
1215
+ expect(content[0].text).toBe('Hello');
1216
+ }
1217
+ expect(content[1].type).toBe('tool_use');
1218
+ if (content[1].type === 'tool_use') {
1219
+ expect(content[1].id).toBe('c1');
1220
+ expect(content[1].name).toBe('Read');
1221
+ expect(content[1].input).toEqual({});
1222
+ }
1223
+ }
1224
+ });
1225
+
1226
+ it('Zod transform is idempotent (applying twice produces same result)', () => {
1227
+ const message = {
1228
+ role: 'agent',
1229
+ content: {
1230
+ type: 'output',
1231
+ data: {
1232
+ type: 'assistant',
1233
+ message: {
1234
+ role: 'assistant',
1235
+ model: 'claude-3',
1236
+ content: [
1237
+ { type: 'tool-call', callId: 'idem_1', name: 'Bash', input: {} }
1238
+ ]
1239
+ },
1240
+ uuid: 'idem-uuid'
1241
+ }
1242
+ }
1243
+ };
1244
+
1245
+ // Parse once
1246
+ const firstResult = RawRecordSchema.safeParse(message);
1247
+ expect(firstResult.success).toBe(true);
1248
+
1249
+ // Parse the result again (should be idempotent)
1250
+ if (firstResult.success) {
1251
+ const secondResult = RawRecordSchema.safeParse(firstResult.data);
1252
+ expect(secondResult.success).toBe(true);
1253
+
1254
+ // Results should be identical
1255
+ expect(JSON.stringify(secondResult.data)).toBe(JSON.stringify(firstResult.data));
1256
+ }
1257
+ });
1258
+
1259
+ it('Error messages are preserved (validation still returns clear errors)', () => {
1260
+ const invalidMessage = {
1261
+ role: 'agent',
1262
+ content: {
1263
+ type: 'output',
1264
+ data: {
1265
+ type: 'assistant',
1266
+ message: {
1267
+ role: 'assistant',
1268
+ model: 'claude-3',
1269
+ content: [{
1270
+ type: 'invalid-type',
1271
+ data: 'bad'
1272
+ }]
1273
+ },
1274
+ uuid: 'error-test'
1275
+ }
1276
+ }
1277
+ };
1278
+
1279
+ const result = RawRecordSchema.safeParse(invalidMessage);
1280
+
1281
+ expect(result.success).toBe(false);
1282
+ if (!result.success) {
1283
+ // Error should be clear and actionable
1284
+ expect(result.error.issues.length).toBeGreaterThan(0);
1285
+ // Should mention union validation issue
1286
+ const errorJson = JSON.stringify(result.error.issues);
1287
+ expect(errorJson).toContain('invalid_union');
1288
+ }
1289
+ });
1290
+ });
1291
+
1292
+ describe('Unknown field preservation (WOLOG)', () => {
1293
+ it('preserves unknown fields in thinking content via .passthrough()', () => {
1294
+ const thinkingWithUnknownFields = {
1295
+ role: 'agent',
1296
+ content: {
1297
+ type: 'output',
1298
+ data: {
1299
+ type: 'assistant',
1300
+ message: {
1301
+ role: 'assistant',
1302
+ model: 'claude-3',
1303
+ content: [{
1304
+ type: 'thinking',
1305
+ thinking: 'Reasoning here',
1306
+ signature: 'EqkCCkYICxgCKkB...', // Unknown field
1307
+ futureField: 'some_value' // Unknown field
1308
+ }]
1309
+ },
1310
+ uuid: 'test-uuid'
1311
+ }
1312
+ }
1313
+ };
1314
+
1315
+ const result = RawRecordSchema.safeParse(thinkingWithUnknownFields);
1316
+
1317
+ expect(result.success).toBe(true);
1318
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'assistant') {
1319
+ const thinkingContent = result.data.content.data.message.content[0];
1320
+ if (thinkingContent.type === 'thinking') {
1321
+ // Verify unknown fields preserved
1322
+ expect((thinkingContent as any).signature).toBe('EqkCCkYICxgCKkB...');
1323
+ expect((thinkingContent as any).futureField).toBe('some_value');
1324
+ }
1325
+ }
1326
+ });
1327
+
1328
+ it('preserves unknown fields in transformed tool-call → tool_use', () => {
1329
+ const toolCallWithUnknownFields = {
1330
+ role: 'agent',
1331
+ content: {
1332
+ type: 'output',
1333
+ data: {
1334
+ type: 'assistant',
1335
+ message: {
1336
+ role: 'assistant',
1337
+ model: 'claude-3',
1338
+ content: [{
1339
+ type: 'tool-call',
1340
+ callId: 'test-call',
1341
+ name: 'Bash',
1342
+ input: { command: 'ls' },
1343
+ metadata: { timestamp: 123 }, // Unknown field
1344
+ customField: 'custom_value' // Unknown field
1345
+ }]
1346
+ },
1347
+ uuid: 'test-uuid'
1348
+ }
1349
+ }
1350
+ };
1351
+
1352
+ const result = RawRecordSchema.safeParse(toolCallWithUnknownFields);
1353
+
1354
+ expect(result.success).toBe(true);
1355
+ if (result.success && result.data.content.type === 'output' && result.data.content.data.type === 'assistant') {
1356
+ const toolUseContent = result.data.content.data.message.content[0];
1357
+ if (toolUseContent.type === 'tool_use') {
1358
+ // Verify transform preserved unknown fields
1359
+ expect(toolUseContent.id).toBe('test-call');
1360
+ expect((toolUseContent as any).metadata).toEqual({ timestamp: 123 });
1361
+ expect((toolUseContent as any).customField).toBe('custom_value');
1362
+ }
1363
+ }
1364
+ });
1365
+
1366
+ it('preserves CLI metadata fields via .passthrough()', () => {
1367
+ const messageWithMetadata = {
1368
+ role: 'agent',
1369
+ content: {
1370
+ type: 'output',
1371
+ data: {
1372
+ type: 'assistant',
1373
+ message: { role: 'assistant', model: 'claude-3', content: [] },
1374
+ uuid: 'test-uuid',
1375
+ userType: 'external', // CLI metadata
1376
+ cwd: '/path/to/project', // CLI metadata
1377
+ sessionId: 'session-123', // CLI metadata
1378
+ version: '2.1.1', // CLI metadata
1379
+ gitBranch: 'main', // CLI metadata
1380
+ slug: 'test-slug', // CLI metadata
1381
+ requestId: 'req-123', // CLI metadata
1382
+ timestamp: '2026-01-09T00:00:00.000Z' // CLI metadata
1383
+ }
1384
+ }
1385
+ };
1386
+
1387
+ const result = RawRecordSchema.safeParse(messageWithMetadata);
1388
+
1389
+ expect(result.success).toBe(true);
1390
+ if (result.success && result.data.content.type === 'output') {
1391
+ // Verify metadata preserved
1392
+ expect((result.data.content.data as any).userType).toBe('external');
1393
+ expect((result.data.content.data as any).cwd).toBe('/path/to/project');
1394
+ expect((result.data.content.data as any).sessionId).toBe('session-123');
1395
+ }
1396
+ });
1397
+
1398
+ it('END-TO-END: preserves unknown fields through normalizeRawMessage()', () => {
1399
+ const messageWithUnknownFields = {
1400
+ role: 'agent' as const,
1401
+ content: {
1402
+ type: 'output' as const,
1403
+ data: {
1404
+ type: 'assistant' as const,
1405
+ message: {
1406
+ role: 'assistant' as const,
1407
+ model: 'claude-3',
1408
+ content: [
1409
+ {
1410
+ type: 'thinking' as const,
1411
+ thinking: 'Extended thinking reasoning',
1412
+ signature: 'EqkCCkYICxgCKkB...', // Unknown field from Claude API
1413
+ customField: 'test_value' // Unknown field
1414
+ },
1415
+ {
1416
+ type: 'text' as const,
1417
+ text: 'Final response',
1418
+ metadata: { timestamp: 123 } // Unknown field
1419
+ }
1420
+ ]
1421
+ },
1422
+ uuid: 'wolog-e2e-test',
1423
+ userType: 'external' // CLI metadata (unknown to schema definition)
1424
+ }
1425
+ }
1426
+ };
1427
+
1428
+ const normalized = normalizeRawMessage('msg-1', null, Date.now(), messageWithUnknownFields);
1429
+
1430
+ expect(normalized).toBeTruthy();
1431
+ if (normalized && normalized.role === 'agent') {
1432
+ expect(normalized.content.length).toBe(2);
1433
+
1434
+ // Verify thinking content preserved unknown fields
1435
+ const thinkingItem = normalized.content[0];
1436
+ expect(thinkingItem.type).toBe('thinking');
1437
+ if (thinkingItem.type === 'thinking') {
1438
+ expect(thinkingItem.thinking).toBe('Extended thinking reasoning');
1439
+ expect((thinkingItem as any).signature).toBe('EqkCCkYICxgCKkB...');
1440
+ expect((thinkingItem as any).customField).toBe('test_value');
1441
+ }
1442
+
1443
+ // Verify text content preserved unknown fields
1444
+ const textItem = normalized.content[1];
1445
+ expect(textItem.type).toBe('text');
1446
+ if (textItem.type === 'text') {
1447
+ expect(textItem.text).toBe('Final response');
1448
+ expect((textItem as any).metadata).toEqual({ timestamp: 123 });
1449
+ }
1450
+ }
1451
+ });
1452
+
1453
+ it('END-TO-END: preserves unknown fields in transformed tool-call through normalizeRawMessage()', () => {
1454
+ const messageWithHyphenatedUnknownFields = {
1455
+ role: 'agent' as const,
1456
+ content: {
1457
+ type: 'output' as const,
1458
+ data: {
1459
+ type: 'assistant' as const,
1460
+ message: {
1461
+ role: 'assistant' as const,
1462
+ model: 'claude-3',
1463
+ content: [{
1464
+ type: 'tool-call' as const,
1465
+ callId: 'e2e-test-call',
1466
+ name: 'Bash',
1467
+ input: { command: 'ls' },
1468
+ executionMetadata: { server: 'remote' }, // Unknown field
1469
+ timestamp: 1234567890 // Unknown field
1470
+ }]
1471
+ },
1472
+ uuid: 'wolog-transform-e2e'
1473
+ }
1474
+ }
1475
+ };
1476
+
1477
+ const normalized = normalizeRawMessage('msg-2', null, Date.now(), messageWithHyphenatedUnknownFields);
1478
+
1479
+ expect(normalized).toBeTruthy();
1480
+ if (normalized && normalized.role === 'agent') {
1481
+ const toolCallItem = normalized.content[0];
1482
+ expect(toolCallItem.type).toBe('tool-call');
1483
+ if (toolCallItem.type === 'tool-call') {
1484
+ expect(toolCallItem.id).toBe('e2e-test-call');
1485
+ expect(toolCallItem.name).toBe('Bash');
1486
+ // Verify unknown fields preserved through transformation
1487
+ expect((toolCallItem as any).executionMetadata).toEqual({ server: 'remote' });
1488
+ expect((toolCallItem as any).timestamp).toBe(1234567890);
1489
+ }
1490
+ }
1491
+ });
1492
+ });
1493
+
1494
+ describe('Session protocol normalization', () => {
1495
+
1496
+ const base = {
1497
+ role: 'agent' as const,
1498
+ content: {
1499
+ type: 'session' as const,
1500
+ }
1501
+ };
1502
+
1503
+ it('normalizes text events to agent text content', () => {
1504
+ const normalized = normalizeRawMessage('db-1', null, 1, {
1505
+ ...base,
1506
+ content: {
1507
+ type: 'session',
1508
+ data: {
1509
+ id: 'env-1',
1510
+ time: 1,
1511
+ role: 'agent',
1512
+ turn: 'turn-1',
1513
+ ev: { t: 'text', text: 'hello session' }
1514
+ }
1515
+ }
1516
+ });
1517
+
1518
+ expect(normalized).toBeTruthy();
1519
+ expect(normalized?.id).toBe('env-1');
1520
+ expect(normalized?.createdAt).toBe(1);
1521
+ expect(normalized?.role).toBe('agent');
1522
+ if (normalized && normalized.role === 'agent') {
1523
+ expect(normalized.content[0]).toMatchObject({
1524
+ type: 'text',
1525
+ text: 'hello session',
1526
+ uuid: 'env-1',
1527
+ parentUUID: null
1528
+ });
1529
+ }
1530
+ });
1531
+
1532
+ it('normalizes new direct session-role envelope shape', () => {
1533
+ const normalized = normalizeRawMessage('db-1-direct', null, 1, {
1534
+ role: 'session',
1535
+ content: {
1536
+ id: 'env-1-direct',
1537
+ time: 1,
1538
+ role: 'agent',
1539
+ turn: 'turn-1',
1540
+ ev: { t: 'text', text: 'hello direct session envelope' }
1541
+ }
1542
+ } as any);
1543
+
1544
+ expect(normalized).toBeTruthy();
1545
+ expect(normalized?.id).toBe('env-1-direct');
1546
+ expect(normalized?.createdAt).toBe(1);
1547
+ expect(normalized?.role).toBe('agent');
1548
+ if (normalized && normalized.role === 'agent') {
1549
+ expect(normalized.content[0]).toMatchObject({
1550
+ type: 'text',
1551
+ text: 'hello direct session envelope',
1552
+ uuid: 'env-1-direct',
1553
+ parentUUID: null
1554
+ });
1555
+ }
1556
+ });
1557
+
1558
+ it('normalizes thinking text events', () => {
1559
+ const normalized = normalizeRawMessage('db-2', null, 1, {
1560
+ ...base,
1561
+ content: {
1562
+ type: 'session',
1563
+ data: {
1564
+ id: 'env-2',
1565
+ time: 1,
1566
+ role: 'agent',
1567
+ turn: 'turn-1',
1568
+ ev: { t: 'text', text: 'thinking...', thinking: true }
1569
+ }
1570
+ }
1571
+ });
1572
+
1573
+ expect(normalized).toBeTruthy();
1574
+ if (normalized && normalized.role === 'agent') {
1575
+ expect(normalized.content[0]).toMatchObject({
1576
+ type: 'thinking',
1577
+ thinking: 'thinking...',
1578
+ uuid: 'env-2',
1579
+ parentUUID: null
1580
+ });
1581
+ }
1582
+ });
1583
+
1584
+ it('renders session protocol user text envelopes', () => {
1585
+ const normalized = normalizeRawMessage('db-modern-user-1', null, 1, {
1586
+ role: 'session',
1587
+ content: {
1588
+ id: 'env-modern-user-1',
1589
+ time: 1,
1590
+ role: 'user',
1591
+ ev: { t: 'text', text: 'modern user envelope' }
1592
+ }
1593
+ } as any);
1594
+
1595
+ expect(normalized).toBeTruthy();
1596
+ expect(normalized?.role).toBe('user');
1597
+ if (normalized && normalized.role === 'user') {
1598
+ expect(normalized.content).toEqual({
1599
+ type: 'text',
1600
+ text: 'modern user envelope'
1601
+ });
1602
+ }
1603
+ });
1604
+
1605
+ it('renders legacy user text messages', () => {
1606
+ const normalized = normalizeRawMessage('db-legacy-user-1', null, 1, {
1607
+ role: 'user',
1608
+ content: {
1609
+ type: 'text',
1610
+ text: 'legacy user message'
1611
+ }
1612
+ } as any);
1613
+
1614
+ expect(normalized).toBeTruthy();
1615
+ expect(normalized?.role).toBe('user');
1616
+ if (normalized && normalized.role === 'user') {
1617
+ expect(normalized.content).toEqual({
1618
+ type: 'text',
1619
+ text: 'legacy user message'
1620
+ });
1621
+ }
1622
+ });
1623
+
1624
+ it('normalizes service events to visible agent text', () => {
1625
+ const normalized = normalizeRawMessage('db-service-1', null, 1, {
1626
+ ...base,
1627
+ content: {
1628
+ type: 'session',
1629
+ data: {
1630
+ id: 'env-service-1',
1631
+ time: 1,
1632
+ role: 'agent',
1633
+ turn: 'turn-service-1',
1634
+ ev: { t: 'service', text: '**Service:** Connection restored' }
1635
+ }
1636
+ }
1637
+ });
1638
+
1639
+ expect(normalized).toBeTruthy();
1640
+ expect(normalized?.role).toBe('agent');
1641
+ if (normalized && normalized.role === 'agent') {
1642
+ expect(normalized.content[0]).toMatchObject({
1643
+ type: 'text',
1644
+ text: '**Service:** Connection restored',
1645
+ uuid: 'env-service-1',
1646
+ parentUUID: null
1647
+ });
1648
+ }
1649
+ });
1650
+
1651
+ it('normalizes tool-call lifecycle events', () => {
1652
+ const start = normalizeRawMessage('db-3', null, 1, {
1653
+ ...base,
1654
+ content: {
1655
+ type: 'session',
1656
+ data: {
1657
+ id: 'env-3',
1658
+ time: 1,
1659
+ role: 'agent',
1660
+ turn: 'turn-1',
1661
+ ev: {
1662
+ t: 'tool-call-start',
1663
+ call: 'call-1',
1664
+ name: 'CodexBash',
1665
+ title: 'Run `ls`',
1666
+ description: 'Run command',
1667
+ args: { command: 'ls' }
1668
+ }
1669
+ }
1670
+ }
1671
+ });
1672
+ expect(start).toBeTruthy();
1673
+ if (start && start.role === 'agent') {
1674
+ expect(start.content[0]).toMatchObject({
1675
+ type: 'tool-call',
1676
+ id: 'call-1',
1677
+ name: 'CodexBash',
1678
+ input: { command: 'ls' }
1679
+ });
1680
+ }
1681
+
1682
+ const end = normalizeRawMessage('db-4', null, 1, {
1683
+ ...base,
1684
+ content: {
1685
+ type: 'session',
1686
+ data: {
1687
+ id: 'env-4',
1688
+ time: 1,
1689
+ role: 'agent',
1690
+ turn: 'turn-1',
1691
+ ev: {
1692
+ t: 'tool-call-end',
1693
+ call: 'call-1'
1694
+ }
1695
+ }
1696
+ }
1697
+ });
1698
+ expect(end).toBeTruthy();
1699
+ if (end && end.role === 'agent') {
1700
+ expect(end.content[0]).toMatchObject({
1701
+ type: 'tool-result',
1702
+ tool_use_id: 'call-1',
1703
+ content: null,
1704
+ is_error: false
1705
+ });
1706
+ }
1707
+ });
1708
+
1709
+ it('maps turn-end to ready event and drops turn-start', () => {
1710
+ const turnStart = normalizeRawMessage('db-5', null, 1, {
1711
+ ...base,
1712
+ content: {
1713
+ type: 'session',
1714
+ data: {
1715
+ id: 'env-5',
1716
+ time: 1,
1717
+ role: 'agent',
1718
+ turn: 'turn-5',
1719
+ ev: { t: 'turn-start' }
1720
+ }
1721
+ }
1722
+ });
1723
+ expect(turnStart).toBeNull();
1724
+
1725
+ const turnEnd = normalizeRawMessage('db-6', null, 1, {
1726
+ ...base,
1727
+ content: {
1728
+ type: 'session',
1729
+ data: {
1730
+ id: 'env-6',
1731
+ time: 1,
1732
+ role: 'agent',
1733
+ turn: 'turn-5',
1734
+ ev: { t: 'turn-end', status: 'completed' }
1735
+ }
1736
+ }
1737
+ });
1738
+ expect(turnEnd).toMatchObject({
1739
+ id: 'env-6',
1740
+ role: 'event',
1741
+ content: { type: 'ready' }
1742
+ });
1743
+ });
1744
+
1745
+ it('normalizes file events with required size and optional image metadata', () => {
1746
+ const fileOnly = normalizeRawMessage('db-file-1', null, 1, {
1747
+ ...base,
1748
+ content: {
1749
+ type: 'session',
1750
+ data: {
1751
+ id: 'env-file-1',
1752
+ time: 1,
1753
+ role: 'agent',
1754
+ turn: 'turn-file-1',
1755
+ ev: {
1756
+ t: 'file',
1757
+ ref: 'upload-file-1',
1758
+ name: 'report.pdf',
1759
+ size: 1234
1760
+ }
1761
+ }
1762
+ }
1763
+ });
1764
+
1765
+ expect(fileOnly).toBeTruthy();
1766
+ if (fileOnly && fileOnly.role === 'agent') {
1767
+ expect(fileOnly.content[0]).toMatchObject({
1768
+ type: 'tool-call',
1769
+ name: 'file',
1770
+ input: {
1771
+ ref: 'upload-file-1',
1772
+ name: 'report.pdf',
1773
+ size: 1234
1774
+ },
1775
+ description: 'Attached file: report.pdf'
1776
+ });
1777
+ // The paired tool-result is what closes out the spinner — without
1778
+ // it the chat bubble would show the running indicator forever
1779
+ // because the reducer only flips a tool-call to "completed"
1780
+ // when it sees a matching tool_use_id in a tool-result.
1781
+ expect(fileOnly.content).toHaveLength(2);
1782
+ const toolCall = fileOnly.content[0] as { type: 'tool-call'; id: string };
1783
+ expect(fileOnly.content[1]).toMatchObject({
1784
+ type: 'tool-result',
1785
+ tool_use_id: toolCall.id,
1786
+ content: null,
1787
+ is_error: false,
1788
+ });
1789
+ }
1790
+
1791
+ const imageFile = normalizeRawMessage('db-file-2', null, 1, {
1792
+ ...base,
1793
+ content: {
1794
+ type: 'session',
1795
+ data: {
1796
+ id: 'env-file-2',
1797
+ time: 1,
1798
+ role: 'agent',
1799
+ turn: 'turn-file-2',
1800
+ ev: {
1801
+ t: 'file',
1802
+ ref: 'upload-file-2',
1803
+ name: 'photo.png',
1804
+ size: 4567,
1805
+ image: {
1806
+ width: 800,
1807
+ height: 600,
1808
+ thumbhash: 'abc'
1809
+ }
1810
+ }
1811
+ }
1812
+ }
1813
+ });
1814
+
1815
+ expect(imageFile).toBeTruthy();
1816
+ if (imageFile && imageFile.role === 'agent') {
1817
+ expect(imageFile.content[0]).toMatchObject({
1818
+ type: 'tool-call',
1819
+ name: 'file',
1820
+ input: {
1821
+ ref: 'upload-file-2',
1822
+ name: 'photo.png',
1823
+ size: 4567,
1824
+ image: {
1825
+ width: 800,
1826
+ height: 600,
1827
+ thumbhash: 'abc'
1828
+ }
1829
+ },
1830
+ description: 'Attached image: photo.png (800x600)'
1831
+ });
1832
+ }
1833
+ });
1834
+
1835
+ it('rejects file events without required size', () => {
1836
+ const normalized = normalizeRawMessage('db-file-missing-size', null, 1, {
1837
+ ...base,
1838
+ content: {
1839
+ type: 'session',
1840
+ data: {
1841
+ id: 'env-file-missing-size',
1842
+ time: 1,
1843
+ role: 'agent',
1844
+ turn: 'turn-file-3',
1845
+ ev: {
1846
+ t: 'file',
1847
+ ref: 'upload-file-3',
1848
+ name: 'broken.bin'
1849
+ }
1850
+ }
1851
+ }
1852
+ } as any);
1853
+
1854
+ expect(normalized).toBeNull();
1855
+ });
1856
+
1857
+ it('marks subagent-linked messages as sidechain messages', () => {
1858
+ const subagent = createId();
1859
+ const normalized = normalizeRawMessage('db-7', null, 1, {
1860
+ ...base,
1861
+ content: {
1862
+ type: 'session',
1863
+ data: {
1864
+ id: 'env-7',
1865
+ time: 1,
1866
+ role: 'agent',
1867
+ turn: 'turn-2',
1868
+ subagent,
1869
+ ev: { t: 'text', text: 'subagent output' }
1870
+ }
1871
+ }
1872
+ });
1873
+
1874
+ expect(normalized).toBeTruthy();
1875
+ expect(normalized?.isSidechain).toBe(true);
1876
+ if (normalized && normalized.role === 'agent') {
1877
+ expect(normalized.content[0]).toMatchObject({
1878
+ parentUUID: subagent
1879
+ });
1880
+ }
1881
+ });
1882
+
1883
+ it('drops start/stop lifecycle markers', () => {
1884
+ const subagent = createId();
1885
+ const start = normalizeRawMessage('db-start-1', null, 1, {
1886
+ ...base,
1887
+ content: {
1888
+ type: 'session',
1889
+ data: {
1890
+ id: 'env-start-1',
1891
+ time: 1,
1892
+ role: 'agent',
1893
+ turn: 'turn-1',
1894
+ subagent,
1895
+ ev: { t: 'start', title: 'Research agent' }
1896
+ }
1897
+ }
1898
+ });
1899
+ expect(start).toBeNull();
1900
+
1901
+ const stop = normalizeRawMessage('db-stop-1', null, 1, {
1902
+ ...base,
1903
+ content: {
1904
+ type: 'session',
1905
+ data: {
1906
+ id: 'env-stop-1',
1907
+ time: 1,
1908
+ role: 'agent',
1909
+ turn: 'turn-1',
1910
+ subagent,
1911
+ ev: { t: 'stop' }
1912
+ }
1913
+ }
1914
+ });
1915
+ expect(stop).toBeNull();
1916
+ });
1917
+
1918
+ it('returns null for non-cuid subagent identifiers', () => {
1919
+ const normalized = normalizeRawMessage('db-subagent-invalid', null, 1, {
1920
+ ...base,
1921
+ content: {
1922
+ type: 'session',
1923
+ data: {
1924
+ id: 'env-subagent-invalid',
1925
+ time: 1,
1926
+ role: 'agent',
1927
+ turn: 'turn-1',
1928
+ subagent: 'toolu_provider_id',
1929
+ ev: { t: 'text', text: 'should be dropped' }
1930
+ }
1931
+ }
1932
+ } as any);
1933
+
1934
+ expect(normalized).toBeNull();
1935
+ });
1936
+
1937
+ it('returns null for malformed session payloads', () => {
1938
+ const normalized = normalizeRawMessage('db-8', null, 1, {
1939
+ role: 'agent',
1940
+ content: {
1941
+ type: 'session',
1942
+ data: {
1943
+ id: 'env-8',
1944
+ time: 1,
1945
+ role: 'agent',
1946
+ ev: {
1947
+ t: 'tool-call-start',
1948
+ call: 'call-1',
1949
+ name: 'Bash'
1950
+ }
1951
+ }
1952
+ }
1953
+ } as any);
1954
+
1955
+ expect(normalized).toBeNull();
1956
+ });
1957
+
1958
+ it('returns null for agent session events without turn', () => {
1959
+ const normalized = normalizeRawMessage('db-9', null, 1, {
1960
+ ...base,
1961
+ content: {
1962
+ type: 'session',
1963
+ data: {
1964
+ id: 'env-9',
1965
+ time: 1,
1966
+ role: 'agent',
1967
+ ev: { t: 'text', text: 'missing turn' }
1968
+ }
1969
+ }
1970
+ });
1971
+
1972
+ expect(normalized).toBeNull();
1973
+ });
1974
+
1975
+ it('returns null for turn-end session events without status', () => {
1976
+ const normalized = normalizeRawMessage('db-10', null, 1, {
1977
+ ...base,
1978
+ content: {
1979
+ type: 'session',
1980
+ data: {
1981
+ id: 'env-10',
1982
+ time: 1,
1983
+ role: 'agent',
1984
+ turn: 'turn-5',
1985
+ ev: { t: 'turn-end' }
1986
+ }
1987
+ }
1988
+ } as any);
1989
+
1990
+ expect(normalized).toBeNull();
1991
+ });
1992
+
1993
+ it('returns null for service events from user role', () => {
1994
+ const normalized = normalizeRawMessage('db-11', null, 1, {
1995
+ ...base,
1996
+ content: {
1997
+ type: 'session',
1998
+ data: {
1999
+ id: 'env-11',
2000
+ time: 1,
2001
+ role: 'user',
2002
+ ev: { t: 'service', text: 'not allowed' }
2003
+ }
2004
+ }
2005
+ } as any);
2006
+
2007
+ expect(normalized).toBeNull();
2008
+ });
2009
+ });
2010
+ });