@knowzai/cli 0.1.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 (578) hide show
  1. package/LICENSE +21 -0
  2. package/assets/portable/.env.example +250 -0
  3. package/assets/portable/docker-compose.yml +444 -0
  4. package/assets/portable/postgres-initdb/00-databases-and-extensions.sql +16 -0
  5. package/assets/portable/releases.json +37 -0
  6. package/assets/portable/runtime-contract.json +149 -0
  7. package/bin/run.js +4 -0
  8. package/dist/.tsbuildinfo +1 -0
  9. package/dist/base-command.d.ts +47 -0
  10. package/dist/base-command.d.ts.map +1 -0
  11. package/dist/base-command.js +98 -0
  12. package/dist/base-command.js.map +1 -0
  13. package/dist/commands/activate.d.ts +39 -0
  14. package/dist/commands/activate.d.ts.map +1 -0
  15. package/dist/commands/activate.js +103 -0
  16. package/dist/commands/activate.js.map +1 -0
  17. package/dist/commands/ask.d.ts +14 -0
  18. package/dist/commands/ask.d.ts.map +1 -0
  19. package/dist/commands/ask.js +33 -0
  20. package/dist/commands/ask.js.map +1 -0
  21. package/dist/commands/auth/status.d.ts +7 -0
  22. package/dist/commands/auth/status.d.ts.map +1 -0
  23. package/dist/commands/auth/status.js +26 -0
  24. package/dist/commands/auth/status.js.map +1 -0
  25. package/dist/commands/backup.d.ts +15 -0
  26. package/dist/commands/backup.d.ts.map +1 -0
  27. package/dist/commands/backup.js +52 -0
  28. package/dist/commands/backup.js.map +1 -0
  29. package/dist/commands/capture/observe.d.ts +23 -0
  30. package/dist/commands/capture/observe.d.ts.map +1 -0
  31. package/dist/commands/capture/observe.js +68 -0
  32. package/dist/commands/capture/observe.js.map +1 -0
  33. package/dist/commands/capture/seal.d.ts +27 -0
  34. package/dist/commands/capture/seal.d.ts.map +1 -0
  35. package/dist/commands/capture/seal.js +144 -0
  36. package/dist/commands/capture/seal.js.map +1 -0
  37. package/dist/commands/capture/status.d.ts +33 -0
  38. package/dist/commands/capture/status.d.ts.map +1 -0
  39. package/dist/commands/capture/status.js +52 -0
  40. package/dist/commands/capture/status.js.map +1 -0
  41. package/dist/commands/chat.d.ts +21 -0
  42. package/dist/commands/chat.d.ts.map +1 -0
  43. package/dist/commands/chat.js +142 -0
  44. package/dist/commands/chat.js.map +1 -0
  45. package/dist/commands/cmek/decrypt.d.ts +13 -0
  46. package/dist/commands/cmek/decrypt.d.ts.map +1 -0
  47. package/dist/commands/cmek/decrypt.js +25 -0
  48. package/dist/commands/cmek/decrypt.js.map +1 -0
  49. package/dist/commands/cmek/encrypt.d.ts +15 -0
  50. package/dist/commands/cmek/encrypt.d.ts.map +1 -0
  51. package/dist/commands/cmek/encrypt.js +26 -0
  52. package/dist/commands/cmek/encrypt.js.map +1 -0
  53. package/dist/commands/cmek/init.d.ts +13 -0
  54. package/dist/commands/cmek/init.d.ts.map +1 -0
  55. package/dist/commands/cmek/init.js +27 -0
  56. package/dist/commands/cmek/init.js.map +1 -0
  57. package/dist/commands/cmek/status.d.ts +11 -0
  58. package/dist/commands/cmek/status.d.ts.map +1 -0
  59. package/dist/commands/cmek/status.js +23 -0
  60. package/dist/commands/cmek/status.js.map +1 -0
  61. package/dist/commands/completion.d.ts +13 -0
  62. package/dist/commands/completion.d.ts.map +1 -0
  63. package/dist/commands/completion.js +19 -0
  64. package/dist/commands/completion.js.map +1 -0
  65. package/dist/commands/config/get.d.ts +13 -0
  66. package/dist/commands/config/get.d.ts.map +1 -0
  67. package/dist/commands/config/get.js +28 -0
  68. package/dist/commands/config/get.js.map +1 -0
  69. package/dist/commands/config/list.d.ts +7 -0
  70. package/dist/commands/config/list.d.ts.map +1 -0
  71. package/dist/commands/config/list.js +28 -0
  72. package/dist/commands/config/list.js.map +1 -0
  73. package/dist/commands/config/path.d.ts +9 -0
  74. package/dist/commands/config/path.d.ts.map +1 -0
  75. package/dist/commands/config/path.js +15 -0
  76. package/dist/commands/config/path.js.map +1 -0
  77. package/dist/commands/config/set.d.ts +16 -0
  78. package/dist/commands/config/set.d.ts.map +1 -0
  79. package/dist/commands/config/set.js +36 -0
  80. package/dist/commands/config/set.js.map +1 -0
  81. package/dist/commands/doctor.d.ts +56 -0
  82. package/dist/commands/doctor.d.ts.map +1 -0
  83. package/dist/commands/doctor.js +151 -0
  84. package/dist/commands/doctor.js.map +1 -0
  85. package/dist/commands/down.d.ts +30 -0
  86. package/dist/commands/down.d.ts.map +1 -0
  87. package/dist/commands/down.js +20 -0
  88. package/dist/commands/down.js.map +1 -0
  89. package/dist/commands/entities/find.d.ts +16 -0
  90. package/dist/commands/entities/find.d.ts.map +1 -0
  91. package/dist/commands/entities/find.js +27 -0
  92. package/dist/commands/entities/find.js.map +1 -0
  93. package/dist/commands/hooks/install.d.ts +19 -0
  94. package/dist/commands/hooks/install.d.ts.map +1 -0
  95. package/dist/commands/hooks/install.js +53 -0
  96. package/dist/commands/hooks/install.js.map +1 -0
  97. package/dist/commands/index/graph.d.ts +11 -0
  98. package/dist/commands/index/graph.d.ts.map +1 -0
  99. package/dist/commands/index/graph.js +31 -0
  100. package/dist/commands/index/graph.js.map +1 -0
  101. package/dist/commands/index/scan.d.ts +22 -0
  102. package/dist/commands/index/scan.d.ts.map +1 -0
  103. package/dist/commands/index/scan.js +48 -0
  104. package/dist/commands/index/scan.js.map +1 -0
  105. package/dist/commands/index/search.d.ts +18 -0
  106. package/dist/commands/index/search.d.ts.map +1 -0
  107. package/dist/commands/index/search.js +40 -0
  108. package/dist/commands/index/search.js.map +1 -0
  109. package/dist/commands/ingest/add.d.ts +15 -0
  110. package/dist/commands/ingest/add.d.ts.map +1 -0
  111. package/dist/commands/ingest/add.js +50 -0
  112. package/dist/commands/ingest/add.js.map +1 -0
  113. package/dist/commands/knowledge/amend.d.ts +19 -0
  114. package/dist/commands/knowledge/amend.d.ts.map +1 -0
  115. package/dist/commands/knowledge/amend.js +27 -0
  116. package/dist/commands/knowledge/amend.js.map +1 -0
  117. package/dist/commands/knowledge/comment.d.ts +16 -0
  118. package/dist/commands/knowledge/comment.d.ts.map +1 -0
  119. package/dist/commands/knowledge/comment.js +27 -0
  120. package/dist/commands/knowledge/comment.js.map +1 -0
  121. package/dist/commands/knowledge/comments.d.ts +11 -0
  122. package/dist/commands/knowledge/comments.d.ts.map +1 -0
  123. package/dist/commands/knowledge/comments.js +20 -0
  124. package/dist/commands/knowledge/comments.js.map +1 -0
  125. package/dist/commands/knowledge/create.d.ts +18 -0
  126. package/dist/commands/knowledge/create.d.ts.map +1 -0
  127. package/dist/commands/knowledge/create.js +45 -0
  128. package/dist/commands/knowledge/create.js.map +1 -0
  129. package/dist/commands/knowledge/delete.d.ts +14 -0
  130. package/dist/commands/knowledge/delete.d.ts.map +1 -0
  131. package/dist/commands/knowledge/delete.js +30 -0
  132. package/dist/commands/knowledge/delete.js.map +1 -0
  133. package/dist/commands/knowledge/get.d.ts +13 -0
  134. package/dist/commands/knowledge/get.d.ts.map +1 -0
  135. package/dist/commands/knowledge/get.js +20 -0
  136. package/dist/commands/knowledge/get.js.map +1 -0
  137. package/dist/commands/knowledge/list.d.ts +13 -0
  138. package/dist/commands/knowledge/list.d.ts.map +1 -0
  139. package/dist/commands/knowledge/list.js +31 -0
  140. package/dist/commands/knowledge/list.js.map +1 -0
  141. package/dist/commands/knowledge/status.d.ts +11 -0
  142. package/dist/commands/knowledge/status.d.ts.map +1 -0
  143. package/dist/commands/knowledge/status.js +23 -0
  144. package/dist/commands/knowledge/status.js.map +1 -0
  145. package/dist/commands/knowledge/update.d.ts +16 -0
  146. package/dist/commands/knowledge/update.d.ts.map +1 -0
  147. package/dist/commands/knowledge/update.js +32 -0
  148. package/dist/commands/knowledge/update.js.map +1 -0
  149. package/dist/commands/knowledge/versions.d.ts +11 -0
  150. package/dist/commands/knowledge/versions.d.ts.map +1 -0
  151. package/dist/commands/knowledge/versions.js +22 -0
  152. package/dist/commands/knowledge/versions.js.map +1 -0
  153. package/dist/commands/local/info.d.ts +17 -0
  154. package/dist/commands/local/info.d.ts.map +1 -0
  155. package/dist/commands/local/info.js +26 -0
  156. package/dist/commands/local/info.js.map +1 -0
  157. package/dist/commands/local/init.d.ts +16 -0
  158. package/dist/commands/local/init.d.ts.map +1 -0
  159. package/dist/commands/local/init.js +31 -0
  160. package/dist/commands/local/init.js.map +1 -0
  161. package/dist/commands/local/list.d.ts +13 -0
  162. package/dist/commands/local/list.d.ts.map +1 -0
  163. package/dist/commands/local/list.js +29 -0
  164. package/dist/commands/local/list.js.map +1 -0
  165. package/dist/commands/local/reset.d.ts +12 -0
  166. package/dist/commands/local/reset.d.ts.map +1 -0
  167. package/dist/commands/local/reset.js +34 -0
  168. package/dist/commands/local/reset.js.map +1 -0
  169. package/dist/commands/local/show.d.ts +15 -0
  170. package/dist/commands/local/show.d.ts.map +1 -0
  171. package/dist/commands/local/show.js +33 -0
  172. package/dist/commands/local/show.js.map +1 -0
  173. package/dist/commands/login.d.ts +23 -0
  174. package/dist/commands/login.d.ts.map +1 -0
  175. package/dist/commands/login.js +139 -0
  176. package/dist/commands/login.js.map +1 -0
  177. package/dist/commands/logout.d.ts +11 -0
  178. package/dist/commands/logout.d.ts.map +1 -0
  179. package/dist/commands/logout.js +23 -0
  180. package/dist/commands/logout.js.map +1 -0
  181. package/dist/commands/menu.d.ts +10 -0
  182. package/dist/commands/menu.d.ts.map +1 -0
  183. package/dist/commands/menu.js +50 -0
  184. package/dist/commands/menu.js.map +1 -0
  185. package/dist/commands/pg/destroy.d.ts +13 -0
  186. package/dist/commands/pg/destroy.d.ts.map +1 -0
  187. package/dist/commands/pg/destroy.js +36 -0
  188. package/dist/commands/pg/destroy.js.map +1 -0
  189. package/dist/commands/pg/down.d.ts +12 -0
  190. package/dist/commands/pg/down.d.ts.map +1 -0
  191. package/dist/commands/pg/down.js +20 -0
  192. package/dist/commands/pg/down.js.map +1 -0
  193. package/dist/commands/pg/status.d.ts +13 -0
  194. package/dist/commands/pg/status.d.ts.map +1 -0
  195. package/dist/commands/pg/status.js +28 -0
  196. package/dist/commands/pg/status.js.map +1 -0
  197. package/dist/commands/pg/up.d.ts +13 -0
  198. package/dist/commands/pg/up.d.ts.map +1 -0
  199. package/dist/commands/pg/up.js +34 -0
  200. package/dist/commands/pg/up.js.map +1 -0
  201. package/dist/commands/platform/destroy.d.ts +18 -0
  202. package/dist/commands/platform/destroy.d.ts.map +1 -0
  203. package/dist/commands/platform/destroy.js +41 -0
  204. package/dist/commands/platform/destroy.js.map +1 -0
  205. package/dist/commands/platform/doctor.d.ts +11 -0
  206. package/dist/commands/platform/doctor.d.ts.map +1 -0
  207. package/dist/commands/platform/doctor.js +18 -0
  208. package/dist/commands/platform/doctor.js.map +1 -0
  209. package/dist/commands/platform/down.d.ts +26 -0
  210. package/dist/commands/platform/down.d.ts.map +1 -0
  211. package/dist/commands/platform/down.js +16 -0
  212. package/dist/commands/platform/down.js.map +1 -0
  213. package/dist/commands/platform/logs.d.ts +26 -0
  214. package/dist/commands/platform/logs.d.ts.map +1 -0
  215. package/dist/commands/platform/logs.js +24 -0
  216. package/dist/commands/platform/logs.js.map +1 -0
  217. package/dist/commands/platform/reset.d.ts +26 -0
  218. package/dist/commands/platform/reset.d.ts.map +1 -0
  219. package/dist/commands/platform/reset.js +49 -0
  220. package/dist/commands/platform/reset.js.map +1 -0
  221. package/dist/commands/platform/setup.d.ts +24 -0
  222. package/dist/commands/platform/setup.d.ts.map +1 -0
  223. package/dist/commands/platform/setup.js +21 -0
  224. package/dist/commands/platform/setup.js.map +1 -0
  225. package/dist/commands/platform/status.d.ts +28 -0
  226. package/dist/commands/platform/status.d.ts.map +1 -0
  227. package/dist/commands/platform/status.js +37 -0
  228. package/dist/commands/platform/status.js.map +1 -0
  229. package/dist/commands/platform/up.d.ts +42 -0
  230. package/dist/commands/platform/up.d.ts.map +1 -0
  231. package/dist/commands/platform/up.js +22 -0
  232. package/dist/commands/platform/up.js.map +1 -0
  233. package/dist/commands/platform/upgrade.d.ts +14 -0
  234. package/dist/commands/platform/upgrade.d.ts.map +1 -0
  235. package/dist/commands/platform/upgrade.js +22 -0
  236. package/dist/commands/platform/upgrade.js.map +1 -0
  237. package/dist/commands/profile/add.d.ts +18 -0
  238. package/dist/commands/profile/add.d.ts.map +1 -0
  239. package/dist/commands/profile/add.js +26 -0
  240. package/dist/commands/profile/add.js.map +1 -0
  241. package/dist/commands/profile/list.d.ts +10 -0
  242. package/dist/commands/profile/list.d.ts.map +1 -0
  243. package/dist/commands/profile/list.js +20 -0
  244. package/dist/commands/profile/list.js.map +1 -0
  245. package/dist/commands/profile/remove.d.ts +15 -0
  246. package/dist/commands/profile/remove.d.ts.map +1 -0
  247. package/dist/commands/profile/remove.js +19 -0
  248. package/dist/commands/profile/remove.js.map +1 -0
  249. package/dist/commands/profile/use.d.ts +12 -0
  250. package/dist/commands/profile/use.d.ts.map +1 -0
  251. package/dist/commands/profile/use.js +18 -0
  252. package/dist/commands/profile/use.js.map +1 -0
  253. package/dist/commands/recall.d.ts +29 -0
  254. package/dist/commands/recall.d.ts.map +1 -0
  255. package/dist/commands/recall.js +94 -0
  256. package/dist/commands/recall.js.map +1 -0
  257. package/dist/commands/repo/context.d.ts +24 -0
  258. package/dist/commands/repo/context.d.ts.map +1 -0
  259. package/dist/commands/repo/context.js +52 -0
  260. package/dist/commands/repo/context.js.map +1 -0
  261. package/dist/commands/repo/graph.d.ts +24 -0
  262. package/dist/commands/repo/graph.d.ts.map +1 -0
  263. package/dist/commands/repo/graph.js +72 -0
  264. package/dist/commands/repo/graph.js.map +1 -0
  265. package/dist/commands/repo/index/index.d.ts +28 -0
  266. package/dist/commands/repo/index/index.d.ts.map +1 -0
  267. package/dist/commands/repo/index/index.js +76 -0
  268. package/dist/commands/repo/index/index.js.map +1 -0
  269. package/dist/commands/repo/search.d.ts +22 -0
  270. package/dist/commands/repo/search.d.ts.map +1 -0
  271. package/dist/commands/repo/search.js +50 -0
  272. package/dist/commands/repo/search.js.map +1 -0
  273. package/dist/commands/repo/setup.d.ts +41 -0
  274. package/dist/commands/repo/setup.d.ts.map +1 -0
  275. package/dist/commands/repo/setup.js +144 -0
  276. package/dist/commands/repo/setup.js.map +1 -0
  277. package/dist/commands/repo/status.d.ts +31 -0
  278. package/dist/commands/repo/status.d.ts.map +1 -0
  279. package/dist/commands/repo/status.js +60 -0
  280. package/dist/commands/repo/status.js.map +1 -0
  281. package/dist/commands/restore.d.ts +16 -0
  282. package/dist/commands/restore.d.ts.map +1 -0
  283. package/dist/commands/restore.js +53 -0
  284. package/dist/commands/restore.js.map +1 -0
  285. package/dist/commands/search.d.ts +14 -0
  286. package/dist/commands/search.d.ts.map +1 -0
  287. package/dist/commands/search.js +32 -0
  288. package/dist/commands/search.js.map +1 -0
  289. package/dist/commands/setup.d.ts +24 -0
  290. package/dist/commands/setup.d.ts.map +1 -0
  291. package/dist/commands/setup.js +21 -0
  292. package/dist/commands/setup.js.map +1 -0
  293. package/dist/commands/stats.d.ts +6 -0
  294. package/dist/commands/stats.d.ts.map +1 -0
  295. package/dist/commands/stats.js +16 -0
  296. package/dist/commands/stats.js.map +1 -0
  297. package/dist/commands/status.d.ts +20 -0
  298. package/dist/commands/status.d.ts.map +1 -0
  299. package/dist/commands/status.js +33 -0
  300. package/dist/commands/status.js.map +1 -0
  301. package/dist/commands/sync/conflicts.d.ts +14 -0
  302. package/dist/commands/sync/conflicts.d.ts.map +1 -0
  303. package/dist/commands/sync/conflicts.js +23 -0
  304. package/dist/commands/sync/conflicts.js.map +1 -0
  305. package/dist/commands/sync/pull.d.ts +13 -0
  306. package/dist/commands/sync/pull.d.ts.map +1 -0
  307. package/dist/commands/sync/pull.js +26 -0
  308. package/dist/commands/sync/pull.js.map +1 -0
  309. package/dist/commands/sync/push.d.ts +13 -0
  310. package/dist/commands/sync/push.d.ts.map +1 -0
  311. package/dist/commands/sync/push.js +26 -0
  312. package/dist/commands/sync/push.js.map +1 -0
  313. package/dist/commands/sync/recover.d.ts +16 -0
  314. package/dist/commands/sync/recover.d.ts.map +1 -0
  315. package/dist/commands/sync/recover.js +29 -0
  316. package/dist/commands/sync/recover.js.map +1 -0
  317. package/dist/commands/sync/resolve.d.ts +21 -0
  318. package/dist/commands/sync/resolve.d.ts.map +1 -0
  319. package/dist/commands/sync/resolve.js +38 -0
  320. package/dist/commands/sync/resolve.js.map +1 -0
  321. package/dist/commands/sync/run.d.ts +13 -0
  322. package/dist/commands/sync/run.d.ts.map +1 -0
  323. package/dist/commands/sync/run.js +26 -0
  324. package/dist/commands/sync/run.js.map +1 -0
  325. package/dist/commands/sync/status.d.ts +13 -0
  326. package/dist/commands/sync/status.d.ts.map +1 -0
  327. package/dist/commands/sync/status.js +28 -0
  328. package/dist/commands/sync/status.js.map +1 -0
  329. package/dist/commands/topics/list.d.ts +11 -0
  330. package/dist/commands/topics/list.d.ts.map +1 -0
  331. package/dist/commands/topics/list.js +20 -0
  332. package/dist/commands/topics/list.js.map +1 -0
  333. package/dist/commands/tui.d.ts +10 -0
  334. package/dist/commands/tui.d.ts.map +1 -0
  335. package/dist/commands/tui.js +124 -0
  336. package/dist/commands/tui.js.map +1 -0
  337. package/dist/commands/up.d.ts +108 -0
  338. package/dist/commands/up.d.ts.map +1 -0
  339. package/dist/commands/up.js +210 -0
  340. package/dist/commands/up.js.map +1 -0
  341. package/dist/commands/vault/contents.d.ts +14 -0
  342. package/dist/commands/vault/contents.d.ts.map +1 -0
  343. package/dist/commands/vault/contents.js +24 -0
  344. package/dist/commands/vault/contents.js.map +1 -0
  345. package/dist/commands/vault/create.d.ts +15 -0
  346. package/dist/commands/vault/create.d.ts.map +1 -0
  347. package/dist/commands/vault/create.js +26 -0
  348. package/dist/commands/vault/create.js.map +1 -0
  349. package/dist/commands/vault/get.d.ts +10 -0
  350. package/dist/commands/vault/get.d.ts.map +1 -0
  351. package/dist/commands/vault/get.js +25 -0
  352. package/dist/commands/vault/get.js.map +1 -0
  353. package/dist/commands/vault/list.d.ts +7 -0
  354. package/dist/commands/vault/list.d.ts.map +1 -0
  355. package/dist/commands/vault/list.js +17 -0
  356. package/dist/commands/vault/list.js.map +1 -0
  357. package/dist/commands/web.d.ts +14 -0
  358. package/dist/commands/web.d.ts.map +1 -0
  359. package/dist/commands/web.js +50 -0
  360. package/dist/commands/web.js.map +1 -0
  361. package/dist/commands/whoami.d.ts +7 -0
  362. package/dist/commands/whoami.d.ts.map +1 -0
  363. package/dist/commands/whoami.js +24 -0
  364. package/dist/commands/whoami.js.map +1 -0
  365. package/dist/hooks/init/launch-menu.d.ts +10 -0
  366. package/dist/hooks/init/launch-menu.d.ts.map +1 -0
  367. package/dist/hooks/init/launch-menu.js +11 -0
  368. package/dist/hooks/init/launch-menu.js.map +1 -0
  369. package/dist/lib/activate.d.ts +92 -0
  370. package/dist/lib/activate.d.ts.map +1 -0
  371. package/dist/lib/activate.js +292 -0
  372. package/dist/lib/activate.js.map +1 -0
  373. package/dist/lib/browser.d.ts +30 -0
  374. package/dist/lib/browser.d.ts.map +1 -0
  375. package/dist/lib/browser.js +45 -0
  376. package/dist/lib/browser.js.map +1 -0
  377. package/dist/lib/chat.d.ts +41 -0
  378. package/dist/lib/chat.d.ts.map +1 -0
  379. package/dist/lib/chat.js +63 -0
  380. package/dist/lib/chat.js.map +1 -0
  381. package/dist/lib/claude-hooks.d.ts +34 -0
  382. package/dist/lib/claude-hooks.d.ts.map +1 -0
  383. package/dist/lib/claude-hooks.js +85 -0
  384. package/dist/lib/claude-hooks.js.map +1 -0
  385. package/dist/lib/completion.d.ts +9 -0
  386. package/dist/lib/completion.d.ts.map +1 -0
  387. package/dist/lib/completion.js +57 -0
  388. package/dist/lib/completion.js.map +1 -0
  389. package/dist/lib/container-engine.d.ts +45 -0
  390. package/dist/lib/container-engine.d.ts.map +1 -0
  391. package/dist/lib/container-engine.js +348 -0
  392. package/dist/lib/container-engine.js.map +1 -0
  393. package/dist/lib/content.d.ts +9 -0
  394. package/dist/lib/content.d.ts.map +1 -0
  395. package/dist/lib/content.js +20 -0
  396. package/dist/lib/content.js.map +1 -0
  397. package/dist/lib/doctor-fixture.d.ts +8 -0
  398. package/dist/lib/doctor-fixture.d.ts.map +1 -0
  399. package/dist/lib/doctor-fixture.js +50 -0
  400. package/dist/lib/doctor-fixture.js.map +1 -0
  401. package/dist/lib/embedding-guard.d.ts +34 -0
  402. package/dist/lib/embedding-guard.d.ts.map +1 -0
  403. package/dist/lib/embedding-guard.js +50 -0
  404. package/dist/lib/embedding-guard.js.map +1 -0
  405. package/dist/lib/hook-io.d.ts +24 -0
  406. package/dist/lib/hook-io.d.ts.map +1 -0
  407. package/dist/lib/hook-io.js +73 -0
  408. package/dist/lib/hook-io.js.map +1 -0
  409. package/dist/lib/ingest.d.ts +24 -0
  410. package/dist/lib/ingest.d.ts.map +1 -0
  411. package/dist/lib/ingest.js +44 -0
  412. package/dist/lib/ingest.js.map +1 -0
  413. package/dist/lib/login.d.ts +40 -0
  414. package/dist/lib/login.d.ts.map +1 -0
  415. package/dist/lib/login.js +56 -0
  416. package/dist/lib/login.js.map +1 -0
  417. package/dist/lib/pending-captures.d.ts +25 -0
  418. package/dist/lib/pending-captures.d.ts.map +1 -0
  419. package/dist/lib/pending-captures.js +143 -0
  420. package/dist/lib/pending-captures.js.map +1 -0
  421. package/dist/lib/platform-backup.d.ts +110 -0
  422. package/dist/lib/platform-backup.d.ts.map +1 -0
  423. package/dist/lib/platform-backup.js +579 -0
  424. package/dist/lib/platform-backup.js.map +1 -0
  425. package/dist/lib/platform-command-shared.d.ts +132 -0
  426. package/dist/lib/platform-command-shared.d.ts.map +1 -0
  427. package/dist/lib/platform-command-shared.js +159 -0
  428. package/dist/lib/platform-command-shared.js.map +1 -0
  429. package/dist/lib/platform-frontdoor-runtime.d.ts +33 -0
  430. package/dist/lib/platform-frontdoor-runtime.d.ts.map +1 -0
  431. package/dist/lib/platform-frontdoor-runtime.js +285 -0
  432. package/dist/lib/platform-frontdoor-runtime.js.map +1 -0
  433. package/dist/lib/platform-frontdoor.d.ts +155 -0
  434. package/dist/lib/platform-frontdoor.d.ts.map +1 -0
  435. package/dist/lib/platform-frontdoor.js +467 -0
  436. package/dist/lib/platform-frontdoor.js.map +1 -0
  437. package/dist/lib/platform-image-source.d.ts +81 -0
  438. package/dist/lib/platform-image-source.d.ts.map +1 -0
  439. package/dist/lib/platform-image-source.js +143 -0
  440. package/dist/lib/platform-image-source.js.map +1 -0
  441. package/dist/lib/platform-lifecycle.d.ts +112 -0
  442. package/dist/lib/platform-lifecycle.d.ts.map +1 -0
  443. package/dist/lib/platform-lifecycle.js +725 -0
  444. package/dist/lib/platform-lifecycle.js.map +1 -0
  445. package/dist/lib/platform-onboarding.d.ts +128 -0
  446. package/dist/lib/platform-onboarding.d.ts.map +1 -0
  447. package/dist/lib/platform-onboarding.js +227 -0
  448. package/dist/lib/platform-onboarding.js.map +1 -0
  449. package/dist/lib/platform-preflight.d.ts +48 -0
  450. package/dist/lib/platform-preflight.d.ts.map +1 -0
  451. package/dist/lib/platform-preflight.js +90 -0
  452. package/dist/lib/platform-preflight.js.map +1 -0
  453. package/dist/lib/platform-profile-purge.d.ts +18 -0
  454. package/dist/lib/platform-profile-purge.d.ts.map +1 -0
  455. package/dist/lib/platform-profile-purge.js +26 -0
  456. package/dist/lib/platform-profile-purge.js.map +1 -0
  457. package/dist/lib/platform-provider-fields.d.ts +2 -0
  458. package/dist/lib/platform-provider-fields.d.ts.map +1 -0
  459. package/dist/lib/platform-provider-fields.js +2 -0
  460. package/dist/lib/platform-provider-fields.js.map +1 -0
  461. package/dist/lib/platform-provider-probe.d.ts +75 -0
  462. package/dist/lib/platform-provider-probe.d.ts.map +1 -0
  463. package/dist/lib/platform-provider-probe.js +781 -0
  464. package/dist/lib/platform-provider-probe.js.map +1 -0
  465. package/dist/lib/platform-provider-prompt.d.ts +118 -0
  466. package/dist/lib/platform-provider-prompt.d.ts.map +1 -0
  467. package/dist/lib/platform-provider-prompt.js +245 -0
  468. package/dist/lib/platform-provider-prompt.js.map +1 -0
  469. package/dist/lib/platform-release-manifest.d.ts +34 -0
  470. package/dist/lib/platform-release-manifest.d.ts.map +1 -0
  471. package/dist/lib/platform-release-manifest.js +100 -0
  472. package/dist/lib/platform-release-manifest.js.map +1 -0
  473. package/dist/lib/platform-runtime.d.ts +212 -0
  474. package/dist/lib/platform-runtime.d.ts.map +1 -0
  475. package/dist/lib/platform-runtime.js +866 -0
  476. package/dist/lib/platform-runtime.js.map +1 -0
  477. package/dist/lib/poll.d.ts +9 -0
  478. package/dist/lib/poll.d.ts.map +1 -0
  479. package/dist/lib/poll.js +18 -0
  480. package/dist/lib/poll.js.map +1 -0
  481. package/dist/lib/prompt.d.ts +7 -0
  482. package/dist/lib/prompt.d.ts.map +1 -0
  483. package/dist/lib/prompt.js +28 -0
  484. package/dist/lib/prompt.js.map +1 -0
  485. package/dist/lib/provider-presets.d.ts +108 -0
  486. package/dist/lib/provider-presets.d.ts.map +1 -0
  487. package/dist/lib/provider-presets.js +184 -0
  488. package/dist/lib/provider-presets.js.map +1 -0
  489. package/dist/lib/recall.d.ts +32 -0
  490. package/dist/lib/recall.d.ts.map +1 -0
  491. package/dist/lib/recall.js +69 -0
  492. package/dist/lib/recall.js.map +1 -0
  493. package/dist/lib/redact.d.ts +41 -0
  494. package/dist/lib/redact.d.ts.map +1 -0
  495. package/dist/lib/redact.js +130 -0
  496. package/dist/lib/redact.js.map +1 -0
  497. package/dist/lib/render.d.ts +55 -0
  498. package/dist/lib/render.d.ts.map +1 -0
  499. package/dist/lib/render.js +172 -0
  500. package/dist/lib/render.js.map +1 -0
  501. package/dist/lib/repo-binding.d.ts +53 -0
  502. package/dist/lib/repo-binding.d.ts.map +1 -0
  503. package/dist/lib/repo-binding.js +127 -0
  504. package/dist/lib/repo-binding.js.map +1 -0
  505. package/dist/lib/repo-command-support.d.ts +18 -0
  506. package/dist/lib/repo-command-support.d.ts.map +1 -0
  507. package/dist/lib/repo-command-support.js +54 -0
  508. package/dist/lib/repo-command-support.js.map +1 -0
  509. package/dist/lib/seal-core.d.ts +34 -0
  510. package/dist/lib/seal-core.d.ts.map +1 -0
  511. package/dist/lib/seal-core.js +154 -0
  512. package/dist/lib/seal-core.js.map +1 -0
  513. package/dist/lib/setup-console.d.ts +46 -0
  514. package/dist/lib/setup-console.d.ts.map +1 -0
  515. package/dist/lib/setup-console.js +191 -0
  516. package/dist/lib/setup-console.js.map +1 -0
  517. package/dist/lib/setup-page.d.ts +21 -0
  518. package/dist/lib/setup-page.d.ts.map +1 -0
  519. package/dist/lib/setup-page.js +656 -0
  520. package/dist/lib/setup-page.js.map +1 -0
  521. package/dist/lib/setup-plan.d.ts +52 -0
  522. package/dist/lib/setup-plan.d.ts.map +1 -0
  523. package/dist/lib/setup-plan.js +154 -0
  524. package/dist/lib/setup-plan.js.map +1 -0
  525. package/dist/lib/setup-server.d.ts +71 -0
  526. package/dist/lib/setup-server.d.ts.map +1 -0
  527. package/dist/lib/setup-server.js +936 -0
  528. package/dist/lib/setup-server.js.map +1 -0
  529. package/dist/lib/tui.d.ts +77 -0
  530. package/dist/lib/tui.d.ts.map +1 -0
  531. package/dist/lib/tui.js +126 -0
  532. package/dist/lib/tui.js.map +1 -0
  533. package/dist/lib/ui.d.ts +23 -0
  534. package/dist/lib/ui.d.ts.map +1 -0
  535. package/dist/lib/ui.js +100 -0
  536. package/dist/lib/ui.js.map +1 -0
  537. package/dist/lib/vault.d.ts +10 -0
  538. package/dist/lib/vault.d.ts.map +1 -0
  539. package/dist/lib/vault.js +18 -0
  540. package/dist/lib/vault.js.map +1 -0
  541. package/dist/menu/forms.d.ts +13 -0
  542. package/dist/menu/forms.d.ts.map +1 -0
  543. package/dist/menu/forms.js +45 -0
  544. package/dist/menu/forms.js.map +1 -0
  545. package/dist/menu/frontends.d.ts +32 -0
  546. package/dist/menu/frontends.d.ts.map +1 -0
  547. package/dist/menu/frontends.js +31 -0
  548. package/dist/menu/frontends.js.map +1 -0
  549. package/dist/menu/help.d.ts +11 -0
  550. package/dist/menu/help.d.ts.map +1 -0
  551. package/dist/menu/help.js +33 -0
  552. package/dist/menu/help.js.map +1 -0
  553. package/dist/menu/palette.d.ts +28 -0
  554. package/dist/menu/palette.d.ts.map +1 -0
  555. package/dist/menu/palette.js +57 -0
  556. package/dist/menu/palette.js.map +1 -0
  557. package/dist/menu/reducer.d.ts +19 -0
  558. package/dist/menu/reducer.d.ts.map +1 -0
  559. package/dist/menu/reducer.js +37 -0
  560. package/dist/menu/reducer.js.map +1 -0
  561. package/dist/menu/run.d.ts +34 -0
  562. package/dist/menu/run.d.ts.map +1 -0
  563. package/dist/menu/run.js +490 -0
  564. package/dist/menu/run.js.map +1 -0
  565. package/dist/menu/screens.d.ts +15 -0
  566. package/dist/menu/screens.d.ts.map +1 -0
  567. package/dist/menu/screens.js +251 -0
  568. package/dist/menu/screens.js.map +1 -0
  569. package/dist/menu/should-launch.d.ts +19 -0
  570. package/dist/menu/should-launch.d.ts.map +1 -0
  571. package/dist/menu/should-launch.js +22 -0
  572. package/dist/menu/should-launch.js.map +1 -0
  573. package/dist/menu/types.d.ts +95 -0
  574. package/dist/menu/types.d.ts.map +1 -0
  575. package/dist/menu/types.js +7 -0
  576. package/dist/menu/types.js.map +1 -0
  577. package/oclif.manifest.json +7995 -0
  578. package/package.json +133 -0
@@ -0,0 +1,936 @@
1
+ import { randomBytes as cryptoRandomBytes } from 'node:crypto';
2
+ import { Buffer } from 'node:buffer';
3
+ import { serve } from '@hono/node-server';
4
+ import { Hono } from 'hono';
5
+ import { createRedactor, registerSecret, validateCloudAiKeyFormat } from '@knowzai/core';
6
+ import { PLATFORM_SECRET_KEYS, redactPlatformSecrets, validatePort, validatePublicUrl, validateStorageMode, } from './platform-runtime.js';
7
+ import { renderPage } from './setup-page.js';
8
+ import { setupPlanToFrontDoorInput, } from './setup-plan.js';
9
+ import { PROVIDER_PRESETS } from './provider-presets.js';
10
+ import { validateModelName, } from './platform-provider-probe.js';
11
+ const BODY_LIMIT = 64 * 1024;
12
+ export const SETUP_IDLE_TIMEOUT_MS = 15 * 60 * 1_000;
13
+ const realClock = {
14
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
15
+ clearTimeout: (id) => clearTimeout(id),
16
+ };
17
+ export function mintSetupToken(randomBytes = cryptoRandomBytes) {
18
+ return Buffer.from(randomBytes(32)).toString('hex');
19
+ }
20
+ function isRecord(value) {
21
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
22
+ }
23
+ function containsPlatformSecretKey(value) {
24
+ if (!isRecord(value))
25
+ return false;
26
+ for (const [key, nested] of Object.entries(value)) {
27
+ if (PLATFORM_SECRET_KEYS.includes(key))
28
+ return true;
29
+ if (containsPlatformSecretKey(nested))
30
+ return true;
31
+ }
32
+ return false;
33
+ }
34
+ function registerCollectedSecrets(value) {
35
+ if (!isRecord(value))
36
+ return;
37
+ for (const [key, nested] of Object.entries(value)) {
38
+ if (typeof nested === 'string' && /(apiKey|token|password|secret|credential|passphrase)/i.test(key)) {
39
+ registerSecret(nested);
40
+ }
41
+ else if (isRecord(nested)) {
42
+ registerCollectedSecrets(nested);
43
+ }
44
+ }
45
+ }
46
+ export function parseProviderFields(provider, value, schema) {
47
+ if (!isRecord(value))
48
+ throw new Error('Provider fields must be an object.');
49
+ const formFields = schema[provider];
50
+ const byKey = new Map(formFields.map((field) => [field.key, field]));
51
+ if (Object.keys(value).some((key) => !byKey.has(key))) {
52
+ throw new Error('Provider configuration contains an unsupported field.');
53
+ }
54
+ const providerFields = {};
55
+ for (const field of formFields) {
56
+ const raw = value[field.key];
57
+ if (field.required && (raw === undefined || String(raw).trim() === '')) {
58
+ throw new Error(`${field.label} is required.`);
59
+ }
60
+ if (raw === undefined || String(raw).trim() === '')
61
+ continue;
62
+ providerFields[field.key] = field.number ? Number(raw) : String(raw);
63
+ }
64
+ return providerFields;
65
+ }
66
+ function parseSetupProvider(value, schema) {
67
+ if (typeof value !== 'string' || !Object.prototype.hasOwnProperty.call(schema, value)) {
68
+ throw new Error('Unsupported setup provider.');
69
+ }
70
+ return value;
71
+ }
72
+ const setupPortNames = ['api', 'web', 'mcp', 'publicSite'];
73
+ function findPortCollisions(ports) {
74
+ const namesByPort = new Map();
75
+ for (const name of setupPortNames) {
76
+ const port = ports[name];
77
+ if (port === undefined)
78
+ continue;
79
+ namesByPort.set(port, [...(namesByPort.get(port) ?? []), name]);
80
+ }
81
+ return [...namesByPort.entries()]
82
+ .filter(([, names]) => names.length > 1)
83
+ .map(([port, names]) => ({ port, names }));
84
+ }
85
+ function describePortCollisions(collisions) {
86
+ const collision = collisions[0];
87
+ if (!collision)
88
+ return undefined;
89
+ const names = collision.names.length === 2
90
+ ? collision.names.join(' and ')
91
+ : `${collision.names.slice(0, -1).join(', ')}, and ${collision.names.at(-1)}`;
92
+ return `Ports must be distinct — ${names} ${collision.names.length === 2 ? 'both' : 'all'} use ${collision.port}`;
93
+ }
94
+ function parsePlan(value, schema, defaults) {
95
+ if (!isRecord(value))
96
+ throw new Error('Setup request must be a JSON object.');
97
+ if (containsPlatformSecretKey(value)) {
98
+ throw new Error('Machine-minted platform secrets cannot be supplied by the setup form.');
99
+ }
100
+ const allowed = new Set([
101
+ 'provider',
102
+ 'providerFields',
103
+ 'imageMode',
104
+ 'version',
105
+ 'name',
106
+ 'ports',
107
+ 'components',
108
+ 'storage',
109
+ 'publicUrls',
110
+ 'orgName',
111
+ 'superAdminPassphrase',
112
+ 'ghcrToken',
113
+ 'accountName',
114
+ 'accountEmail',
115
+ 'seedDemo',
116
+ 'open',
117
+ 'reconfigure',
118
+ ]);
119
+ if (Object.keys(value).some((key) => !allowed.has(key))) {
120
+ throw new Error('Setup request contains an unsupported field.');
121
+ }
122
+ const provider = parseSetupProvider(value.provider, schema);
123
+ const imageMode = value.imageMode ?? defaults.imageMode ?? 'pull';
124
+ if (imageMode !== 'build' && imageMode !== 'pull')
125
+ throw new Error('Image mode must be build or pull.');
126
+ const providerFields = parseProviderFields(provider, value.providerFields ?? {}, schema);
127
+ let storage = defaults.storage;
128
+ if (value.storage !== undefined) {
129
+ if (typeof value.storage !== 'string')
130
+ throw new Error('Storage mode is invalid.');
131
+ storage = validateStorageMode(value.storage);
132
+ }
133
+ let publicUrls = defaults.publicUrls;
134
+ if (value.publicUrls !== undefined) {
135
+ if (!isRecord(value.publicUrls) ||
136
+ Object.keys(value.publicUrls).some((key) => !['api', 'web', 'mcp', 'publicSite'].includes(key))) {
137
+ throw new Error('Public URLs contain an unsupported field.');
138
+ }
139
+ const parsed = {};
140
+ for (const [key, label, originOnly] of [
141
+ ['api', 'Public API URL', false],
142
+ ['web', 'Public web origin', true],
143
+ ['mcp', 'Public MCP URL', false],
144
+ ['publicSite', 'Public site origin', true],
145
+ ]) {
146
+ const raw = value.publicUrls[key];
147
+ if (raw === undefined || raw === '')
148
+ continue;
149
+ if (typeof raw !== 'string')
150
+ throw new Error(`${label} is invalid.`);
151
+ parsed[key] = validatePublicUrl(raw.trim(), label, originOnly);
152
+ }
153
+ publicUrls = parsed;
154
+ }
155
+ let orgName = defaults.orgName;
156
+ if (value.orgName !== undefined) {
157
+ if (typeof value.orgName !== 'string') {
158
+ throw new Error('Organization name must be 1–64 characters without control characters.');
159
+ }
160
+ const candidate = value.orgName.trim();
161
+ if (candidate && (candidate.length > 64 || /[\u0000-\u001f\u007f]/.test(candidate))) {
162
+ throw new Error('Organization name must be 1–64 characters without control characters.');
163
+ }
164
+ orgName = candidate || undefined;
165
+ }
166
+ let superAdminPassphrase = defaults.superAdminPassphrase;
167
+ if (value.superAdminPassphrase !== undefined) {
168
+ if (typeof value.superAdminPassphrase !== 'string') {
169
+ throw new Error('SuperAdmin passphrase must be 12–128 characters and mix letters with digits or symbols.');
170
+ }
171
+ const candidate = value.superAdminPassphrase.trim();
172
+ if (candidate &&
173
+ (candidate.length < 12 || candidate.length > 128 || !/[A-Za-z]/.test(candidate) || !/[^A-Za-z]/.test(candidate))) {
174
+ throw new Error('SuperAdmin passphrase must be 12–128 characters and mix letters with digits or symbols.');
175
+ }
176
+ superAdminPassphrase = candidate || undefined;
177
+ }
178
+ let ports = defaults.ports;
179
+ if (value.ports !== undefined) {
180
+ if (!isRecord(value.ports) || Object.keys(value.ports).some((key) => !setupPortNames.includes(key))) {
181
+ throw new Error('Ports contain an unsupported value.');
182
+ }
183
+ ports = {
184
+ api: value.ports.api === undefined ? undefined : validatePort(Number(value.ports.api), 'API'),
185
+ web: value.ports.web === undefined ? undefined : validatePort(Number(value.ports.web), 'WEB'),
186
+ mcp: value.ports.mcp === undefined ? undefined : validatePort(Number(value.ports.mcp), 'MCP'),
187
+ publicSite: value.ports.publicSite === undefined
188
+ ? undefined
189
+ : validatePort(Number(value.ports.publicSite), 'public site'),
190
+ };
191
+ }
192
+ let components = defaults.components;
193
+ if (value.components !== undefined) {
194
+ if (!isRecord(value.components) ||
195
+ Object.keys(value.components).some((key) => !['mcp', 'publicSite'].includes(key)) ||
196
+ Object.values(value.components).some((entry) => typeof entry !== 'boolean')) {
197
+ throw new Error('Components must contain only boolean mcp and publicSite values.');
198
+ }
199
+ components = {
200
+ mcp: value.components.mcp,
201
+ publicSite: value.components.publicSite,
202
+ };
203
+ }
204
+ const selectedPorts = {
205
+ api: ports?.api,
206
+ web: ports?.web,
207
+ ...(components?.mcp === false ? {} : { mcp: ports?.mcp }),
208
+ ...(components?.publicSite === true ? { publicSite: ports?.publicSite } : {}),
209
+ };
210
+ const collisionMessage = describePortCollisions(findPortCollisions(selectedPorts));
211
+ if (collisionMessage)
212
+ throw new Error(collisionMessage);
213
+ const accountName = typeof value.accountName === 'string' ? value.accountName.trim() : undefined;
214
+ const accountEmail = typeof value.accountEmail === 'string' ? value.accountEmail.trim() : undefined;
215
+ if (Boolean(accountName) !== Boolean(accountEmail)) {
216
+ throw new Error('Account name and account email must be supplied together.');
217
+ }
218
+ return setupPlanToFrontDoorInput({
219
+ provider,
220
+ providerFields,
221
+ imageMode,
222
+ version: typeof value.version === 'string' ? value.version : defaults.version,
223
+ name: typeof value.name === 'string' ? value.name : defaults.name,
224
+ configDir: defaults.configDir,
225
+ ports,
226
+ components,
227
+ storage,
228
+ publicUrls,
229
+ orgName,
230
+ superAdminPassphrase,
231
+ ghcrToken: typeof value.ghcrToken === 'string' ? value.ghcrToken : undefined,
232
+ account: accountName && accountEmail ? { name: accountName, email: accountEmail } : defaults.account,
233
+ seedDemo: value.seedDemo === true,
234
+ open: value.open === true,
235
+ reconfigure: value.reconfigure === true,
236
+ });
237
+ }
238
+ export function createSetupApp(deps) {
239
+ const app = new Hono();
240
+ const clock = deps.clock ?? realClock;
241
+ const now = deps.now ?? Date.now;
242
+ const idleTimeoutMs = deps.idleTimeoutMs ?? SETUP_IDLE_TIMEOUT_MS;
243
+ const redact = createRedactor();
244
+ const progress = [];
245
+ const subscribers = new Set();
246
+ const encoder = new TextEncoder();
247
+ let expectedPort = deps.expectedPort;
248
+ let shutdown = deps.shutdown;
249
+ let tokenValid = true;
250
+ let inFlight = false;
251
+ let probeInFlight = false;
252
+ let cloudActivationInFlight = false;
253
+ let completed = false;
254
+ let idleTimer;
255
+ let completionResolved = false;
256
+ let resolveCompletion;
257
+ app.completion = new Promise((resolve) => {
258
+ resolveCompletion = resolve;
259
+ });
260
+ const safe = (line) => redact(redactPlatformSecrets(line));
261
+ const safePayload = (value) => {
262
+ if (typeof value === 'string')
263
+ return safe(value);
264
+ if (Array.isArray(value))
265
+ return value.map(safePayload);
266
+ if (isRecord(value)) {
267
+ return Object.fromEntries(Object.entries(value).map(([key, nested]) => [key, safePayload(nested)]));
268
+ }
269
+ return value;
270
+ };
271
+ const frame = (event, payload) => encoder.encode(`event: ${event}\ndata: ${JSON.stringify(safePayload(payload))}\n\n`);
272
+ const publish = (line, event = 'progress') => {
273
+ const redacted = safe(line);
274
+ progress.push({ event, payload: redacted });
275
+ deps.log?.(redacted);
276
+ const encoded = frame(event, redacted);
277
+ for (const subscriber of subscribers)
278
+ subscriber.enqueue(encoded);
279
+ };
280
+ const publishPayload = (payload, event) => {
281
+ const redacted = safePayload(payload);
282
+ progress.push({ event, payload: redacted });
283
+ const encoded = frame(event, redacted);
284
+ for (const subscriber of subscribers)
285
+ subscriber.enqueue(encoded);
286
+ };
287
+ const closeSubscribers = () => {
288
+ for (const subscriber of subscribers)
289
+ subscriber.close();
290
+ subscribers.clear();
291
+ };
292
+ const finishCompletion = (value) => {
293
+ if (completionResolved)
294
+ return;
295
+ completionResolved = true;
296
+ resolveCompletion(value);
297
+ };
298
+ const clearIdle = () => {
299
+ if (idleTimer !== undefined)
300
+ clock.clearTimeout(idleTimer);
301
+ idleTimer = undefined;
302
+ };
303
+ const armIdle = () => {
304
+ clearIdle();
305
+ if (inFlight || completed || !tokenValid)
306
+ return;
307
+ idleTimer = clock.setTimeout(() => {
308
+ if (inFlight || completed || !tokenValid)
309
+ return;
310
+ tokenValid = false;
311
+ publish('Setup console timed out — re-run `knowz setup`.', 'timeout');
312
+ closeSubscribers();
313
+ finishCompletion({ status: 'timeout' });
314
+ void shutdown?.('timeout');
315
+ }, idleTimeoutMs);
316
+ };
317
+ const authenticated = (headers) => {
318
+ if (!tokenValid || headers.get('x-setup-token') !== deps.token)
319
+ return false;
320
+ const origin = headers.get('origin');
321
+ const site = headers.get('sec-fetch-site');
322
+ const expectedOrigin = expectedPort === undefined ? undefined : `http://127.0.0.1:${expectedPort}`;
323
+ const localhostOrigin = expectedPort === undefined ? undefined : `http://localhost:${expectedPort}`;
324
+ const originOk = origin === expectedOrigin || origin === localhostOrigin;
325
+ const siteOk = site === 'same-origin';
326
+ if (!originOk && !siteOk)
327
+ return false;
328
+ if (origin && !originOk)
329
+ return false;
330
+ if (site && !siteOk)
331
+ return false;
332
+ armIdle();
333
+ return true;
334
+ };
335
+ const buildResultSummary = (result, progressStart) => {
336
+ const record = isRecord(result) ? result : undefined;
337
+ const state = record && isRecord(record.state) ? record.state : undefined;
338
+ const stateUrls = state && isRecord(state.serviceUrls) ? state.serviceUrls : undefined;
339
+ const currentRunLines = progress
340
+ .slice(progressStart)
341
+ .map((item) => typeof item.payload === 'string' ? item.payload : '')
342
+ .filter(Boolean);
343
+ const warning = currentRunLines.find((line) => /warning: provider .*round-trip failed/i.test(line));
344
+ const verified = currentRunLines.some((line) => /provider .*round-trip confirmed/i.test(line));
345
+ const apiUrl = typeof stateUrls?.api === 'string' ? stateUrls.api : deps.serviceUrls?.apiUrl;
346
+ const summary = {
347
+ webUrl: typeof stateUrls?.web === 'string' ? stateUrls.web : deps.serviceUrls?.webUrl,
348
+ apiUrl,
349
+ mcpUrl: typeof stateUrls?.mcp === 'string' ? stateUrls.mcp : deps.serviceUrls?.mcpUrl,
350
+ publicSiteUrl: typeof stateUrls?.publicSite === 'string'
351
+ ? stateUrls.publicSite
352
+ : deps.serviceUrls?.publicSiteUrl,
353
+ loginMode: typeof record?.loginMode === 'string' ? record.loginMode : undefined,
354
+ existing: record?.existing === true ? true : undefined,
355
+ verify: warning
356
+ ? { api: 'warn', probeWarning: 'Provider round-trip failed — check credentials and endpoint configuration.' }
357
+ : verified
358
+ ? { api: 'ok' }
359
+ : { api: 'unknown' },
360
+ };
361
+ return Object.fromEntries(Object.entries(summary).filter(([, value]) => value !== undefined));
362
+ };
363
+ app.setExpectedPort = (port) => {
364
+ expectedPort = port;
365
+ };
366
+ app.setShutdown = (next) => {
367
+ shutdown = next;
368
+ };
369
+ app.isInFlight = () => inFlight;
370
+ app.close = (reason = 'closed') => {
371
+ tokenValid = false;
372
+ clearIdle();
373
+ closeSubscribers();
374
+ finishCompletion({ status: reason });
375
+ };
376
+ app.use('*', async (c, next) => {
377
+ const host = c.req.header('host') ?? '';
378
+ const allowed = expectedPort !== undefined &&
379
+ (host === `127.0.0.1:${expectedPort}` || host === `localhost:${expectedPort}`);
380
+ if (!allowed)
381
+ return c.json({ error: 'Forbidden.' }, 403);
382
+ await next();
383
+ });
384
+ app.get('/', async (c) => {
385
+ const url = new URL(c.req.url);
386
+ if ([...url.searchParams.keys()].some((key) => /(key|token|password|secret|credential|passphrase)/i.test(key))) {
387
+ return c.json({ error: 'Credentials are accepted only in the setup POST body.' }, 400);
388
+ }
389
+ if (completed)
390
+ return c.html('<!doctype html><title>Knowz setup complete</title><p>Setup complete.</p>');
391
+ const report = await deps.preflight();
392
+ let licenseStatus = { linked: false };
393
+ try {
394
+ licenseStatus = await deps.licenseStatus?.() ?? licenseStatus;
395
+ }
396
+ catch { /* The setup page remains available while the local API is down. */ }
397
+ c.header('Cache-Control', 'no-store');
398
+ c.header('Referrer-Policy', 'no-referrer');
399
+ c.header('X-Content-Type-Options', 'nosniff');
400
+ c.header('Content-Security-Policy', "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; font-src data:; "
401
+ + "connect-src 'self'; form-action 'self'; base-uri 'none'; frame-ancestors 'none'");
402
+ return c.html(renderPage({
403
+ token: deps.token,
404
+ schema: deps.formSchema,
405
+ preflight: report,
406
+ currentState: deps.currentState?.(),
407
+ defaults: deps.planDefaults ?? {},
408
+ credentialFilePath: deps.credentialFilePath,
409
+ licenseStatus,
410
+ }));
411
+ });
412
+ app.get('/api/progress', (c) => {
413
+ if (!authenticated(c.req.raw.headers))
414
+ return c.json({ error: 'Forbidden.' }, 403);
415
+ const waitForRun = c.req.header('x-setup-progress-stream') === '1';
416
+ let ownController;
417
+ const stream = new ReadableStream({
418
+ start(controller) {
419
+ ownController = controller;
420
+ for (const item of progress)
421
+ controller.enqueue(frame(item.event, item.payload));
422
+ if (inFlight || waitForRun)
423
+ subscribers.add(controller);
424
+ else
425
+ controller.close();
426
+ },
427
+ cancel() {
428
+ if (ownController)
429
+ subscribers.delete(ownController);
430
+ },
431
+ });
432
+ return c.body(stream, 200, {
433
+ 'Content-Type': 'text/event-stream; charset=utf-8',
434
+ 'Cache-Control': 'no-store',
435
+ Connection: 'keep-alive',
436
+ });
437
+ });
438
+ app.post('/api/cloud-ai/activate', async (c) => {
439
+ if (!authenticated(c.req.raw.headers))
440
+ return c.json({ ok: false, message: safe('Forbidden.') }, 403);
441
+ if (!deps.activateCloudAi) {
442
+ return c.json({ ok: false, message: safe('Knowz Cloud account activation is unavailable.') }, 503);
443
+ }
444
+ if (inFlight || probeInFlight || cloudActivationInFlight) {
445
+ return c.json({ ok: false, message: safe('Another setup operation is already running.') }, 409);
446
+ }
447
+ cloudActivationInFlight = true;
448
+ try {
449
+ const credential = await deps.activateCloudAi();
450
+ if (!validateCloudAiKeyFormat(credential).ok) {
451
+ throw new Error('The mothership returned a malformed Knowz Cloud AI credential.');
452
+ }
453
+ registerSecret(credential);
454
+ c.header('Cache-Control', 'no-store');
455
+ return c.json({ ok: true, credential });
456
+ }
457
+ catch (error) {
458
+ return c.json({
459
+ ok: false,
460
+ message: safe(error instanceof Error ? error.message : 'Knowz Cloud account activation failed.'),
461
+ }, 400);
462
+ }
463
+ finally {
464
+ cloudActivationInFlight = false;
465
+ }
466
+ });
467
+ app.post('/api/test-connection', async (c) => {
468
+ if (!authenticated(c.req.raw.headers)) {
469
+ return c.json({ ok: false, message: safe('Forbidden.') }, 403);
470
+ }
471
+ if (probeInFlight || cloudActivationInFlight) {
472
+ return c.json({ ok: false, message: safe('A connection test is already running.') }, 409);
473
+ }
474
+ if (inFlight)
475
+ return c.json({ ok: false, message: safe('Setup is already running.') }, 409);
476
+ // Claim before the first await so two test requests cannot both probe.
477
+ probeInFlight = true;
478
+ try {
479
+ const declaredLength = Number(c.req.header('content-length') ?? '0');
480
+ if (Number.isFinite(declaredLength) && declaredLength > BODY_LIMIT) {
481
+ return c.json({ ok: false, message: safe('Connection test request is too large.') }, 413);
482
+ }
483
+ const text = await c.req.text();
484
+ if (Buffer.byteLength(text, 'utf8') > BODY_LIMIT) {
485
+ return c.json({ ok: false, message: safe('Connection test request is too large.') }, 413);
486
+ }
487
+ let body;
488
+ try {
489
+ body = JSON.parse(text);
490
+ }
491
+ catch {
492
+ return c.json({ ok: false, message: safe('Malformed connection test request.') }, 400);
493
+ }
494
+ // Register submitted credentials before validation or any other surface.
495
+ registerCollectedSecrets(body);
496
+ if (!isRecord(body) || Object.keys(body).some((key) => !['provider', 'providerFields'].includes(key))) {
497
+ return c.json({ ok: false, message: safe('Connection test request contains an unsupported field.') }, 400);
498
+ }
499
+ if (containsPlatformSecretKey(body)) {
500
+ return c.json({
501
+ ok: false,
502
+ message: safe('Machine-minted platform secrets cannot be supplied by the setup form.'),
503
+ }, 400);
504
+ }
505
+ let provider;
506
+ try {
507
+ provider = parseSetupProvider(body.provider, deps.formSchema);
508
+ }
509
+ catch {
510
+ return c.json({ ok: false, message: safe('Unsupported setup provider.') }, 400);
511
+ }
512
+ let selection;
513
+ try {
514
+ const providerFields = parseProviderFields(provider, body.providerFields ?? {}, deps.formSchema);
515
+ // This is the same conversion used by /api/setup, so its shared endpoint
516
+ // validators run before the injected probe can make any outbound call.
517
+ const input = setupPlanToFrontDoorInput({
518
+ provider,
519
+ providerFields,
520
+ imageMode: 'pull',
521
+ name: deps.planDefaults?.name,
522
+ version: deps.planDefaults?.version,
523
+ });
524
+ selection = {
525
+ provider,
526
+ azure: input.base.azure,
527
+ gcp: input.base.gcp,
528
+ openAiCompatible: input.base.openAiCompatible,
529
+ };
530
+ }
531
+ catch (error) {
532
+ return c.json({
533
+ ok: false,
534
+ message: safe(error instanceof Error ? error.message : 'Invalid provider configuration.'),
535
+ }, 400);
536
+ }
537
+ if (provider === 'offline') {
538
+ return c.json({ ok: true, message: safe('Offline stub ready — no credentials needed') });
539
+ }
540
+ if (!deps.probeProvider) {
541
+ return c.json({ ok: false, category: 'unknown', message: safe('Connection test is unavailable') });
542
+ }
543
+ const startedAt = now();
544
+ let outcome;
545
+ try {
546
+ outcome = await deps.probeProvider(selection);
547
+ }
548
+ catch {
549
+ outcome = { ok: false };
550
+ }
551
+ if (outcome.ok) {
552
+ const credential = selection.openAiCompatible?.apiKey;
553
+ const discovered = provider === 'knowz-cloud' && credential && deps.discoverCloudAiModels
554
+ ? await deps.discoverCloudAiModels(credential)
555
+ : undefined;
556
+ return c.json({
557
+ ok: true,
558
+ latencyMs: Math.max(0, Math.round(now() - startedAt)),
559
+ message: safe('Connection confirmed'),
560
+ ...(discovered ? {
561
+ models: {
562
+ chat: discovered.chatModels,
563
+ embedding: discovered.embeddingModels,
564
+ },
565
+ ...(discovered.warning ? { discoveryWarning: safe(discovered.warning) } : {}),
566
+ } : {}),
567
+ });
568
+ }
569
+ if (outcome.timedOut) {
570
+ return c.json({
571
+ ok: false,
572
+ category: 'network',
573
+ message: safe('Timed out — check the URL/network'),
574
+ });
575
+ }
576
+ const warning = outcome.warning ?? '';
577
+ const gcpAdcConfigurationFailure = provider === 'gcp' &&
578
+ warning === 'ADC credentials file could not be read or parsed.';
579
+ const category = gcpAdcConfigurationFailure
580
+ ? 'endpoint'
581
+ : /\b(?:401|403|auth|credential)/i.test(warning)
582
+ ? 'auth'
583
+ : /network|reach|connect|dns/i.test(warning)
584
+ ? 'network'
585
+ : /model/i.test(warning)
586
+ ? 'model'
587
+ : 'unknown';
588
+ const message = category === 'auth'
589
+ ? 'Authentication failed — check the provider credentials'
590
+ : category === 'network'
591
+ ? 'Provider could not be reached — check the URL/network'
592
+ : category === 'model'
593
+ ? 'Provider responded but the configured model is unavailable'
594
+ : category === 'endpoint'
595
+ ? 'ADC credentials file could not be read or parsed.'
596
+ : 'Connection test failed — check the provider configuration';
597
+ // Only the probe's explicitly browser-safe canned detail may cross to the
598
+ // page; `warning` stays quarantined (it can carry provider response text).
599
+ const safeDetail = outcome.safeDetail ?? '';
600
+ const detailed = safeDetail && safeDetail !== message ? `${message} · ${safeDetail}` : message;
601
+ return c.json({ ok: false, category, message: safe(detailed) });
602
+ }
603
+ finally {
604
+ probeInFlight = false;
605
+ armIdle();
606
+ }
607
+ });
608
+ app.post('/api/test-model', async (c) => {
609
+ if (!authenticated(c.req.raw.headers)) {
610
+ return c.json({ ok: false, message: safe('Forbidden.') }, 403);
611
+ }
612
+ if (probeInFlight) {
613
+ return c.json({ ok: false, message: safe('A model or connection test is already running.') }, 409);
614
+ }
615
+ if (inFlight)
616
+ return c.json({ ok: false, message: safe('Setup is already running.') }, 409);
617
+ // Shared single-flight claim happens synchronously before the body-read await (SEC-R0-01).
618
+ probeInFlight = true;
619
+ try {
620
+ const declaredLength = Number(c.req.header('content-length') ?? '0');
621
+ if (Number.isFinite(declaredLength) && declaredLength > BODY_LIMIT) {
622
+ return c.json({ ok: false, message: safe('Model test request is too large.') }, 413);
623
+ }
624
+ const text = await c.req.text();
625
+ if (Buffer.byteLength(text, 'utf8') > BODY_LIMIT) {
626
+ return c.json({ ok: false, message: safe('Model test request is too large.') }, 413);
627
+ }
628
+ let body;
629
+ try {
630
+ body = JSON.parse(text);
631
+ }
632
+ catch {
633
+ return c.json({ ok: false, message: safe('Malformed model test request.') }, 400);
634
+ }
635
+ // Register submitted credentials before validation, logging, or any outbound dependency call.
636
+ registerCollectedSecrets(body);
637
+ if (!isRecord(body) || Object.keys(body).some((key) => !['provider', 'providerFields', 'modelRole'].includes(key))) {
638
+ return c.json({ ok: false, message: safe('Model test request contains an unsupported field.') }, 400);
639
+ }
640
+ if (containsPlatformSecretKey(body)) {
641
+ return c.json({
642
+ ok: false,
643
+ message: safe('Machine-minted platform secrets cannot be supplied by the setup form.'),
644
+ }, 400);
645
+ }
646
+ let provider;
647
+ try {
648
+ provider = parseSetupProvider(body.provider, deps.formSchema);
649
+ }
650
+ catch {
651
+ return c.json({ ok: false, message: safe('Unsupported setup provider.') }, 400);
652
+ }
653
+ if (body.modelRole !== 'chat' && body.modelRole !== 'embedding' && body.modelRole !== 'vision') {
654
+ return c.json({ ok: false, message: safe('Model role must be chat, embedding, or vision.') }, 400);
655
+ }
656
+ let providerFields;
657
+ try {
658
+ const family = PROVIDER_PRESETS[provider].optionsFamily;
659
+ const requiredForProbe = family === 'azure'
660
+ ? new Set(['endpoint', 'apiKey'])
661
+ : family === 'gcp'
662
+ ? new Set(['project', 'adcPath'])
663
+ : family === 'openAiCompatible'
664
+ ? new Set(['endpoint', body.modelRole === 'embedding' ? 'embeddingModel' : 'chatModel'])
665
+ : new Set();
666
+ const probeSchema = {
667
+ ...deps.formSchema,
668
+ [provider]: deps.formSchema[provider].map((field) => ({
669
+ ...field,
670
+ required: requiredForProbe.has(field.key),
671
+ })),
672
+ };
673
+ providerFields = parseProviderFields(provider, body.providerFields ?? {}, probeSchema);
674
+ // Reuse the exact setup conversion so shared endpoint validators run before probeModel.
675
+ setupPlanToFrontDoorInput({
676
+ provider,
677
+ providerFields,
678
+ imageMode: 'pull',
679
+ name: deps.planDefaults?.name,
680
+ version: deps.planDefaults?.version,
681
+ });
682
+ if (family === 'openAiCompatible') {
683
+ validateModelName(providerFields[body.modelRole === 'embedding' ? 'embeddingModel' : 'chatModel']);
684
+ }
685
+ }
686
+ catch (error) {
687
+ return c.json({
688
+ ok: false,
689
+ message: safe(error instanceof Error ? error.message : 'Invalid provider configuration.'),
690
+ }, 400);
691
+ }
692
+ if (provider === 'offline') {
693
+ return c.json({ ok: true, message: safe('Offline stub — no model to test') });
694
+ }
695
+ if (!deps.probeModel) {
696
+ return c.json({
697
+ ok: false,
698
+ category: 'unknown',
699
+ message: safe('Model test is not available in this CLI build'),
700
+ }, 503);
701
+ }
702
+ let outcome;
703
+ try {
704
+ outcome = await deps.probeModel({ provider, providerFields, modelRole: body.modelRole });
705
+ }
706
+ catch {
707
+ outcome = { ok: false, category: 'unknown', message: 'Model test failed — check the provider configuration' };
708
+ }
709
+ if (outcome.ok) {
710
+ return c.json({
711
+ ok: true,
712
+ latencyMs: outcome.latencyMs === undefined
713
+ ? undefined
714
+ : Math.max(0, Math.round(outcome.latencyMs)),
715
+ message: safe(outcome.message),
716
+ });
717
+ }
718
+ return c.json({
719
+ ok: false,
720
+ category: outcome.category ?? 'unknown',
721
+ message: safe(outcome.message),
722
+ });
723
+ }
724
+ finally {
725
+ probeInFlight = false;
726
+ armIdle();
727
+ }
728
+ });
729
+ app.post('/api/test-ports', async (c) => {
730
+ if (!authenticated(c.req.raw.headers)) {
731
+ return c.json({ ok: false, message: safe('Forbidden.') }, 403);
732
+ }
733
+ if (probeInFlight) {
734
+ return c.json({ ok: false, message: safe('A connection, model, or port test is already running.') }, 409);
735
+ }
736
+ if (inFlight)
737
+ return c.json({ ok: false, message: safe('Setup is already running.') }, 409);
738
+ // Shared single-flight claim happens synchronously before the first body-read await (SEC-R0-01).
739
+ probeInFlight = true;
740
+ try {
741
+ const declaredLength = Number(c.req.header('content-length') ?? '0');
742
+ if (Number.isFinite(declaredLength) && declaredLength > BODY_LIMIT) {
743
+ return c.json({ ok: false, message: safe('Port test request is too large.') }, 413);
744
+ }
745
+ const text = await c.req.text();
746
+ if (Buffer.byteLength(text, 'utf8') > BODY_LIMIT) {
747
+ return c.json({ ok: false, message: safe('Port test request is too large.') }, 413);
748
+ }
749
+ let body;
750
+ try {
751
+ body = JSON.parse(text);
752
+ }
753
+ catch {
754
+ return c.json({ ok: false, message: safe('Malformed port test request.') }, 400);
755
+ }
756
+ registerCollectedSecrets(body);
757
+ if (containsPlatformSecretKey(body)) {
758
+ return c.json({
759
+ ok: false,
760
+ message: safe('Machine-minted platform secrets cannot be supplied by the setup form.'),
761
+ }, 400);
762
+ }
763
+ if (!isRecord(body) ||
764
+ Object.keys(body).some((key) => !['ports', 'components'].includes(key)) ||
765
+ !Object.prototype.hasOwnProperty.call(body, 'ports')) {
766
+ return c.json({ ok: false, message: safe('Port test request contains an unsupported field.') }, 400);
767
+ }
768
+ if (!isRecord(body.ports)) {
769
+ return c.json({ ok: false, message: safe('Ports must be an object.') }, 400);
770
+ }
771
+ if (body.components !== undefined && (!isRecord(body.components) ||
772
+ Object.keys(body.components).some((key) => !['mcp', 'publicSite'].includes(key)) ||
773
+ Object.values(body.components).some((value) => typeof value !== 'boolean'))) {
774
+ return c.json({ ok: false, message: safe('Components must contain only boolean mcp and publicSite values.') }, 400);
775
+ }
776
+ const requestedPorts = body.ports;
777
+ const requestedNames = Object.keys(requestedPorts);
778
+ const requiredNames = ['api', 'web', 'mcp'];
779
+ if (requiredNames.some((name) => !requestedNames.includes(name)) ||
780
+ requestedNames.some((key) => !setupPortNames.includes(key)) ||
781
+ (requestedNames.length !== 3 && requestedNames.length !== 4)) {
782
+ return c.json({ ok: false, message: safe('Ports must contain api, web, mcp, and optionally publicSite.') }, 400);
783
+ }
784
+ const components = isRecord(body.components) ? body.components : {};
785
+ const names = setupPortNames.filter((name) => requestedNames.includes(name) &&
786
+ (name !== 'mcp' || components.mcp !== false) &&
787
+ (name !== 'publicSite' || components.publicSite === true));
788
+ let ports;
789
+ try {
790
+ ports = Object.fromEntries(names.map((name) => {
791
+ const value = requestedPorts[name];
792
+ if (typeof value !== 'number')
793
+ throw new Error('invalid');
794
+ return [name, validatePort(value, name.toUpperCase())];
795
+ }));
796
+ }
797
+ catch {
798
+ return c.json({ ok: false, message: safe('Ports must be integers from 1 through 65535.') }, 400);
799
+ }
800
+ const collisions = findPortCollisions(ports);
801
+ const collisionMessage = describePortCollisions(collisions);
802
+ const collidingNames = new Set(collisions.flatMap((collision) => collision.names));
803
+ if (!deps.probePort) {
804
+ return c.json({ ok: false, message: safe('Port testing is unavailable') }, 503);
805
+ }
806
+ const outcomes = await Promise.all(names.map(async (name) => {
807
+ if (collidingNames.has(name)) {
808
+ return [name, { port: ports[name], available: false }];
809
+ }
810
+ let available = false;
811
+ try {
812
+ available = await deps.probePort(ports[name]);
813
+ }
814
+ catch {
815
+ available = false;
816
+ }
817
+ return [name, { port: ports[name], available }];
818
+ }));
819
+ const result = Object.fromEntries(outcomes);
820
+ const ok = collisions.length === 0 && names.every((name) => result[name].available);
821
+ return c.json({
822
+ ok,
823
+ ports: result,
824
+ message: safe(collisionMessage ??
825
+ (ok ? 'All selected ports are available' : 'One or more selected ports are already in use')),
826
+ });
827
+ }
828
+ finally {
829
+ probeInFlight = false;
830
+ armIdle();
831
+ }
832
+ });
833
+ app.post('/api/setup', async (c) => {
834
+ if (!authenticated(c.req.raw.headers))
835
+ return c.json({ error: 'Forbidden.' }, 403);
836
+ if (completed)
837
+ return c.json({ error: 'Setup already completed.' }, 409);
838
+ if (inFlight)
839
+ return c.json({ error: 'Setup is already running.' }, 409);
840
+ // Claim before the first await so concurrent authenticated POSTs cannot
841
+ // both parse and apply against the same runtime configuration.
842
+ inFlight = true;
843
+ clearIdle();
844
+ try {
845
+ const declaredLength = Number(c.req.header('content-length') ?? '0');
846
+ if (Number.isFinite(declaredLength) && declaredLength > BODY_LIMIT) {
847
+ return c.json({ error: 'Setup request is too large.' }, 413);
848
+ }
849
+ const text = await c.req.text();
850
+ if (Buffer.byteLength(text, 'utf8') > BODY_LIMIT) {
851
+ return c.json({ error: 'Setup request is too large.' }, 413);
852
+ }
853
+ let body;
854
+ try {
855
+ body = JSON.parse(text);
856
+ }
857
+ catch {
858
+ return c.json({ error: 'Malformed setup request.' }, 400);
859
+ }
860
+ registerCollectedSecrets(body);
861
+ let input;
862
+ try {
863
+ input = parsePlan(body, deps.formSchema, deps.planDefaults ?? {});
864
+ }
865
+ catch (error) {
866
+ const message = safe(error instanceof Error ? error.message : 'Invalid setup request.');
867
+ return c.json({ error: message }, 400);
868
+ }
869
+ const currentState = deps.currentState?.();
870
+ if (currentState && isRecord(body) && body.reconfigure !== true) {
871
+ const result = { existing: true, state: currentState };
872
+ const summary = buildResultSummary(result, progress.length);
873
+ publishPayload(summary, 'result');
874
+ completed = true;
875
+ tokenValid = false;
876
+ closeSubscribers();
877
+ finishCompletion({ status: 'success', result });
878
+ setTimeout(() => void shutdown?.('success'), 10);
879
+ return c.json({ ok: true, existing: true, result: summary });
880
+ }
881
+ try {
882
+ const progressStart = progress.length;
883
+ const result = await deps.runSetup(input, (line) => publish(line));
884
+ const summary = buildResultSummary(result, progressStart);
885
+ // The browser receives the final structured frame while the token and
886
+ // subscribers are still valid; invalidation happens immediately after.
887
+ publishPayload(summary, 'result');
888
+ completed = true;
889
+ tokenValid = false;
890
+ closeSubscribers();
891
+ // In-process consumers (up.ts) need the full result — `state` included;
892
+ // only the wire/browser frames carry the redacted summary.
893
+ finishCompletion({ status: 'success', result });
894
+ setTimeout(() => void shutdown?.('success'), 10);
895
+ return c.json({ ok: true, result: summary });
896
+ }
897
+ catch (error) {
898
+ publish(error instanceof Error ? error.message : 'Setup failed.', 'error');
899
+ closeSubscribers();
900
+ return c.json({ error: 'Setup failed. Correct the configuration and retry.' }, 500);
901
+ }
902
+ }
903
+ finally {
904
+ inFlight = false;
905
+ armIdle();
906
+ }
907
+ });
908
+ armIdle();
909
+ return app;
910
+ }
911
+ export async function startSetupServer(app) {
912
+ const host = '127.0.0.1';
913
+ return new Promise((resolve) => {
914
+ let closed = false;
915
+ const server = serve({ fetch: app.fetch, hostname: host, port: 0 }, (info) => {
916
+ app.setExpectedPort(info.port);
917
+ const close = async () => {
918
+ if (closed)
919
+ return;
920
+ closed = true;
921
+ app.close('closed');
922
+ await new Promise((done) => server.close(() => done()));
923
+ };
924
+ app.setShutdown(async () => close());
925
+ resolve({
926
+ host,
927
+ requestedPort: 0,
928
+ port: info.port,
929
+ url: `http://${host}:${info.port}/`,
930
+ close,
931
+ completion: app.completion,
932
+ });
933
+ });
934
+ });
935
+ }
936
+ //# sourceMappingURL=setup-server.js.map