@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,866 @@
1
+ import { spawn, spawnSync } from 'node:child_process';
2
+ import { randomBytes as cryptoRandomBytes } from 'node:crypto';
3
+ import { accessSync, chmodSync, mkdirSync, writeFileSync, constants as fsConstants } from 'node:fs';
4
+ import { homedir } from 'node:os';
5
+ import { isIP } from 'node:net';
6
+ import { dirname, isAbsolute, join, resolve } from 'node:path';
7
+ import { validateCloudAiKeyFormat } from '@knowzai/core';
8
+ import { assertPortableEmbeddingSupported } from './embedding-guard.js';
9
+ import { KNOWZ_CLOUD_ENDPOINT, PLATFORM_PROVIDERS, PROVIDER_PRESETS, } from './provider-presets.js';
10
+ export { PLATFORM_PROVIDERS } from './provider-presets.js';
11
+ export const PLATFORM_STORAGE_MODES = ['minio', 'filesystem'];
12
+ const PROJECT_NAME = /^[a-z0-9][a-z0-9_-]{0,62}$/;
13
+ const RELEASE_VERSION = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
14
+ const ENV_KEY = /^[A-Za-z_][A-Za-z0-9_]*$/;
15
+ const DEFAULT_PORTS = { api: 5000, web: 3000, mcp: 3001, publicSite: 3002 };
16
+ const DEFAULT_EMBEDDING_DIMENSIONS = 1536;
17
+ export const PLATFORM_SECRET_KEYS = [
18
+ 'PG_PASSWORD',
19
+ 'MINIO_ROOT_PASSWORD',
20
+ 'MINIO_APP_SECRET_KEY',
21
+ 'JWT_SECRET',
22
+ 'ADMIN_PASSWORD',
23
+ 'MCP_SERVICE_KEY',
24
+ 'INTERNAL_API_KEY',
25
+ 'SUPERADMIN_PASSPHRASE',
26
+ ];
27
+ const MANAGED_PROVIDER_KEYS = [
28
+ 'KNOWZ__CLOUDPROVIDER',
29
+ 'KNOWZ__CLOUDPROVIDER__AI',
30
+ 'KNOWZ__CLOUDPROVIDER__DOCINTELLIGENCE',
31
+ 'KNOWZ__CLOUDPROVIDER__VISION',
32
+ 'KNOWZ__CLOUDPROVIDER__TRANSCRIPTION',
33
+ 'AZURE_OPENAI_ENDPOINT',
34
+ 'AZURE_OPENAI_API_KEY',
35
+ 'GCLOUD_ADC_PATH',
36
+ 'VERTEX__PROJECT',
37
+ 'VERTEX__REGION',
38
+ 'VERTEX__CHATMODEL',
39
+ 'VERTEX__EMBEDDINGMODEL',
40
+ 'VERTEX__EMBEDDINGDIMENSIONS',
41
+ 'OPENAICOMPAT__ENDPOINT',
42
+ 'OPENAICOMPAT__APIKEY',
43
+ 'OPENAICOMPAT__CHATMODEL',
44
+ 'OPENAICOMPAT__EMBEDDINGMODEL',
45
+ 'OPENAICOMPAT__EMBEDDINGDIMENSIONS',
46
+ 'EMBEDDING_PROVIDER',
47
+ 'EMBEDDING_MODEL_NAME',
48
+ 'EMBEDDING_DIMENSIONS',
49
+ ];
50
+ export function validateProjectName(name) {
51
+ if (!PROJECT_NAME.test(name)) {
52
+ throw new Error('Invalid platform project name. Use 1-63 lowercase letters, digits, hyphens, or underscores.');
53
+ }
54
+ return name;
55
+ }
56
+ export function validateVersion(version) {
57
+ if (!RELEASE_VERSION.test(version) || version.length > 80) {
58
+ throw new Error('Invalid platform version. Use a pinned SemVer such as 1.2.3 or 1.2.3-rc.1 (without v/latest/build metadata).');
59
+ }
60
+ return version;
61
+ }
62
+ export function validatePort(port, label = 'platform') {
63
+ if (!Number.isInteger(port) || port < 1 || port > 65_535) {
64
+ throw new Error(`Invalid ${label} port: expected an integer from 1 through 65535.`);
65
+ }
66
+ return port;
67
+ }
68
+ export function validateEmbeddingDimensions(dimensions) {
69
+ if (!Number.isInteger(dimensions) || dimensions < 1 || dimensions > 65_536) {
70
+ throw new Error('Invalid embedding dimension: expected an integer from 1 through 65536.');
71
+ }
72
+ return dimensions;
73
+ }
74
+ export function validateProviderPreset(provider) {
75
+ if (!PLATFORM_PROVIDERS.includes(provider)) {
76
+ throw new Error(`Invalid platform provider '${provider}'. Expected ${PLATFORM_PROVIDERS.join(', ')}.`);
77
+ }
78
+ return provider;
79
+ }
80
+ export function validateStorageMode(storage) {
81
+ if (!PLATFORM_STORAGE_MODES.includes(storage)) {
82
+ throw new Error('Invalid platform storage. Expected minio or filesystem.');
83
+ }
84
+ return storage;
85
+ }
86
+ function resolveStorageMode(storage, existingEnv) {
87
+ if (storage !== undefined)
88
+ return validateStorageMode(storage);
89
+ const existing = existingEnv.STORAGE_PROVIDER?.trim().toLowerCase();
90
+ if (!existing || existing === 'minio' || existing === 'minios3')
91
+ return 'minio';
92
+ if (existing === 'filesystem')
93
+ return 'filesystem';
94
+ throw new Error(`Invalid existing platform storage '${existingEnv.STORAGE_PROVIDER}'.`);
95
+ }
96
+ export function resolvePlatformPaths(name, configDir) {
97
+ const projectName = validateProjectName(name);
98
+ const root = resolve(configDir ?? process.env.KNOWZ_CONFIG_DIR ?? join(homedir(), '.knowz'));
99
+ const runtimeDir = join(root, 'platform', projectName);
100
+ return {
101
+ runtimeDir,
102
+ composeFile: join(runtimeDir, 'docker-compose.yml'),
103
+ envFile: join(runtimeDir, '.env'),
104
+ stateFile: join(runtimeDir, 'state.json'),
105
+ postgresInitDir: join(runtimeDir, 'postgres-initdb'),
106
+ };
107
+ }
108
+ function parseAxis(value, allowNone, label) {
109
+ const normalized = value.trim().toLowerCase();
110
+ const axis = normalized === 'azure'
111
+ ? 'Azure'
112
+ : normalized === 'gcp'
113
+ ? 'Gcp'
114
+ : normalized === 'openaicompat' || normalized === 'openai-compatible' || normalized === 'openai-compat'
115
+ ? 'OpenAiCompat'
116
+ : normalized === 'none' || normalized === 'off'
117
+ ? 'None'
118
+ : undefined;
119
+ if (!axis || (!allowNone && axis === 'None')) {
120
+ throw new Error(`Invalid ${label} provider axis '${value}'.`);
121
+ }
122
+ return axis;
123
+ }
124
+ function defaultAxes(provider) {
125
+ return { ...PROVIDER_PRESETS[provider].defaultAxes };
126
+ }
127
+ function resolveAxes(provider, overrides) {
128
+ const axes = defaultAxes(provider);
129
+ if (overrides?.ai !== undefined)
130
+ axes.ai = parseAxis(overrides.ai, false, 'AI');
131
+ if (overrides?.docIntelligence !== undefined) {
132
+ axes.docIntelligence = parseAxis(overrides.docIntelligence, true, 'document intelligence');
133
+ }
134
+ if (overrides?.vision !== undefined)
135
+ axes.vision = parseAxis(overrides.vision, true, 'vision');
136
+ if (overrides?.transcription !== undefined) {
137
+ axes.transcription = parseAxis(overrides.transcription, true, 'transcription');
138
+ }
139
+ return axes;
140
+ }
141
+ function present(value) {
142
+ return value !== undefined && value.trim().length > 0;
143
+ }
144
+ function envOr(value, env, key) {
145
+ return value !== undefined ? value.trim() : env[key]?.trim();
146
+ }
147
+ function numberOr(value, env, key) {
148
+ if (value !== undefined)
149
+ return value;
150
+ const raw = env[key];
151
+ if (!present(raw))
152
+ return undefined;
153
+ const parsed = Number(raw);
154
+ return Number.isFinite(parsed) ? parsed : Number.NaN;
155
+ }
156
+ function defaultPathReadable(path) {
157
+ try {
158
+ accessSync(path, fsConstants.R_OK);
159
+ return true;
160
+ }
161
+ catch {
162
+ return false;
163
+ }
164
+ }
165
+ export function validateHttpsEndpoint(endpoint, label) {
166
+ let url;
167
+ try {
168
+ url = new URL(endpoint);
169
+ }
170
+ catch {
171
+ throw new Error(`${label} endpoint must be an absolute URL.`);
172
+ }
173
+ if (url.protocol !== 'https:')
174
+ throw new Error(`${label} endpoint must use HTTPS.`);
175
+ if (isLinkLocalOrMetadataHost(url.hostname)) {
176
+ throw new Error(`${label} endpoint must not use a link-local or metadata host.`);
177
+ }
178
+ if (url.username || url.password)
179
+ throw new Error(`${label} endpoint must not contain credentials.`);
180
+ if (url.search || url.hash)
181
+ throw new Error(`${label} endpoint must not contain a query or fragment.`);
182
+ return url;
183
+ }
184
+ export function validateOpenAiCompatibleEndpoint(endpoint) {
185
+ let url;
186
+ try {
187
+ url = new URL(endpoint);
188
+ }
189
+ catch {
190
+ throw new Error('OpenAI-compatible endpoint must be an absolute HTTP(S) URL.');
191
+ }
192
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
193
+ throw new Error('OpenAI-compatible endpoint must use HTTP or HTTPS.');
194
+ }
195
+ const host = url.hostname.toLowerCase();
196
+ if (isLinkLocalOrMetadataHost(host)) {
197
+ throw new Error('OpenAI-compatible endpoint must not use a link-local or metadata host.');
198
+ }
199
+ const localPlaintext = host === 'localhost' ||
200
+ host.endsWith('.localhost') ||
201
+ host === 'host.docker.internal' ||
202
+ (isIP(host) === 4 && host.startsWith('127.')) ||
203
+ host === '[::1]' ||
204
+ host === '::1';
205
+ if (url.protocol === 'http:' && !localPlaintext) {
206
+ throw new Error('Remote plaintext OpenAI-compatible endpoints are forbidden; use HTTPS or a loopback/localhost endpoint.');
207
+ }
208
+ if (url.username || url.password)
209
+ throw new Error('OpenAI-compatible endpoint must not contain credentials.');
210
+ if (url.search || url.hash)
211
+ throw new Error('OpenAI-compatible endpoint must not contain a query or fragment.');
212
+ return url;
213
+ }
214
+ function usesProvider(axes, provider) {
215
+ return Object.values(axes).includes(provider);
216
+ }
217
+ function resolvePorts(input) {
218
+ const ports = {
219
+ api: validatePort(input?.api ?? DEFAULT_PORTS.api, 'API'),
220
+ web: validatePort(input?.web ?? DEFAULT_PORTS.web, 'web'),
221
+ mcp: validatePort(input?.mcp ?? DEFAULT_PORTS.mcp, 'MCP'),
222
+ publicSite: validatePort(input?.publicSite ?? DEFAULT_PORTS.publicSite, 'public site'),
223
+ };
224
+ if (new Set(Object.values(ports)).size !== Object.values(ports).length) {
225
+ throw new Error('Platform public ports must be unique.');
226
+ }
227
+ return ports;
228
+ }
229
+ function isIpv4LinkLocal(host) {
230
+ if (isIP(host) !== 4)
231
+ return false;
232
+ const [first, second] = host.split('.').map(Number);
233
+ return first === 169 && second === 254;
234
+ }
235
+ function mappedIpv4Host(host) {
236
+ const prefix = '::ffff:';
237
+ if (!host.startsWith(prefix))
238
+ return undefined;
239
+ const suffix = host.slice(prefix.length);
240
+ if (isIP(suffix) === 4)
241
+ return suffix;
242
+ const match = /^([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(suffix);
243
+ if (!match)
244
+ return undefined;
245
+ const upper = Number.parseInt(match[1], 16);
246
+ const lower = Number.parseInt(match[2], 16);
247
+ return `${upper >>> 8}.${upper & 0xff}.${lower >>> 8}.${lower & 0xff}`;
248
+ }
249
+ function isLinkLocalOrMetadataHost(hostname) {
250
+ const host = hostname.toLowerCase().replace(/^\[|\]$/g, '');
251
+ if (host === 'metadata.google.internal' || host.endsWith('.metadata.google.internal') ||
252
+ host === 'metadata.goog' || host.endsWith('.metadata.goog'))
253
+ return true;
254
+ if (isIpv4LinkLocal(host))
255
+ return true;
256
+ if (isIP(host) === 6) {
257
+ const mappedHost = mappedIpv4Host(host);
258
+ if (mappedHost && isIpv4LinkLocal(mappedHost))
259
+ return true;
260
+ const firstHextet = Number.parseInt(host.split(':')[0] ?? '', 16);
261
+ if (Number.isFinite(firstHextet) && (firstHextet & 0xffc0) === 0xfe80)
262
+ return true;
263
+ }
264
+ return false;
265
+ }
266
+ export function validatePublicUrl(value, label, originOnly = false) {
267
+ let url;
268
+ try {
269
+ url = new URL(value);
270
+ }
271
+ catch {
272
+ throw new Error(`${label} must be an absolute HTTP(S) URL.`);
273
+ }
274
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
275
+ throw new Error(`${label} must use HTTP or HTTPS.`);
276
+ }
277
+ const host = url.hostname.toLowerCase();
278
+ if (isLinkLocalOrMetadataHost(host))
279
+ throw new Error(`${label} must not use a link-local or metadata host.`);
280
+ const local = host === 'localhost' || host.endsWith('.localhost') || (isIP(host) === 4 && host.startsWith('127.'));
281
+ if (url.protocol === 'http:' && !local)
282
+ throw new Error(`${label} must use HTTPS for a non-local host.`);
283
+ if (url.username || url.password)
284
+ throw new Error(`${label} must not contain credentials.`);
285
+ if (url.search || url.hash)
286
+ throw new Error(`${label} must not contain a query or fragment.`);
287
+ if (originOnly && url.pathname !== '/') {
288
+ throw new Error(`${label} must be an origin without a path.`);
289
+ }
290
+ return value.replace(/\/$/, '');
291
+ }
292
+ function resolvePublicUrls(input, ports) {
293
+ return {
294
+ api: validatePublicUrl(input?.api ?? `http://localhost:${ports.api}`, 'Public API URL'),
295
+ web: validatePublicUrl(input?.web ?? `http://localhost:${ports.web}`, 'Public web origin', true),
296
+ mcp: validatePublicUrl(input?.mcp ?? `http://localhost:${ports.mcp}`, 'Public MCP URL'),
297
+ publicSite: validatePublicUrl(input?.publicSite ?? `http://localhost:${ports.publicSite}`, 'Public site origin', true),
298
+ };
299
+ }
300
+ export function buildPlatformPlan(input, dependencies = {}) {
301
+ const name = validateProjectName(input.name);
302
+ const version = validateVersion(input.version);
303
+ const provider = validateProviderPreset(input.provider);
304
+ const preset = PROVIDER_PRESETS[provider];
305
+ const storage = resolveStorageMode(input.storage, input.existingEnv ?? {});
306
+ const axes = resolveAxes(provider, input.axes);
307
+ const ports = resolvePorts(input.ports);
308
+ const publicUrls = resolvePublicUrls(input.publicUrls, ports);
309
+ const components = {
310
+ mcp: input.components?.mcp ?? true,
311
+ publicSite: input.components?.publicSite ?? false,
312
+ };
313
+ const existing = input.existingEnv ?? {};
314
+ const explicitOpenAi = Object.fromEntries(Object.entries(input.openAiCompatible ?? {}).filter(([, value]) => value !== undefined));
315
+ const openAiCompatible = preset.optionsFamily === 'openAiCompatible'
316
+ ? { ...(preset.prefill ?? {}), ...explicitOpenAi }
317
+ : explicitOpenAi;
318
+ if (provider === 'knowz-cloud' &&
319
+ input.openAiCompatible?.endpoint !== undefined &&
320
+ input.openAiCompatible.endpoint.trim().replace(/\/$/, '') !== KNOWZ_CLOUD_ENDPOINT) {
321
+ throw new Error(`Knowz Cloud endpoint is locked to ${KNOWZ_CLOUD_ENDPOINT}.`);
322
+ }
323
+ const providerEnv = {
324
+ KNOWZ__CLOUDPROVIDER: preset.masterProvider,
325
+ KNOWZ__CLOUDPROVIDER__DOCINTELLIGENCE: axes.docIntelligence,
326
+ KNOWZ__CLOUDPROVIDER__VISION: axes.vision,
327
+ KNOWZ__CLOUDPROVIDER__TRANSCRIPTION: axes.transcription,
328
+ };
329
+ if (axes.ai !== undefined)
330
+ providerEnv.KNOWZ__CLOUDPROVIDER__AI = axes.ai;
331
+ const openAiDimensions = numberOr(openAiCompatible.embeddingDimensions, existing, 'OPENAICOMPAT__EMBEDDINGDIMENSIONS');
332
+ const gcpDimensions = numberOr(input.gcp?.embeddingDimensions, existing, 'VERTEX__EMBEDDINGDIMENSIONS');
333
+ const azureDimensions = input.azure?.embeddingDimensions;
334
+ const globalFromEnv = numberOr(undefined, existing, 'EMBEDDING_DIMENSIONS');
335
+ const selectedDimensions = input.embeddingDimensions ??
336
+ (axes.ai === 'OpenAiCompat'
337
+ ? openAiDimensions
338
+ : axes.ai === 'Gcp'
339
+ ? gcpDimensions
340
+ : axes.ai === 'Azure'
341
+ ? azureDimensions
342
+ : undefined) ??
343
+ globalFromEnv ??
344
+ DEFAULT_EMBEDDING_DIMENSIONS;
345
+ const embeddingDimensions = validateEmbeddingDimensions(selectedDimensions);
346
+ if (usesProvider(axes, 'Azure')) {
347
+ const endpoint = envOr(input.azure?.endpoint, existing, 'AZURE_OPENAI_ENDPOINT');
348
+ const apiKey = envOr(input.azure?.apiKey, existing, 'AZURE_OPENAI_API_KEY');
349
+ if (!present(endpoint))
350
+ throw new Error('Azure provider requires an Azure OpenAI endpoint.');
351
+ validateHttpsEndpoint(endpoint, 'Azure OpenAI');
352
+ if (!present(apiKey))
353
+ throw new Error('Azure provider requires an Azure OpenAI API key.');
354
+ providerEnv.AZURE_OPENAI_ENDPOINT = normalizeAzureOpenAiEndpoint(endpoint);
355
+ providerEnv.AZURE_OPENAI_API_KEY = apiKey;
356
+ }
357
+ if (usesProvider(axes, 'Gcp')) {
358
+ const project = envOr(input.gcp?.project, existing, 'VERTEX__PROJECT');
359
+ const region = envOr(input.gcp?.region, existing, 'VERTEX__REGION') ?? 'us-central1';
360
+ const adcPath = envOr(input.gcp?.adcPath, existing, 'GCLOUD_ADC_PATH');
361
+ if (!present(project))
362
+ throw new Error('GCP provider requires a Vertex project.');
363
+ if (!present(adcPath) || !isAbsolute(adcPath)) {
364
+ throw new Error('GCP provider requires an absolute, readable ADC path.');
365
+ }
366
+ if (!(dependencies.pathReadable ?? defaultPathReadable)(adcPath)) {
367
+ throw new Error('GCP ADC path is not readable.');
368
+ }
369
+ if (axes.ai === 'Gcp' &&
370
+ gcpDimensions !== undefined &&
371
+ validateEmbeddingDimensions(gcpDimensions) !== embeddingDimensions) {
372
+ throw new Error('Vertex and global embedding dimensions must be equal.');
373
+ }
374
+ providerEnv.GCLOUD_ADC_PATH = adcPath;
375
+ providerEnv.VERTEX__PROJECT = project;
376
+ providerEnv.VERTEX__REGION = region;
377
+ providerEnv.VERTEX__EMBEDDINGDIMENSIONS = String(embeddingDimensions);
378
+ const chatModel = envOr(input.gcp?.chatModel, existing, 'VERTEX__CHATMODEL');
379
+ const embeddingModel = envOr(input.gcp?.embeddingModel, existing, 'VERTEX__EMBEDDINGMODEL');
380
+ if (present(chatModel))
381
+ providerEnv.VERTEX__CHATMODEL = chatModel;
382
+ if (present(embeddingModel))
383
+ providerEnv.VERTEX__EMBEDDINGMODEL = embeddingModel;
384
+ }
385
+ if (usesProvider(axes, 'OpenAiCompat')) {
386
+ const endpoint = provider === 'knowz-cloud'
387
+ ? KNOWZ_CLOUD_ENDPOINT
388
+ : envOr(openAiCompatible.endpoint, existing, 'OPENAICOMPAT__ENDPOINT');
389
+ const apiKey = envOr(openAiCompatible.apiKey, existing, 'OPENAICOMPAT__APIKEY');
390
+ const chatModel = envOr(openAiCompatible.chatModel, existing, 'OPENAICOMPAT__CHATMODEL');
391
+ const embeddingModel = envOr(openAiCompatible.embeddingModel, existing, 'OPENAICOMPAT__EMBEDDINGMODEL');
392
+ if (!present(endpoint))
393
+ throw new Error('OpenAI-compatible provider requires an endpoint.');
394
+ validateOpenAiCompatibleEndpoint(endpoint);
395
+ if (provider === 'knowz-cloud') {
396
+ if (!present(apiKey)) {
397
+ throw new Error('Knowz Cloud requires an AI key. Run `knowz activate --scope cloud-ai` for this platform.');
398
+ }
399
+ if (!validateCloudAiKeyFormat(apiKey).ok) {
400
+ throw new Error('Knowz Cloud requires a valid kzai_ AI credential. Run `knowz activate --scope cloud-ai`.');
401
+ }
402
+ }
403
+ if (axes.ai === 'OpenAiCompat') {
404
+ if (!present(chatModel))
405
+ throw new Error('OpenAI-compatible provider requires a chat model.');
406
+ if (!present(embeddingModel))
407
+ throw new Error('OpenAI-compatible provider requires an embedding model.');
408
+ if (openAiDimensions === undefined) {
409
+ throw new Error('OpenAI-compatible provider requires embedding dimensions.');
410
+ }
411
+ if (validateEmbeddingDimensions(openAiDimensions) !== embeddingDimensions) {
412
+ throw new Error('OpenAI-compatible and global embedding dimensions must be equal.');
413
+ }
414
+ }
415
+ providerEnv.OPENAICOMPAT__ENDPOINT = endpoint;
416
+ providerEnv.OPENAICOMPAT__APIKEY = apiKey ?? '';
417
+ if (present(chatModel))
418
+ providerEnv.OPENAICOMPAT__CHATMODEL = chatModel;
419
+ if (present(embeddingModel))
420
+ providerEnv.OPENAICOMPAT__EMBEDDINGMODEL = embeddingModel;
421
+ if (axes.ai === 'OpenAiCompat') {
422
+ providerEnv.OPENAICOMPAT__EMBEDDINGDIMENSIONS = String(embeddingDimensions);
423
+ }
424
+ }
425
+ const imageFlavor = usesProvider(axes, 'Gcp') ? '-gcp' : '';
426
+ if (input.requestedFlavor !== undefined && input.requestedFlavor !== imageFlavor) {
427
+ throw new Error(`Requested image flavor '${input.requestedFlavor || '(default)'}' conflicts with provider axes.`);
428
+ }
429
+ providerEnv.EMBEDDING_DIMENSIONS = String(embeddingDimensions);
430
+ if (axes.ai === 'OpenAiCompat') {
431
+ providerEnv.EMBEDDING_PROVIDER = 'OpenAiCompat';
432
+ providerEnv.EMBEDDING_MODEL_NAME = providerEnv.OPENAICOMPAT__EMBEDDINGMODEL ?? '';
433
+ }
434
+ else if (axes.ai === 'Gcp') {
435
+ providerEnv.EMBEDDING_PROVIDER = 'Vertex';
436
+ providerEnv.EMBEDDING_MODEL_NAME = providerEnv.VERTEX__EMBEDDINGMODEL ?? 'google/gemini-embedding-001';
437
+ }
438
+ else if (axes.ai === 'Azure') {
439
+ providerEnv.EMBEDDING_PROVIDER = 'AzureOpenAI';
440
+ providerEnv.EMBEDDING_MODEL_NAME = input.azure?.embeddingModel ?? existing.EMBEDDING_MODEL_NAME ?? 'text-embedding-3-small';
441
+ }
442
+ else {
443
+ providerEnv.EMBEDDING_PROVIDER = 'Stub';
444
+ providerEnv.EMBEDDING_MODEL_NAME = 'text-embedding-3-small';
445
+ }
446
+ // Fail-fast BEFORE any boot when a portable Azure embedding model would produce vectors that
447
+ // don't match the pgvector column dimension (the transport never truncates). Both the CLI-flag
448
+ // path and the --ui setup plan flow through here. See FEAT_PortableEmbeddingGuardrails.
449
+ assertPortableEmbeddingSupported({
450
+ aiProvider: axes.ai,
451
+ model: providerEnv.EMBEDDING_MODEL_NAME,
452
+ dimensions: embeddingDimensions,
453
+ });
454
+ return {
455
+ name,
456
+ version,
457
+ provider,
458
+ storage,
459
+ imageFlavor,
460
+ axes,
461
+ ports,
462
+ publicUrls,
463
+ components,
464
+ embeddingDimensions,
465
+ paths: resolvePlatformPaths(name, input.configDir),
466
+ providerEnv,
467
+ };
468
+ }
469
+ export function parseEnv(contents) {
470
+ const env = {};
471
+ for (const rawLine of contents.split(/\r?\n/)) {
472
+ const line = rawLine.trim();
473
+ if (!line || line.startsWith('#'))
474
+ continue;
475
+ const assignment = line.startsWith('export ') ? line.slice(7).trim() : line;
476
+ const separator = assignment.indexOf('=');
477
+ if (separator < 1)
478
+ continue;
479
+ const key = assignment.slice(0, separator).trim();
480
+ if (!ENV_KEY.test(key))
481
+ continue;
482
+ const rawValue = assignment.slice(separator + 1).trim();
483
+ if (rawValue.length >= 2 &&
484
+ ((rawValue.startsWith('"') && rawValue.endsWith('"')) ||
485
+ (rawValue.startsWith("'") && rawValue.endsWith("'")))) {
486
+ const unquoted = rawValue.slice(1, -1);
487
+ env[key] = rawValue.startsWith('"')
488
+ ? unquoted.replace(/\\n/g, '\n').replace(/\\r/g, '\r').replace(/\\"/g, '"').replace(/\\\\/g, '\\')
489
+ : unquoted;
490
+ }
491
+ else {
492
+ env[key] = rawValue;
493
+ }
494
+ }
495
+ return env;
496
+ }
497
+ function renderEnvValue(value) {
498
+ if (/^[A-Za-z0-9_./:@+-]*$/.test(value))
499
+ return value;
500
+ return JSON.stringify(value);
501
+ }
502
+ export function renderEnv(env) {
503
+ return `${Object.keys(env)
504
+ .sort((left, right) => left.localeCompare(right))
505
+ .map((key) => `${key}=${renderEnvValue(env[key] ?? '')}`)
506
+ .join('\n')}\n`;
507
+ }
508
+ function isMissingSecret(value) {
509
+ return !present(value) || /^<CHANGE_ME/i.test(value);
510
+ }
511
+ function generateSecret(randomBytes) {
512
+ return Buffer.from(randomBytes(32)).toString('base64url');
513
+ }
514
+ const ADMIN_UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
515
+ const ADMIN_LOWER = 'abcdefghijklmnopqrstuvwxyz';
516
+ const ADMIN_DIGITS = '0123456789';
517
+ const ADMIN_SPECIAL = '-_';
518
+ /**
519
+ * Mint a dotenv/Compose-safe password that always satisfies the platform's
520
+ * IsPasswordStrong policy. Rejection sampling avoids modulo bias while the
521
+ * injectable byte source keeps the policy property directly testable.
522
+ */
523
+ export function generateAdminPassword(randomBytes = cryptoRandomBytes) {
524
+ const base = Buffer.from(randomBytes(12)).toString('base64url');
525
+ let pool = new Uint8Array();
526
+ let cursor = 0;
527
+ const uniformIndex = (upperExclusive) => {
528
+ const acceptedRange = 256 - (256 % upperExclusive);
529
+ while (true) {
530
+ if (cursor >= pool.length) {
531
+ pool = randomBytes(64);
532
+ cursor = 0;
533
+ if (pool.length === 0)
534
+ throw new Error('Random byte source returned no data.');
535
+ }
536
+ const value = pool[cursor++];
537
+ if (value < acceptedRange)
538
+ return value % upperExclusive;
539
+ }
540
+ };
541
+ const pick = (alphabet) => alphabet[uniformIndex(alphabet.length)];
542
+ const chars = [
543
+ pick(ADMIN_UPPER),
544
+ pick(ADMIN_LOWER),
545
+ pick(ADMIN_DIGITS),
546
+ pick(ADMIN_SPECIAL),
547
+ ...base,
548
+ ];
549
+ for (let index = chars.length - 1; index > 0; index -= 1) {
550
+ const swap = uniformIndex(index + 1);
551
+ [chars[index], chars[swap]] = [chars[swap], chars[index]];
552
+ }
553
+ return chars.join('');
554
+ }
555
+ export function buildPlatformEnvironment(plan, existingEnv = {}, dependencies = {}) {
556
+ const env = { ...existingEnv };
557
+ for (const key of MANAGED_PROVIDER_KEYS)
558
+ delete env[key];
559
+ Object.assign(env, plan.providerEnv, {
560
+ KNOWZ_VERSION: plan.version,
561
+ KNOWZ_FLAVOR: plan.imageFlavor,
562
+ API_PORT: String(plan.ports.api),
563
+ WEB_PORT: String(plan.ports.web),
564
+ MCP_PORT: String(plan.ports.mcp),
565
+ PUBLIC_SITE_PORT: String(plan.ports.publicSite),
566
+ PUBLIC_API_URL: plan.publicUrls.api,
567
+ PUBLIC_WEB_ORIGIN: plan.publicUrls.web,
568
+ PUBLIC_MCP_URL: plan.publicUrls.mcp,
569
+ PUBLIC_SITE_URL: plan.publicUrls.publicSite,
570
+ KNOWZ_COMPONENTS: [
571
+ ...(plan.components.mcp ? ['mcp'] : []),
572
+ ...(plan.components.publicSite ? ['public-site'] : []),
573
+ ].join(','),
574
+ PG_USER: env.PG_USER || 'knowz',
575
+ MINIO_ROOT_USER: env.MINIO_ROOT_USER || 'knowzminio',
576
+ MINIO_APP_ACCESS_KEY: env.MINIO_APP_ACCESS_KEY || 'knowzapp',
577
+ MINIO_BUCKET: env.MINIO_BUCKET || 'knowz-portable',
578
+ ADMIN_USERNAME: env.ADMIN_USERNAME || 'admin@knowz.local',
579
+ STORAGE_PROVIDER: plan.storage === 'filesystem' ? 'FileSystem' : 'MinioS3',
580
+ });
581
+ if (dependencies.orgName?.trim())
582
+ env.PLATFORM_ORG_NAME = dependencies.orgName.trim();
583
+ if (dependencies.superAdminPassphrase)
584
+ env.SUPERADMIN_PASSPHRASE = dependencies.superAdminPassphrase;
585
+ const randomBytes = dependencies.randomBytes ?? cryptoRandomBytes;
586
+ for (const key of PLATFORM_SECRET_KEYS) {
587
+ if (isMissingSecret(env[key])) {
588
+ env[key] = key === 'ADMIN_PASSWORD'
589
+ ? generateAdminPassword(randomBytes)
590
+ : generateSecret(randomBytes);
591
+ }
592
+ }
593
+ return env;
594
+ }
595
+ function escapeRegExp(value) {
596
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
597
+ }
598
+ /** Redacts exact known values first, then common key/value secret assignments. */
599
+ export function redactPlatformSecrets(text, knownSecrets = []) {
600
+ let redacted = text;
601
+ for (const secret of [...knownSecrets].filter((value) => value.length >= 4).sort((a, b) => b.length - a.length)) {
602
+ redacted = redacted.replace(new RegExp(escapeRegExp(secret), 'g'), '[REDACTED]');
603
+ }
604
+ return redacted.replace(/\b(api[_-]?key|token|password|passwd|pwd|secret|credential|passphrase)\s*[:=]\s*["']?[^\s,"']{8,}["']?/gi, (_match, key) => `${key}=[REDACTED]`);
605
+ }
606
+ export function createPlatformState(plan, now = () => new Date()) {
607
+ return {
608
+ schemaVersion: 1,
609
+ name: plan.name,
610
+ version: plan.version,
611
+ provider: plan.provider,
612
+ storage: plan.storage,
613
+ imageFlavor: plan.imageFlavor,
614
+ axes: { ...plan.axes },
615
+ ports: { ...plan.ports },
616
+ serviceUrls: { ...plan.publicUrls },
617
+ components: { ...plan.components },
618
+ imageMode: 'pull',
619
+ updatedAt: now().toISOString(),
620
+ };
621
+ }
622
+ export function serializePlatformState(state) {
623
+ const json = JSON.stringify(state, null, 2);
624
+ if (/"[^"]*(?:apiKey|password|secret|token|credential|passphrase|pgDsn)[^"]*"\s*:/i.test(json)) {
625
+ throw new Error('Refusing to serialize secret-bearing platform state.');
626
+ }
627
+ return `${json}\n`;
628
+ }
629
+ export function writePrivateFile(filePath, contents) {
630
+ mkdirSync(dirname(filePath), { recursive: true, mode: 0o700 });
631
+ writeFileSync(filePath, contents, { encoding: 'utf8', mode: 0o600 });
632
+ chmodSync(filePath, 0o600);
633
+ }
634
+ function composeInvocation(paths, projectName, actionArgs, override = {}, engine) {
635
+ if (engine?.engine === 'none') {
636
+ throw new Error('No container engine is available. Install Docker Desktop or Podman Desktop, then retry.');
637
+ }
638
+ if (engine && !engine.composeFront) {
639
+ throw new Error('Install the Docker Compose v2 plugin or standalone `docker-compose` binary (https://docs.docker.com/compose/install/), then retry.');
640
+ }
641
+ const front = engine?.composeFront ?? { command: 'docker', baseArgs: ['compose'] };
642
+ const profiles = override.profiles ?? [];
643
+ return {
644
+ command: front.command,
645
+ args: [
646
+ ...front.baseArgs,
647
+ '--project-name',
648
+ validateProjectName(projectName),
649
+ '--file',
650
+ override.composeFile ?? paths.composeFile,
651
+ ...profiles.flatMap((profile) => ['--profile', profile]),
652
+ '--env-file',
653
+ paths.envFile,
654
+ ...actionArgs,
655
+ ],
656
+ options: {
657
+ cwd: override.projectDir ?? paths.runtimeDir,
658
+ shell: false,
659
+ ...(front.env ? { env: { ...front.env } } : {}),
660
+ },
661
+ };
662
+ }
663
+ export function planComposeInvocations(action, paths, projectName, options = {}) {
664
+ switch (action) {
665
+ case 'up':
666
+ case 'upgrade': {
667
+ const override = {
668
+ composeFile: options.composeFile,
669
+ projectDir: options.projectDir,
670
+ profiles: options.profiles ?? ['mcp'],
671
+ };
672
+ const composePlan = options.composePlan ?? 'config-pull-up';
673
+ const acquisition = composePlan === 'config-build-up'
674
+ ? 'build'
675
+ : composePlan === 'config-pull-up'
676
+ ? 'pull'
677
+ : undefined;
678
+ return [
679
+ composeInvocation(paths, projectName, ['config'], override, options.engine),
680
+ ...(acquisition
681
+ ? [composeInvocation(paths, projectName, [acquisition], override, options.engine)]
682
+ : []),
683
+ composeInvocation(paths, projectName, ['up', '--detach', '--remove-orphans', '--wait'], override, options.engine),
684
+ ];
685
+ }
686
+ case 'status':
687
+ return [composeInvocation(paths, projectName, ['ps', '--all', '--format', 'json'], {
688
+ profiles: options.profiles,
689
+ }, options.engine)];
690
+ case 'doctor':
691
+ return [
692
+ composeInvocation(paths, projectName, ['config'], { profiles: options.profiles }, options.engine),
693
+ composeInvocation(paths, projectName, ['ps', '--all', '--format', 'json'], {
694
+ profiles: options.profiles,
695
+ }, options.engine),
696
+ ];
697
+ case 'logs': {
698
+ const tail = options.tail ?? 100;
699
+ if (!Number.isInteger(tail) || tail < 0 || tail > 100_000)
700
+ throw new Error('Invalid Compose log tail count.');
701
+ return [
702
+ composeInvocation(paths, projectName, [
703
+ 'logs',
704
+ '--tail',
705
+ String(tail),
706
+ ...(options.follow ? ['--follow'] : []),
707
+ ], { profiles: options.profiles }, options.engine),
708
+ ];
709
+ }
710
+ case 'down':
711
+ return [composeInvocation(paths, projectName, ['down', '--remove-orphans'], {}, options.engine)];
712
+ case 'destroy':
713
+ if (!options.confirmed)
714
+ throw new Error('Destroy requires explicit confirmation with --yes.');
715
+ return [composeInvocation(paths, projectName, ['down', '--volumes', '--remove-orphans'], {}, options.engine)];
716
+ }
717
+ }
718
+ export const nodeProcessRunner = (command, args, options) => {
719
+ const hasInput = options.input !== undefined;
720
+ const result = spawnSync(command, [...args], {
721
+ cwd: options.cwd,
722
+ shell: false,
723
+ encoding: 'utf8',
724
+ input: options.input,
725
+ env: options.env ? { ...process.env, ...options.env } : undefined,
726
+ stdio: hasInput ? ['pipe', 'pipe', 'pipe'] : ['inherit', 'pipe', 'pipe'],
727
+ });
728
+ return {
729
+ status: result.status,
730
+ stdout: result.stdout,
731
+ stderr: result.stderr,
732
+ error: result.error,
733
+ };
734
+ };
735
+ export const nodeAsyncProcessRunner = (command, args, options) => new Promise((resolveResult) => {
736
+ const hasInput = options.input !== undefined;
737
+ let stdout = '';
738
+ let stderr = '';
739
+ let settled = false;
740
+ const settle = (result) => {
741
+ if (settled)
742
+ return;
743
+ settled = true;
744
+ resolveResult(result);
745
+ };
746
+ try {
747
+ const child = spawn(command, [...args], {
748
+ cwd: options.cwd,
749
+ shell: false,
750
+ env: options.env ? { ...process.env, ...options.env } : undefined,
751
+ stdio: hasInput ? ['pipe', 'pipe', 'pipe'] : ['inherit', 'pipe', 'pipe'],
752
+ });
753
+ child.stdout?.setEncoding('utf8');
754
+ child.stderr?.setEncoding('utf8');
755
+ child.stdout?.on('data', (chunk) => { stdout += chunk; });
756
+ child.stderr?.on('data', (chunk) => { stderr += chunk; });
757
+ child.once('error', (error) => settle({ status: null, stdout, stderr, error }));
758
+ child.once('close', (status) => settle({ status, stdout, stderr }));
759
+ if (hasInput)
760
+ child.stdin?.end(options.input);
761
+ }
762
+ catch (error) {
763
+ settle({ status: null, stdout, stderr, error: error });
764
+ }
765
+ });
766
+ export const ARM64_RETRY_NOTICE = 'ℹ No native arm64 image for this version yet — running under amd64 emulation (normal on Apple Silicon, just a little slower).\n';
767
+ export const ARM64_RETRY_EXPECTATION = '⏳ Pulling images and starting services — the first run can take a minute or two.\n';
768
+ export function shouldRetryWithAmd64(result) {
769
+ return Boolean((result.error || result.status !== 0) &&
770
+ /no matching manifest for linux\/arm64/i.test(result.stderr ?? result.stdout ?? ''));
771
+ }
772
+ export function composeFailureError(result, knownSecrets) {
773
+ const detail = result.stderr || result.stdout || result.error?.message || `exit status ${String(result.status)}`;
774
+ const missingVar = /required variable (\w+) is missing a value/i.exec(detail)?.[1];
775
+ if (missingVar) {
776
+ return new Error(`The portable stack needs an auto-generated secret (${missingVar}) that isn't in your .env yet. ` +
777
+ `Re-run this command — the CLI generates any missing secret before starting. ` +
778
+ `If it keeps failing, your global 'knowz' is from an older build: rebuild it (in cli/: 'pnpm -r build') or reinstall the CLI, then retry.`);
779
+ }
780
+ return new Error(`Docker Compose failed: ${redactPlatformSecrets(detail.trim(), knownSecrets)}`);
781
+ }
782
+ function isPodmanInvocation(invocation) {
783
+ return invocation.command === 'podman' || invocation.options.env?.DOCKER_HOST !== undefined;
784
+ }
785
+ function invocationFailureError(invocation, result, knownSecrets, retriedForAmd64) {
786
+ const failure = composeFailureError(result, knownSecrets);
787
+ if (!retriedForAmd64 || !isPodmanInvocation(invocation))
788
+ return failure;
789
+ return new Error('Podman amd64 emulation may require machine-level configuration. On Apple Silicon, try ' +
790
+ '`podman machine set --rosetta` (or re-initialize the machine); see FEAT_PodmanEmulationConfig. ' +
791
+ failure.message);
792
+ }
793
+ export function executeComposeInvocations(invocations, runner = nodeProcessRunner, knownSecrets = []) {
794
+ const results = [];
795
+ for (const invocation of invocations) {
796
+ let retriedForAmd64 = false;
797
+ let result = runner(invocation.command, invocation.args, { ...invocation.options, shell: false });
798
+ if (shouldRetryWithAmd64(result)) {
799
+ retriedForAmd64 = true;
800
+ // Release images may be published amd64-only; on ARM hosts Docker refuses
801
+ // them outright. Retry once forcing amd64 so Docker Desktop runs them under
802
+ // Rosetta/QEMU emulation. Harmless once multi-arch images ship (the native
803
+ // pull succeeds and this branch never runs).
804
+ process.stderr.write(ARM64_RETRY_NOTICE + ARM64_RETRY_EXPECTATION);
805
+ result = runner(invocation.command, invocation.args, {
806
+ ...invocation.options,
807
+ shell: false,
808
+ env: { ...invocation.options.env, DOCKER_DEFAULT_PLATFORM: 'linux/amd64' },
809
+ });
810
+ }
811
+ results.push(result);
812
+ if (result.error || result.status !== 0) {
813
+ throw invocationFailureError(invocation, result, knownSecrets, retriedForAmd64);
814
+ }
815
+ }
816
+ return results;
817
+ }
818
+ export async function executeComposeInvocationsAsync(invocations, runner = nodeAsyncProcessRunner, knownSecrets = [], wrapStep) {
819
+ const results = [];
820
+ for (const invocation of invocations) {
821
+ let retriedForAmd64 = false;
822
+ const run = async () => {
823
+ let result = await Promise.resolve(runner(invocation.command, invocation.args, { ...invocation.options, shell: false }));
824
+ if (shouldRetryWithAmd64(result)) {
825
+ retriedForAmd64 = true;
826
+ process.stderr.write(ARM64_RETRY_NOTICE);
827
+ result = await Promise.resolve(runner(invocation.command, invocation.args, {
828
+ ...invocation.options,
829
+ shell: false,
830
+ env: { ...invocation.options.env, DOCKER_DEFAULT_PLATFORM: 'linux/amd64' },
831
+ }));
832
+ }
833
+ return result;
834
+ };
835
+ const result = wrapStep ? await wrapStep(invocation, run) : await run();
836
+ results.push(result);
837
+ if (result.error || result.status !== 0) {
838
+ throw invocationFailureError(invocation, result, knownSecrets, retriedForAmd64);
839
+ }
840
+ }
841
+ return results;
842
+ }
843
+ /**
844
+ * Azure portals hand out several endpoint spellings for the same resource —
845
+ * the base form, and the newer v1-surface forms ending in /openai/v1 or /v1.
846
+ * The portable runtime and probes append their own /openai/deployments/...
847
+ * paths, so those suffixes must be stripped or every call 404s. Only known
848
+ * Azure OpenAI hosts are normalized; custom gateways keep their paths.
849
+ */
850
+ export function normalizeAzureOpenAiEndpoint(endpoint) {
851
+ try {
852
+ const url = new URL(endpoint);
853
+ const host = url.hostname.toLowerCase();
854
+ if (!host.endsWith('.openai.azure.com') && !host.endsWith('.cognitiveservices.azure.com'))
855
+ return endpoint;
856
+ const path = url.pathname.replace(/\/+$/, '');
857
+ if (path === '' || path === '/openai' || path === '/openai/v1' || path === '/v1') {
858
+ return url.origin;
859
+ }
860
+ return endpoint;
861
+ }
862
+ catch {
863
+ return endpoint;
864
+ }
865
+ }
866
+ //# sourceMappingURL=platform-runtime.js.map