@cicore/cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/bin/ci.js +13 -0
  2. package/dist/commands/addon/api-actions.d.ts +45 -0
  3. package/dist/commands/addon/api-actions.d.ts.map +1 -0
  4. package/dist/commands/addon/api-actions.js +281 -0
  5. package/dist/commands/addon/api-actions.js.map +1 -0
  6. package/dist/commands/addon/build.d.ts +11 -0
  7. package/dist/commands/addon/build.d.ts.map +1 -0
  8. package/dist/commands/addon/build.js +182 -0
  9. package/dist/commands/addon/build.js.map +1 -0
  10. package/dist/commands/addon/create.d.ts +11 -0
  11. package/dist/commands/addon/create.d.ts.map +1 -0
  12. package/dist/commands/addon/create.js +1186 -0
  13. package/dist/commands/addon/create.js.map +1 -0
  14. package/dist/commands/addon/delete.d.ts +13 -0
  15. package/dist/commands/addon/delete.d.ts.map +1 -0
  16. package/dist/commands/addon/delete.js +83 -0
  17. package/dist/commands/addon/delete.js.map +1 -0
  18. package/dist/commands/addon/deploy.d.ts +27 -0
  19. package/dist/commands/addon/deploy.d.ts.map +1 -0
  20. package/dist/commands/addon/deploy.js +459 -0
  21. package/dist/commands/addon/deploy.js.map +1 -0
  22. package/dist/commands/addon/dev-deploy.d.ts +31 -0
  23. package/dist/commands/addon/dev-deploy.d.ts.map +1 -0
  24. package/dist/commands/addon/dev-deploy.js +128 -0
  25. package/dist/commands/addon/dev-deploy.js.map +1 -0
  26. package/dist/commands/addon/dev.d.ts +36 -0
  27. package/dist/commands/addon/dev.d.ts.map +1 -0
  28. package/dist/commands/addon/dev.js +323 -0
  29. package/dist/commands/addon/dev.js.map +1 -0
  30. package/dist/commands/addon/extract-classes.d.ts +23 -0
  31. package/dist/commands/addon/extract-classes.d.ts.map +1 -0
  32. package/dist/commands/addon/extract-classes.js +281 -0
  33. package/dist/commands/addon/extract-classes.js.map +1 -0
  34. package/dist/commands/addon/generate-safelist.d.ts +24 -0
  35. package/dist/commands/addon/generate-safelist.d.ts.map +1 -0
  36. package/dist/commands/addon/generate-safelist.js +276 -0
  37. package/dist/commands/addon/generate-safelist.js.map +1 -0
  38. package/dist/commands/addon/index.d.ts +19 -0
  39. package/dist/commands/addon/index.d.ts.map +1 -0
  40. package/dist/commands/addon/index.js +296 -0
  41. package/dist/commands/addon/index.js.map +1 -0
  42. package/dist/commands/addon/init-repo.d.ts +25 -0
  43. package/dist/commands/addon/init-repo.d.ts.map +1 -0
  44. package/dist/commands/addon/init-repo.js +171 -0
  45. package/dist/commands/addon/init-repo.js.map +1 -0
  46. package/dist/commands/addon/install.d.ts +23 -0
  47. package/dist/commands/addon/install.d.ts.map +1 -0
  48. package/dist/commands/addon/install.js +84 -0
  49. package/dist/commands/addon/install.js.map +1 -0
  50. package/dist/commands/addon/list.d.ts +10 -0
  51. package/dist/commands/addon/list.d.ts.map +1 -0
  52. package/dist/commands/addon/list.js +102 -0
  53. package/dist/commands/addon/list.js.map +1 -0
  54. package/dist/commands/addon/manifest-refresh.d.ts +17 -0
  55. package/dist/commands/addon/manifest-refresh.d.ts.map +1 -0
  56. package/dist/commands/addon/manifest-refresh.js +48 -0
  57. package/dist/commands/addon/manifest-refresh.js.map +1 -0
  58. package/dist/commands/addon/migrate.d.ts +40 -0
  59. package/dist/commands/addon/migrate.d.ts.map +1 -0
  60. package/dist/commands/addon/migrate.js +236 -0
  61. package/dist/commands/addon/migrate.js.map +1 -0
  62. package/dist/commands/addon/publish.d.ts +33 -0
  63. package/dist/commands/addon/publish.d.ts.map +1 -0
  64. package/dist/commands/addon/publish.js +236 -0
  65. package/dist/commands/addon/publish.js.map +1 -0
  66. package/dist/commands/addon/scaffold-quality.d.ts +21 -0
  67. package/dist/commands/addon/scaffold-quality.d.ts.map +1 -0
  68. package/dist/commands/addon/scaffold-quality.js +90 -0
  69. package/dist/commands/addon/scaffold-quality.js.map +1 -0
  70. package/dist/commands/addon/sign.d.ts +9 -0
  71. package/dist/commands/addon/sign.d.ts.map +1 -0
  72. package/dist/commands/addon/sign.js +83 -0
  73. package/dist/commands/addon/sign.js.map +1 -0
  74. package/dist/commands/addon/toggle.d.ts +6 -0
  75. package/dist/commands/addon/toggle.d.ts.map +1 -0
  76. package/dist/commands/addon/toggle.js +46 -0
  77. package/dist/commands/addon/toggle.js.map +1 -0
  78. package/dist/commands/agent/index.d.ts +34 -0
  79. package/dist/commands/agent/index.d.ts.map +1 -0
  80. package/dist/commands/agent/index.js +564 -0
  81. package/dist/commands/agent/index.js.map +1 -0
  82. package/dist/commands/brand/index.d.ts +54 -0
  83. package/dist/commands/brand/index.d.ts.map +1 -0
  84. package/dist/commands/brand/index.js +367 -0
  85. package/dist/commands/brand/index.js.map +1 -0
  86. package/dist/commands/build/index.d.ts +53 -0
  87. package/dist/commands/build/index.d.ts.map +1 -0
  88. package/dist/commands/build/index.js +726 -0
  89. package/dist/commands/build/index.js.map +1 -0
  90. package/dist/commands/cache/flush-local.d.ts +31 -0
  91. package/dist/commands/cache/flush-local.d.ts.map +1 -0
  92. package/dist/commands/cache/flush-local.js +161 -0
  93. package/dist/commands/cache/flush-local.js.map +1 -0
  94. package/dist/commands/cache/index.d.ts +14 -0
  95. package/dist/commands/cache/index.d.ts.map +1 -0
  96. package/dist/commands/cache/index.js +453 -0
  97. package/dist/commands/cache/index.js.map +1 -0
  98. package/dist/commands/check/index.d.ts +8 -0
  99. package/dist/commands/check/index.d.ts.map +1 -0
  100. package/dist/commands/check/index.js +1316 -0
  101. package/dist/commands/check/index.js.map +1 -0
  102. package/dist/commands/cloudflare/index.d.ts +8 -0
  103. package/dist/commands/cloudflare/index.d.ts.map +1 -0
  104. package/dist/commands/cloudflare/index.js +453 -0
  105. package/dist/commands/cloudflare/index.js.map +1 -0
  106. package/dist/commands/core/create.d.ts +12 -0
  107. package/dist/commands/core/create.d.ts.map +1 -0
  108. package/dist/commands/core/create.js +206 -0
  109. package/dist/commands/core/create.js.map +1 -0
  110. package/dist/commands/core/delete.d.ts +11 -0
  111. package/dist/commands/core/delete.d.ts.map +1 -0
  112. package/dist/commands/core/delete.js +64 -0
  113. package/dist/commands/core/delete.js.map +1 -0
  114. package/dist/commands/core/env.d.ts +12 -0
  115. package/dist/commands/core/env.d.ts.map +1 -0
  116. package/dist/commands/core/env.js +95 -0
  117. package/dist/commands/core/env.js.map +1 -0
  118. package/dist/commands/core/health.d.ts +6 -0
  119. package/dist/commands/core/health.d.ts.map +1 -0
  120. package/dist/commands/core/health.js +215 -0
  121. package/dist/commands/core/health.js.map +1 -0
  122. package/dist/commands/core/index.d.ts +15 -0
  123. package/dist/commands/core/index.d.ts.map +1 -0
  124. package/dist/commands/core/index.js +86 -0
  125. package/dist/commands/core/index.js.map +1 -0
  126. package/dist/commands/core/list.d.ts +11 -0
  127. package/dist/commands/core/list.d.ts.map +1 -0
  128. package/dist/commands/core/list.js +58 -0
  129. package/dist/commands/core/list.js.map +1 -0
  130. package/dist/commands/core/rebuild.d.ts +13 -0
  131. package/dist/commands/core/rebuild.d.ts.map +1 -0
  132. package/dist/commands/core/rebuild.js +119 -0
  133. package/dist/commands/core/rebuild.js.map +1 -0
  134. package/dist/commands/db/index.d.ts +23 -0
  135. package/dist/commands/db/index.d.ts.map +1 -0
  136. package/dist/commands/db/index.js +355 -0
  137. package/dist/commands/db/index.js.map +1 -0
  138. package/dist/commands/db/promote-silo.d.ts +320 -0
  139. package/dist/commands/db/promote-silo.d.ts.map +1 -0
  140. package/dist/commands/db/promote-silo.js +930 -0
  141. package/dist/commands/db/promote-silo.js.map +1 -0
  142. package/dist/commands/db/relocate.d.ts +41 -0
  143. package/dist/commands/db/relocate.d.ts.map +1 -0
  144. package/dist/commands/db/relocate.js +482 -0
  145. package/dist/commands/db/relocate.js.map +1 -0
  146. package/dist/commands/db/rollback-silo.d.ts +44 -0
  147. package/dist/commands/db/rollback-silo.d.ts.map +1 -0
  148. package/dist/commands/db/rollback-silo.js +402 -0
  149. package/dist/commands/db/rollback-silo.js.map +1 -0
  150. package/dist/commands/deploy/index.d.ts +26 -0
  151. package/dist/commands/deploy/index.d.ts.map +1 -0
  152. package/dist/commands/deploy/index.js +107 -0
  153. package/dist/commands/deploy/index.js.map +1 -0
  154. package/dist/commands/devops/index.d.ts +6 -0
  155. package/dist/commands/devops/index.d.ts.map +1 -0
  156. package/dist/commands/devops/index.js +220 -0
  157. package/dist/commands/devops/index.js.map +1 -0
  158. package/dist/commands/domain/index.d.ts +8 -0
  159. package/dist/commands/domain/index.d.ts.map +1 -0
  160. package/dist/commands/domain/index.js +386 -0
  161. package/dist/commands/domain/index.js.map +1 -0
  162. package/dist/commands/image/index.d.ts +8 -0
  163. package/dist/commands/image/index.d.ts.map +1 -0
  164. package/dist/commands/image/index.js +308 -0
  165. package/dist/commands/image/index.js.map +1 -0
  166. package/dist/commands/install/factory-reset.d.ts +21 -0
  167. package/dist/commands/install/factory-reset.d.ts.map +1 -0
  168. package/dist/commands/install/factory-reset.js +83 -0
  169. package/dist/commands/install/factory-reset.js.map +1 -0
  170. package/dist/commands/install/index.d.ts +17 -0
  171. package/dist/commands/install/index.d.ts.map +1 -0
  172. package/dist/commands/install/index.js +44 -0
  173. package/dist/commands/install/index.js.map +1 -0
  174. package/dist/commands/install/install.d.ts +35 -0
  175. package/dist/commands/install/install.d.ts.map +1 -0
  176. package/dist/commands/install/install.js +171 -0
  177. package/dist/commands/install/install.js.map +1 -0
  178. package/dist/commands/login/index.d.ts +15 -0
  179. package/dist/commands/login/index.d.ts.map +1 -0
  180. package/dist/commands/login/index.js +58 -0
  181. package/dist/commands/login/index.js.map +1 -0
  182. package/dist/commands/nginx/index.d.ts +11 -0
  183. package/dist/commands/nginx/index.d.ts.map +1 -0
  184. package/dist/commands/nginx/index.js +580 -0
  185. package/dist/commands/nginx/index.js.map +1 -0
  186. package/dist/commands/server/bootstrap.d.ts +25 -0
  187. package/dist/commands/server/bootstrap.d.ts.map +1 -0
  188. package/dist/commands/server/bootstrap.js +260 -0
  189. package/dist/commands/server/bootstrap.js.map +1 -0
  190. package/dist/commands/server/index.d.ts +8 -0
  191. package/dist/commands/server/index.d.ts.map +1 -0
  192. package/dist/commands/server/index.js +2524 -0
  193. package/dist/commands/server/index.js.map +1 -0
  194. package/dist/commands/setup/index.d.ts +34 -0
  195. package/dist/commands/setup/index.d.ts.map +1 -0
  196. package/dist/commands/setup/index.js +423 -0
  197. package/dist/commands/setup/index.js.map +1 -0
  198. package/dist/commands/ssl/index.d.ts +8 -0
  199. package/dist/commands/ssl/index.d.ts.map +1 -0
  200. package/dist/commands/ssl/index.js +275 -0
  201. package/dist/commands/ssl/index.js.map +1 -0
  202. package/dist/commands/superadmin/index.d.ts +16 -0
  203. package/dist/commands/superadmin/index.d.ts.map +1 -0
  204. package/dist/commands/superadmin/index.js +81 -0
  205. package/dist/commands/superadmin/index.js.map +1 -0
  206. package/dist/commands/tenant/index.d.ts +6 -0
  207. package/dist/commands/tenant/index.d.ts.map +1 -0
  208. package/dist/commands/tenant/index.js +192 -0
  209. package/dist/commands/tenant/index.js.map +1 -0
  210. package/dist/index.d.ts +11 -0
  211. package/dist/index.d.ts.map +1 -0
  212. package/dist/index.js +107 -0
  213. package/dist/index.js.map +1 -0
  214. package/dist/lib/addon-sign.d.ts +23 -0
  215. package/dist/lib/addon-sign.d.ts.map +1 -0
  216. package/dist/lib/addon-sign.js +39 -0
  217. package/dist/lib/addon-sign.js.map +1 -0
  218. package/dist/lib/addon-sign.test.d.ts +2 -0
  219. package/dist/lib/addon-sign.test.d.ts.map +1 -0
  220. package/dist/lib/addon-sign.test.js +27 -0
  221. package/dist/lib/addon-sign.test.js.map +1 -0
  222. package/dist/lib/cdn.d.ts +25 -0
  223. package/dist/lib/cdn.d.ts.map +1 -0
  224. package/dist/lib/cdn.js +131 -0
  225. package/dist/lib/cdn.js.map +1 -0
  226. package/dist/lib/cloudflare.d.ts +133 -0
  227. package/dist/lib/cloudflare.d.ts.map +1 -0
  228. package/dist/lib/cloudflare.js +435 -0
  229. package/dist/lib/cloudflare.js.map +1 -0
  230. package/dist/lib/config.d.ts +96 -0
  231. package/dist/lib/config.d.ts.map +1 -0
  232. package/dist/lib/config.js +132 -0
  233. package/dist/lib/config.js.map +1 -0
  234. package/dist/lib/env.d.ts +8 -0
  235. package/dist/lib/env.d.ts.map +1 -0
  236. package/dist/lib/env.js +64 -0
  237. package/dist/lib/env.js.map +1 -0
  238. package/dist/lib/hosts.d.ts +194 -0
  239. package/dist/lib/hosts.d.ts.map +1 -0
  240. package/dist/lib/hosts.js +183 -0
  241. package/dist/lib/hosts.js.map +1 -0
  242. package/dist/lib/logger.d.ts +68 -0
  243. package/dist/lib/logger.d.ts.map +1 -0
  244. package/dist/lib/logger.js +130 -0
  245. package/dist/lib/logger.js.map +1 -0
  246. package/dist/lib/nginx-config.d.ts +78 -0
  247. package/dist/lib/nginx-config.d.ts.map +1 -0
  248. package/dist/lib/nginx-config.js +736 -0
  249. package/dist/lib/nginx-config.js.map +1 -0
  250. package/dist/lib/ops/addon-dev.d.ts +93 -0
  251. package/dist/lib/ops/addon-dev.d.ts.map +1 -0
  252. package/dist/lib/ops/addon-dev.js +237 -0
  253. package/dist/lib/ops/addon-dev.js.map +1 -0
  254. package/dist/lib/ops/addon-quality.d.ts +38 -0
  255. package/dist/lib/ops/addon-quality.d.ts.map +1 -0
  256. package/dist/lib/ops/addon-quality.js +338 -0
  257. package/dist/lib/ops/addon-quality.js.map +1 -0
  258. package/dist/lib/ops/addon-routes.d.ts +49 -0
  259. package/dist/lib/ops/addon-routes.d.ts.map +1 -0
  260. package/dist/lib/ops/addon-routes.js +189 -0
  261. package/dist/lib/ops/addon-routes.js.map +1 -0
  262. package/dist/lib/ops/addon.d.ts +120 -0
  263. package/dist/lib/ops/addon.d.ts.map +1 -0
  264. package/dist/lib/ops/addon.js +260 -0
  265. package/dist/lib/ops/addon.js.map +1 -0
  266. package/dist/lib/ops/cdn.d.ts +87 -0
  267. package/dist/lib/ops/cdn.d.ts.map +1 -0
  268. package/dist/lib/ops/cdn.js +170 -0
  269. package/dist/lib/ops/cdn.js.map +1 -0
  270. package/dist/lib/ops/cf.d.ts +36 -0
  271. package/dist/lib/ops/cf.d.ts.map +1 -0
  272. package/dist/lib/ops/cf.js +114 -0
  273. package/dist/lib/ops/cf.js.map +1 -0
  274. package/dist/lib/ops/compose.d.ts +95 -0
  275. package/dist/lib/ops/compose.d.ts.map +1 -0
  276. package/dist/lib/ops/compose.js +165 -0
  277. package/dist/lib/ops/compose.js.map +1 -0
  278. package/dist/lib/ops/core.d.ts +117 -0
  279. package/dist/lib/ops/core.d.ts.map +1 -0
  280. package/dist/lib/ops/core.js +322 -0
  281. package/dist/lib/ops/core.js.map +1 -0
  282. package/dist/lib/ops/db.d.ts +116 -0
  283. package/dist/lib/ops/db.d.ts.map +1 -0
  284. package/dist/lib/ops/db.js +351 -0
  285. package/dist/lib/ops/db.js.map +1 -0
  286. package/dist/lib/ops/dns.d.ts +111 -0
  287. package/dist/lib/ops/dns.d.ts.map +1 -0
  288. package/dist/lib/ops/dns.js +306 -0
  289. package/dist/lib/ops/dns.js.map +1 -0
  290. package/dist/lib/ops/image.d.ts +94 -0
  291. package/dist/lib/ops/image.d.ts.map +1 -0
  292. package/dist/lib/ops/image.js +159 -0
  293. package/dist/lib/ops/image.js.map +1 -0
  294. package/dist/lib/ops/nginx.d.ts +114 -0
  295. package/dist/lib/ops/nginx.d.ts.map +1 -0
  296. package/dist/lib/ops/nginx.js +388 -0
  297. package/dist/lib/ops/nginx.js.map +1 -0
  298. package/dist/lib/ops/redis.d.ts +7 -0
  299. package/dist/lib/ops/redis.d.ts.map +1 -0
  300. package/dist/lib/ops/redis.js +35 -0
  301. package/dist/lib/ops/redis.js.map +1 -0
  302. package/dist/lib/ops/ssh.d.ts +127 -0
  303. package/dist/lib/ops/ssh.d.ts.map +1 -0
  304. package/dist/lib/ops/ssh.js +269 -0
  305. package/dist/lib/ops/ssh.js.map +1 -0
  306. package/dist/lib/prompts.d.ts +46 -0
  307. package/dist/lib/prompts.d.ts.map +1 -0
  308. package/dist/lib/prompts.js +113 -0
  309. package/dist/lib/prompts.js.map +1 -0
  310. package/dist/lib/sast.d.ts +43 -0
  311. package/dist/lib/sast.d.ts.map +1 -0
  312. package/dist/lib/sast.js +79 -0
  313. package/dist/lib/sast.js.map +1 -0
  314. package/dist/lib/sast.test.d.ts +2 -0
  315. package/dist/lib/sast.test.d.ts.map +1 -0
  316. package/dist/lib/sast.test.js +33 -0
  317. package/dist/lib/sast.test.js.map +1 -0
  318. package/dist/lib/shell.d.ts +61 -0
  319. package/dist/lib/shell.d.ts.map +1 -0
  320. package/dist/lib/shell.js +183 -0
  321. package/dist/lib/shell.js.map +1 -0
  322. package/dist/lib/ssh-config.d.ts +37 -0
  323. package/dist/lib/ssh-config.d.ts.map +1 -0
  324. package/dist/lib/ssh-config.js +122 -0
  325. package/dist/lib/ssh-config.js.map +1 -0
  326. package/dist/lib/tenant-scope.d.ts +38 -0
  327. package/dist/lib/tenant-scope.d.ts.map +1 -0
  328. package/dist/lib/tenant-scope.js +129 -0
  329. package/dist/lib/tenant-scope.js.map +1 -0
  330. package/dist/lib/tenant-scope.test.d.ts +2 -0
  331. package/dist/lib/tenant-scope.test.d.ts.map +1 -0
  332. package/dist/lib/tenant-scope.test.js +223 -0
  333. package/dist/lib/tenant-scope.test.js.map +1 -0
  334. package/package.json +58 -0
  335. package/templates/bootstrap/.env.template +54 -0
  336. package/templates/bootstrap/docker-compose.yml +145 -0
  337. package/templates/vhost.conf.tmpl +446 -0
@@ -0,0 +1,236 @@
1
+ /**
2
+ * CiCore CLI — `ci addon publish` (M3.4 S4, option-b / K4 single authority)
3
+ *
4
+ * Publishes an addon to the central marketplace:
5
+ * 1. build (unless --skip-build) — reuse `ci addon build`
6
+ * 2. package → zip — addonPackageBackend
7
+ * 3. sha256 + HMAC signature — addon-sign (cross-lang parity)
8
+ * 4. upload artifact to R2 — cdnUploadZip (→ addons/<name>/<ver>/)
9
+ * 5. enqueue a SIGNED publish_addon job — enqueueJob (cp_provisioning_jobs)
10
+ *
11
+ * The CLI never writes cp_addons directly. The agent (`ci agent run`) claims the
12
+ * signed job (HMAC-verified) and runs publish-addon-job.php INSIDE the app
13
+ * container, so the control-plane registration goes through AddonRegistryService
14
+ * — the SINGLE writer (K-M3.4-1) — then rebuilds + uploads the CDN manifest.
15
+ *
16
+ * Live steps (R2 upload + enqueue) are Mustafa-gated; `--dry-run` (global
17
+ * CICORE_DRY_RUN) short-circuits the R2/DB writes (build + sha + sign still run).
18
+ */
19
+ import { readFile } from 'node:fs/promises';
20
+ import { mkdtemp, rm } from 'node:fs/promises';
21
+ import { tmpdir } from 'node:os';
22
+ import { join as pathJoin } from 'node:path';
23
+ import { createWriteStream, existsSync, readdirSync, statSync } from 'node:fs';
24
+ import { log } from '../../lib/logger.js';
25
+ import { paths, isDryRun } from '../../lib/config.js';
26
+ import { getHostConfig } from '../../lib/hosts.js';
27
+ import { buildAddon } from './build.js';
28
+ import { addonPackageBackend, addonPackageBackendTarGz, addonCleanupPackage } from '../../lib/ops/addon.js';
29
+ import { cdnUploadZip } from '../../lib/ops/cdn.js';
30
+ import { cfPurgePaths } from '../../lib/ops/cf.js';
31
+ import { enqueueJob } from '../agent/index.js';
32
+ import { sha256Hex, signPackage } from '../../lib/addon-sign.js';
33
+ import { runSemgrepScan } from '../../lib/sast.js';
34
+ import archiver from 'archiver';
35
+ export async function publishAddon(name, options) {
36
+ const version = options.version ?? 'latest';
37
+ const addonPath = `${paths.dev.addons}/${name}`;
38
+ const cfg = getHostConfig(options.host ?? 'cicore');
39
+ log.title(`Publish Addon: ${name}@${version}`);
40
+ // 1. Build (unless skipped).
41
+ if (options.skipBuild !== true) {
42
+ await buildAddon(name, { core: options.core });
43
+ }
44
+ // 1.5 SAST pre-flight gate (P-1b): üçüncü-taraf addon kaynağı çekirdekte çalışır →
45
+ // publish ÖNCESİ Semgrep. ERROR-severity bulgu / semgrep YOK → fail-closed ABORT
46
+ // (upload/enqueue YAPILMAZ). Bilinçli atlama: --skip-scan (audit'li). NOT: bu CLI
47
+ // gate'i geliştirici katmanı; OTORİTER tarama (scan_status='passed' yazan) container-
48
+ // içi publish-addon-job'da (semgrep-in-image, mehmet/infra) → o gün gelene dek
49
+ // scan_status server-otoritesiyle 'pending' kalır (P-1).
50
+ if (options.skipScan === true) {
51
+ log.warn('SAST taraması ATLANDI (--skip-scan) — fail-closed bypass, audit edilir.');
52
+ }
53
+ else {
54
+ const scan = await runSemgrepScan(addonPath, { config: options.semgrepConfig });
55
+ if (!scan.available) {
56
+ log.error(`SAST gate: semgrep bulunamadı → publish ABORT (fail-closed). Kur: 'pip install semgrep' veya bilinçli atlamak için --skip-scan. (${scan.message})`);
57
+ process.exit(1);
58
+ }
59
+ if (scan.errorCount > 0) {
60
+ log.error(`SAST gate: ${scan.errorCount} ERROR-severity bulgu → publish ABORT (fail-closed):`);
61
+ for (const f of scan.findings.filter((f) => f.severity === 'ERROR').slice(0, 20)) {
62
+ log.error(` ✗ ${f.checkId} @ ${f.path}${f.line ? ':' + f.line : ''}`);
63
+ }
64
+ process.exit(1);
65
+ }
66
+ log.success(`SAST gate GEÇTİ (semgrep; ${scan.findings.length} non-blocking finding, 0 ERROR).`);
67
+ }
68
+ // 2. Package → zip (legacy SSH deploy) + pkg.tar.gz (FAZ-2 cold-fetch R2).
69
+ const pack = await addonPackageBackend(name, addonPath);
70
+ const pkgTarGz = await addonPackageBackendTarGz(name, addonPath);
71
+ try {
72
+ // 3. Hash + sign. sha256 is from pkg.tar.gz — PHP install verifies this exact hash.
73
+ const secret = process.env.CDN_GRANT_SECRET ?? process.env.CICORE_JOB_SIGNING_SECRET ?? '';
74
+ if (!secret) {
75
+ log.warn('CDN_GRANT_SECRET/CICORE_JOB_SIGNING_SECRET unset — package signature boş (dev).');
76
+ }
77
+ const sha256 = pkgTarGz.sha256;
78
+ const signature = secret ? signPackage(sha256, secret) : '';
79
+ log.kv('sha256 (pkg.tar.gz)', sha256);
80
+ // r2_path = specific file path (not a directory prefix); PHP install fetches this.
81
+ const r2PathPkg = `addons/${name}/${version}/pkg.tar.gz`;
82
+ // 4a. Frontend bundle → R2 (addons/<name>/<version>/*)
83
+ // dist/ veya latest/ içeriğini ayrı bir ZIP olarak CF Worker'a gönder.
84
+ const frontendDir = existsSync(pathJoin(addonPath, 'latest'))
85
+ ? pathJoin(addonPath, 'latest')
86
+ : existsSync(pathJoin(addonPath, 'dist'))
87
+ ? pathJoin(addonPath, 'dist')
88
+ : null;
89
+ // F1 content-hash: frontend bundle ZIP sha256 (AUTHORITATIVE, cp_addon_versions.content_hash)
90
+ let contentHash;
91
+ if (frontendDir) {
92
+ const feZipDir = await mkdtemp(pathJoin(tmpdir(), `vu-addon-fe-${name}-`));
93
+ const feZipPath = pathJoin(feZipDir, `${name}-fe.zip`);
94
+ // F1 determinism: arc.directory() embeds FS mtime + non-deterministic readdir order
95
+ // → same input, different hash on each build. Fix: sorted recursive file list +
96
+ // date: new Date(0) (epoch) per entry → identical ZIP bytes for identical content.
97
+ await new Promise((resolve, reject) => {
98
+ const output = createWriteStream(feZipPath);
99
+ const arc = archiver('zip', { zlib: { level: 6 } });
100
+ output.on('close', resolve);
101
+ output.on('error', reject);
102
+ arc.on('error', reject);
103
+ arc.pipe(output);
104
+ const EPOCH = new Date(0);
105
+ function addSorted(dir, rel) {
106
+ for (const entry of readdirSync(dir).sort()) {
107
+ const abs = pathJoin(dir, entry);
108
+ const relPath = rel ? `${rel}/${entry}` : entry;
109
+ if (statSync(abs).isDirectory()) {
110
+ addSorted(abs, relPath);
111
+ }
112
+ else {
113
+ arc.file(abs, { name: relPath, date: EPOCH });
114
+ }
115
+ }
116
+ }
117
+ addSorted(frontendDir, '');
118
+ arc.finalize().catch(reject);
119
+ });
120
+ // F1: ZIP oluşturulduktan sonra hash hesapla — sorted+epoch → retry-safe deterministic
121
+ const feZipBytes = await readFile(feZipPath);
122
+ contentHash = sha256Hex(feZipBytes);
123
+ log.kv('content_hash (frontend bundle)', contentHash);
124
+ // F1 dual-write: version path + latest path (Worker) + hash path (immutable, Worker)
125
+ const feUp = await cdnUploadZip(cfg, feZipPath, { addon: name, version, contentHash });
126
+ await rm(feZipDir, { recursive: true, force: true }).catch(() => { });
127
+ if (!feUp.success && !isDryRun()) {
128
+ log.error(`Frontend CDN upload failed: ${feUp.errorMessage}`);
129
+ process.exit(1);
130
+ }
131
+ log.success(`Frontend bundle → R2 addons/${name}/${version}/ + addons/${name}/${contentHash}/ (immutable)`);
132
+ }
133
+ else {
134
+ log.warn(`Frontend dist/ / latest/ bulunamadı — sadece backend upload yapılıyor.`);
135
+ }
136
+ // 4b. Backend pkg.tar.gz → R2 via CDN Worker.
137
+ // Wrap pkg.tar.gz in a ZIP so the Worker stores it at
138
+ // addons/<name>/<version>/pkg.tar.gz (single R2 object, not unpacked).
139
+ const wrapDir = await mkdtemp(pathJoin(tmpdir(), `vu-addon-wrap-${name}-`));
140
+ const wrapZipPath = pathJoin(wrapDir, 'pkg-wrap.zip');
141
+ await new Promise((resolve, reject) => {
142
+ const output = createWriteStream(wrapZipPath);
143
+ const arc = archiver('zip', { zlib: { level: 0 } }); // no re-compression
144
+ output.on('close', resolve);
145
+ output.on('error', reject);
146
+ arc.on('error', reject);
147
+ arc.pipe(output);
148
+ arc.file(pkgTarGz.tarGzPath, { name: 'pkg.tar.gz' });
149
+ arc.finalize().catch(reject);
150
+ });
151
+ const pkgUp = await cdnUploadZip(cfg, wrapZipPath, { addon: name, version });
152
+ await rm(wrapDir, { recursive: true, force: true }).catch(() => { });
153
+ if (!pkgUp.success && !isDryRun()) {
154
+ log.error(`Backend pkg.tar.gz CDN upload failed: ${pkgUp.errorMessage}`);
155
+ process.exit(1);
156
+ }
157
+ log.success(`Backend pkg.tar.gz → R2 ${r2PathPkg}`);
158
+ // 5. Enqueue the signed publish_addon job (agent registers via single authority).
159
+ if (options.skipEnqueue === true) {
160
+ log.warn('publish_addon enqueue ATLANDI (--skip-enqueue). DB kaydı için `ci agent run` gerekli.');
161
+ }
162
+ else {
163
+ const payload = {
164
+ addon: {
165
+ slug: name,
166
+ title: options.title ?? name,
167
+ plan_code: options.plan ?? null,
168
+ is_public: options.public === true,
169
+ },
170
+ version: {
171
+ version,
172
+ r2_path: r2PathPkg, // specific pkg.tar.gz file (PHP install uses this)
173
+ sha256, // sha256 of pkg.tar.gz (backend integrity)
174
+ signature,
175
+ size_bytes: pkgTarGz.sizeBytes,
176
+ content_hash: contentHash, // F1: sha256(frontend bundle ZIP) — immutable R2 path key
177
+ },
178
+ // F2 saga: agent publish-addon-job.php bu steps'i kullanarak her adımı kayıt eder;
179
+ // failure → compensation (R2 hash-path sil, cp_addon_versions sil, am_addons pointer geri al)
180
+ saga_steps: [
181
+ { step: 'r2_upload', status: 'completed', hash_path: contentHash ? `addons/${name}/${contentHash}/` : null },
182
+ { step: 'cp_versions_register', status: 'pending' },
183
+ { step: 'am_projection', status: 'pending' },
184
+ { step: 'pointer_flip', status: 'pending' },
185
+ { step: 'cf_purge', status: 'pending' },
186
+ ],
187
+ };
188
+ const queued = await enqueueJob(cfg, 'publish_addon', 'addon', payload, options.requestedBy ?? 'cli');
189
+ if (!queued && !isDryRun()) {
190
+ log.error('publish_addon enqueue failed');
191
+ process.exit(1);
192
+ }
193
+ }
194
+ // 6. CF edge-cache purge — upload tek başına yetmez; CF eski 404/200'ü TTL
195
+ // boyunca tutabilir. Upload'daki tüm dosyaları URL-bazlı purge et.
196
+ if (frontendDir) {
197
+ const purgeUrls = [];
198
+ const cdnBase = cfg.cdnBaseUrl; // full CDN URL for CF purge API (cdn.cicore.com.tr)
199
+ // frontend dosyalarını rekürsif listele
200
+ function collectFiles(dir, rel) {
201
+ for (const entry of readdirSync(dir)) {
202
+ const full = pathJoin(dir, entry);
203
+ const relPath = rel ? `${rel}/${entry}` : entry;
204
+ if (statSync(full).isDirectory()) {
205
+ collectFiles(full, relPath);
206
+ }
207
+ else {
208
+ purgeUrls.push(`${cdnBase}/addons/${name}/${version}/${relPath}`);
209
+ if (version !== 'latest') {
210
+ purgeUrls.push(`${cdnBase}/addons/${name}/latest/${relPath}`);
211
+ }
212
+ }
213
+ }
214
+ }
215
+ collectFiles(frontendDir, '');
216
+ if (purgeUrls.length > 0) {
217
+ const purge = await cfPurgePaths(cfg, purgeUrls);
218
+ if (purge.success) {
219
+ log.success(`CF edge-cache purge: ${purgeUrls.length} URL temizlendi.`);
220
+ }
221
+ else {
222
+ log.warn(`CF cache purge başarısız (non-blocking): ${purge.errorMessage}`);
223
+ }
224
+ }
225
+ }
226
+ log.success(`${name}@${version} → R2 + CF purge + publish_addon job queued${isDryRun() ? ' (dry-run)' : ''}`);
227
+ log.info('`ci agent run` registers it in control-plane (AddonRegistryService) + rebuilds the CDN manifest.');
228
+ }
229
+ finally {
230
+ await addonCleanupPackage(pack.zipPath);
231
+ // Clean pkg.tar.gz temp dir (separate mkdtemp root from addonPackageBackendTarGz)
232
+ const pkgParent = pathJoin(pkgTarGz.tarGzPath, '..');
233
+ await rm(pkgParent, { recursive: true, force: true }).catch(() => { });
234
+ }
235
+ }
236
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../../src/commands/addon/publish.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,QAAQ,EAAa,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC5G,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,QAAQ,MAAM,UAAU,CAAC;AAgBhC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY,EAAE,OAAuB;IACtE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAC;IAC5C,MAAM,SAAS,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;IAChD,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC;IAEpD,GAAG,CAAC,KAAK,CAAC,kBAAkB,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC;IAE/C,6BAA6B;IAC7B,IAAI,OAAO,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;QAC/B,MAAM,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,mFAAmF;IACnF,iFAAiF;IACjF,kFAAkF;IAClF,sFAAsF;IACtF,+EAA+E;IAC/E,yDAAyD;IACzD,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC9B,GAAG,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;IACtF,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;QAChF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,GAAG,CAAC,KAAK,CAAC,oIAAoI,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;YAC/J,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;YACxB,GAAG,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,UAAU,sDAAsD,CAAC,CAAC;YAC/F,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;gBACjF,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACzE,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,6BAA6B,IAAI,CAAC,QAAQ,CAAC,MAAM,kCAAkC,CAAC,CAAC;IACnG,CAAC;IAED,2EAA2E;IAC3E,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjE,IAAI,CAAC;QACH,oFAAoF;QACpF,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,EAAE,CAAC;QAC3F,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,GAAG,CAAC,IAAI,CAAC,iFAAiF,CAAC,CAAC;QAC9F,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,GAAG,CAAC,EAAE,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QAEtC,mFAAmF;QACnF,MAAM,SAAS,GAAG,UAAU,IAAI,IAAI,OAAO,aAAa,CAAC;QAEzD,uDAAuD;QACvD,uEAAuE;QACvE,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC3D,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC;YAC/B,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBACvC,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAC7B,CAAC,CAAC,IAAI,CAAC;QAEX,8FAA8F;QAC9F,IAAI,WAA+B,CAAC;QAEpC,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,eAAe,IAAI,GAAG,CAAC,CAAC,CAAC;YAC3E,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,EAAE,GAAG,IAAI,SAAS,CAAC,CAAC;YACvD,oFAAoF;YACpF,gFAAgF;YAChF,mFAAmF;YACnF,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;gBAC5C,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBACpD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC5B,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAC3B,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBACxB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACjB,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC1B,SAAS,SAAS,CAAC,GAAW,EAAE,GAAW;oBACzC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;wBAC5C,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;wBACjC,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;wBAChD,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;4BAChC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;wBAC1B,CAAC;6BAAM,CAAC;4BACN,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;wBAChD,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;gBAC3B,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;YAEH,uFAAuF;YACvF,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC7C,WAAW,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;YACpC,GAAG,CAAC,EAAE,CAAC,gCAAgC,EAAE,WAAW,CAAC,CAAC;YAEtD,qFAAqF;YACrF,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;YACvF,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACrE,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;gBACjC,GAAG,CAAC,KAAK,CAAC,+BAA+B,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;gBAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,GAAG,CAAC,OAAO,CAAC,+BAA+B,IAAI,IAAI,OAAO,cAAc,IAAI,IAAI,WAAW,eAAe,CAAC,CAAC;QAC9G,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,wEAAwE,CAAC,CAAC;QACrF,CAAC;QAED,8CAA8C;QAC9C,sDAAsD;QACtD,uEAAuE;QACvE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,iBAAiB,IAAI,GAAG,CAAC,CAAC,CAAC;QAC5E,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QACtD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAC9C,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB;YACzE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC5B,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC3B,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACxB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjB,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7E,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACpE,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YAClC,GAAG,CAAC,KAAK,CAAC,yCAAyC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;YACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,2BAA2B,SAAS,EAAE,CAAC,CAAC;QAEpD,kFAAkF;QAClF,IAAI,OAAO,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;YACjC,GAAG,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAC;QACpG,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG;gBACd,KAAK,EAAE;oBACL,IAAI,EAAE,IAAI;oBACV,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;oBAC5B,SAAS,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;oBAC/B,SAAS,EAAE,OAAO,CAAC,MAAM,KAAK,IAAI;iBACnC;gBACD,OAAO,EAAE;oBACP,OAAO;oBACP,OAAO,EAAE,SAAS,EAAU,mDAAmD;oBAC/E,MAAM,EAAuB,2CAA2C;oBACxE,SAAS;oBACT,UAAU,EAAE,QAAQ,CAAC,SAAS;oBAC9B,YAAY,EAAE,WAAW,EAAI,0DAA0D;iBACxF;gBACD,mFAAmF;gBACnF,8FAA8F;gBAC9F,UAAU,EAAE;oBACV,EAAE,IAAI,EAAE,WAAW,EAAY,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,UAAU,IAAI,IAAI,WAAW,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE;oBACtH,EAAE,IAAI,EAAE,sBAAsB,EAAE,MAAM,EAAE,SAAS,EAAE;oBACnD,EAAE,IAAI,EAAE,eAAe,EAAS,MAAM,EAAE,SAAS,EAAE;oBACnD,EAAE,IAAI,EAAE,cAAc,EAAU,MAAM,EAAE,SAAS,EAAE;oBACnD,EAAE,IAAI,EAAE,UAAU,EAAc,MAAM,EAAE,SAAS,EAAE;iBACpD;aACF,CAAC;YACF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,IAAI,KAAK,CAAC,CAAC;YACtG,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;gBAC3B,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;gBAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,2EAA2E;QAC3E,sEAAsE;QACtE,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,SAAS,GAAa,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,oDAAoD;YACpF,wCAAwC;YACxC,SAAS,YAAY,CAAC,GAAW,EAAE,GAAW;gBAC5C,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;oBACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;oBAClC,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;oBAChD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;wBACjC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;oBAC9B,CAAC;yBAAM,CAAC;wBACN,SAAS,CAAC,IAAI,CAAC,GAAG,OAAO,WAAW,IAAI,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC,CAAC;wBAClE,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;4BACzB,SAAS,CAAC,IAAI,CAAC,GAAG,OAAO,WAAW,IAAI,WAAW,OAAO,EAAE,CAAC,CAAC;wBAChE,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YACD,YAAY,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAE9B,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBACjD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClB,GAAG,CAAC,OAAO,CAAC,wBAAwB,SAAS,CAAC,MAAM,kBAAkB,CAAC,CAAC;gBAC1E,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,IAAI,CAAC,4CAA4C,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;gBAC7E,CAAC;YACH,CAAC;QACH,CAAC;QAED,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,IAAI,OAAO,8CAA8C,QAAQ,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9G,GAAG,CAAC,IAAI,CAAC,kGAAkG,CAAC,CAAC;IAC/G,CAAC;YAAS,CAAC;QACT,MAAM,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,kFAAkF;QAClF,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACrD,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACxE,CAAC;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `ci addon scaffold-quality [path]`
3
+ *
4
+ * Applies the Faz 5 quality template to an existing addon directory
5
+ * (eslint config, prettier, tsconfig, editorconfig, gitlab-ci, env.d.ts).
6
+ * Same templates `ci addon create` ships with new addons — this command
7
+ * is the backport path for addons that pre-date Faz 5.
8
+ *
9
+ * Default cwd. `--all` walks every addon under the dev-shell's
10
+ * cores/dev/addons/ directory in sequence — used during the bulk
11
+ * backport (Faz 5B). `--overwrite` replaces existing config files;
12
+ * default is to keep what the addon already has and only add missing
13
+ * files.
14
+ */
15
+ export interface ScaffoldQualityOptions {
16
+ readonly path?: string;
17
+ readonly all?: boolean;
18
+ readonly overwrite?: boolean;
19
+ }
20
+ export declare function scaffoldQuality(options: ScaffoldQualityOptions): Promise<void>;
21
+ //# sourceMappingURL=scaffold-quality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold-quality.d.ts","sourceRoot":"","sources":["../../../src/commands/addon/scaffold-quality.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAC7B;AAID,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBpF"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * `ci addon scaffold-quality [path]`
3
+ *
4
+ * Applies the Faz 5 quality template to an existing addon directory
5
+ * (eslint config, prettier, tsconfig, editorconfig, gitlab-ci, env.d.ts).
6
+ * Same templates `ci addon create` ships with new addons — this command
7
+ * is the backport path for addons that pre-date Faz 5.
8
+ *
9
+ * Default cwd. `--all` walks every addon under the dev-shell's
10
+ * cores/dev/addons/ directory in sequence — used during the bulk
11
+ * backport (Faz 5B). `--overwrite` replaces existing config files;
12
+ * default is to keep what the addon already has and only add missing
13
+ * files.
14
+ */
15
+ import path from 'node:path';
16
+ import fs from 'fs-extra';
17
+ import { log } from '../../lib/logger.js';
18
+ import { findShellRoot } from '../../lib/ops/addon-dev.js';
19
+ import { applyQualityTemplate } from '../../lib/ops/addon-quality.js';
20
+ const ADDON_NAME_RE = /^[A-Za-z0-9_-]+$/;
21
+ export async function scaffoldQuality(options) {
22
+ if (options.all) {
23
+ await applyToAllAddons(options);
24
+ return;
25
+ }
26
+ const addonDir = path.resolve(options.path ?? process.cwd());
27
+ const manifestPath = path.join(addonDir, 'addon.json');
28
+ if (!(await fs.pathExists(manifestPath))) {
29
+ log.error(`addon.json not found at ${manifestPath}`);
30
+ log.info('Run from an addon directory, or pass --path <addon-dir> or --all (from dev-shell).');
31
+ return;
32
+ }
33
+ const addonName = path.basename(addonDir);
34
+ if (!ADDON_NAME_RE.test(addonName)) {
35
+ log.error(`Invalid addon name "${addonName}" (derived from dir) — only [A-Za-z0-9_-].`);
36
+ return;
37
+ }
38
+ await applyOne(addonDir, addonName, options.overwrite === true);
39
+ }
40
+ async function applyToAllAddons(options) {
41
+ const shellRoot = findShellRoot(process.cwd());
42
+ if (!shellRoot) {
43
+ log.error('--all requires running from inside dev-shell. Walk up to a dir containing nginx/snippets/ + cores/dev/addons/.');
44
+ return;
45
+ }
46
+ const addonsRoot = path.join(shellRoot, 'cores', 'dev', 'addons');
47
+ const entries = await fs.readdir(addonsRoot, { withFileTypes: true });
48
+ const addonNames = entries
49
+ .filter((e) => e.isDirectory() && ADDON_NAME_RE.test(e.name))
50
+ .map((e) => e.name);
51
+ if (addonNames.length === 0) {
52
+ log.info(`No addons found under ${addonsRoot}.`);
53
+ return;
54
+ }
55
+ log.title(`Faz 5B — quality template backport to ${addonNames.length} addon${addonNames.length === 1 ? '' : 's'}`);
56
+ log.blank();
57
+ for (const name of addonNames) {
58
+ const addonDir = path.join(addonsRoot, name);
59
+ // Skip dirs that aren't actual addons (missing addon.json) so a
60
+ // half-cloned dir or stray test fixture doesn't get a config dump.
61
+ if (!(await fs.pathExists(path.join(addonDir, 'addon.json')))) {
62
+ log.warn(`${name}: addon.json missing, skipped`);
63
+ continue;
64
+ }
65
+ await applyOne(addonDir, name, options.overwrite === true);
66
+ log.blank();
67
+ }
68
+ log.success(`Backport complete (${addonNames.length} addon${addonNames.length === 1 ? '' : 's'}).`);
69
+ log.info('Next: in each addon repo, run lint + commit:');
70
+ log.item('cd cores/dev/addons/<Name>');
71
+ log.item('../../../../node_modules/.bin/eslint . --fix # autofixable warnings');
72
+ log.item('../../../../node_modules/.bin/vue-tsc --noEmit # type errors');
73
+ log.item('git add -A && git commit -m "chore: Faz 5 quality template"');
74
+ }
75
+ async function applyOne(addonDir, addonName, overwrite) {
76
+ log.kv('Addon', addonName);
77
+ log.kv('Path', addonDir);
78
+ const result = await applyQualityTemplate(addonDir, addonName, { overwrite });
79
+ if (result.written.length > 0) {
80
+ log.success(`Wrote ${result.written.length} config file${result.written.length === 1 ? '' : 's'}:`);
81
+ for (const rel of result.written)
82
+ log.item(rel);
83
+ }
84
+ if (result.skipped.length > 0) {
85
+ log.info(`Skipped ${result.skipped.length} existing file${result.skipped.length === 1 ? '' : 's'} (use --overwrite to replace):`);
86
+ for (const rel of result.skipped)
87
+ log.item(rel);
88
+ }
89
+ }
90
+ //# sourceMappingURL=scaffold-quality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold-quality.js","sourceRoot":"","sources":["../../../src/commands/addon/scaffold-quality.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * vu addon:sign <name>
3
+ */
4
+ interface SignOptions {
5
+ key?: string;
6
+ }
7
+ export declare function signAddon(name: string, options: SignOptions): Promise<void>;
8
+ export {};
9
+ //# sourceMappingURL=sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../../../src/commands/addon/sign.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,UAAU,WAAW;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EjF"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * vu addon:sign <name>
3
+ */
4
+ import { log, spinner } from '../../lib/logger.js';
5
+ import { paths } from '../../lib/config.js';
6
+ import fs from 'fs-extra';
7
+ import path from 'path';
8
+ import crypto from 'crypto';
9
+ export async function signAddon(name, options) {
10
+ log.title(`Sign Addon: ${name}`);
11
+ const addonPath = path.join(paths.dev.addons, name);
12
+ // Check addon exists
13
+ if (!await fs.pathExists(addonPath)) {
14
+ log.error(`Addon "${name}" not found`);
15
+ return;
16
+ }
17
+ const signSpinner = spinner('Generating signature...').start();
18
+ try {
19
+ // Collect files to hash
20
+ const filesToHash = [];
21
+ // addon.json
22
+ const addonJsonPath = path.join(addonPath, 'addon.json');
23
+ if (await fs.pathExists(addonJsonPath)) {
24
+ filesToHash.push(addonJsonPath);
25
+ }
26
+ // Backend files
27
+ const backendPath = path.join(addonPath, 'Backend');
28
+ if (await fs.pathExists(backendPath)) {
29
+ const backendFiles = await getFilesRecursive(backendPath);
30
+ filesToHash.push(...backendFiles);
31
+ }
32
+ // Pages
33
+ const pagesPath = path.join(addonPath, 'pages');
34
+ if (await fs.pathExists(pagesPath)) {
35
+ const pageFiles = await getFilesRecursive(pagesPath);
36
+ filesToHash.push(...pageFiles);
37
+ }
38
+ // Locales
39
+ const localesPath = path.join(addonPath, 'locales');
40
+ if (await fs.pathExists(localesPath)) {
41
+ const localeFiles = await getFilesRecursive(localesPath);
42
+ filesToHash.push(...localeFiles);
43
+ }
44
+ // Generate hash
45
+ const hash = crypto.createHash('sha256');
46
+ for (const file of filesToHash.sort()) {
47
+ const content = await fs.readFile(file);
48
+ const relativePath = path.relative(addonPath, file);
49
+ hash.update(relativePath);
50
+ hash.update(content);
51
+ }
52
+ const signature = hash.digest('hex');
53
+ // Write signature file
54
+ const signaturePath = path.join(addonPath, '.signature');
55
+ await fs.writeFile(signaturePath, signature);
56
+ signSpinner.succeed('Signature generated');
57
+ log.blank();
58
+ log.kv('Files hashed', filesToHash.length.toString());
59
+ log.kv('Signature', signature.slice(0, 16) + '...');
60
+ log.kv('Saved to', signaturePath);
61
+ log.blank();
62
+ log.success('Addon signed successfully');
63
+ }
64
+ catch (error) {
65
+ signSpinner.fail('Failed to sign addon');
66
+ log.error(error.message);
67
+ }
68
+ }
69
+ async function getFilesRecursive(dir) {
70
+ const files = [];
71
+ const entries = await fs.readdir(dir, { withFileTypes: true });
72
+ for (const entry of entries) {
73
+ const fullPath = path.join(dir, entry.name);
74
+ if (entry.isDirectory()) {
75
+ files.push(...await getFilesRecursive(fullPath));
76
+ }
77
+ else {
78
+ files.push(fullPath);
79
+ }
80
+ }
81
+ return files;
82
+ }
83
+ //# sourceMappingURL=sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign.js","sourceRoot":"","sources":["../../../src/commands/addon/sign.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * vu addon:enable / vu addon:disable
3
+ */
4
+ export declare function enableAddon(name: string, core: string): Promise<void>;
5
+ export declare function disableAddon(name: string, core: string): Promise<void>;
6
+ //# sourceMappingURL=toggle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toggle.d.ts","sourceRoot":"","sources":["../../../src/commands/addon/toggle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5E"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * vu addon:enable / vu addon:disable
3
+ */
4
+ import { log, spinner } from '../../lib/logger.js';
5
+ import { ssh } from '../../lib/shell.js';
6
+ export async function enableAddon(name, core) {
7
+ log.title(`Enable Addon: ${name} in ${core}`);
8
+ await toggleAddon(name, core, true);
9
+ }
10
+ export async function disableAddon(name, core) {
11
+ log.title(`Disable Addon: ${name} in ${core}`);
12
+ await toggleAddon(name, core, false);
13
+ }
14
+ async function toggleAddon(name, core, enable) {
15
+ const addonPath = `/home/cores/${core}/addons/${name}`;
16
+ const addonJson = `${addonPath}/addon.json`;
17
+ // Check addon exists
18
+ const checkResult = await ssh(`test -f ${addonJson} && echo "exists"`, { silent: true });
19
+ if (!checkResult.stdout.includes('exists')) {
20
+ log.error(`Addon "${name}" not found in ${core}`);
21
+ return;
22
+ }
23
+ const toggleSpinner = spinner(`${enable ? 'Enabling' : 'Disabling'} addon...`).start();
24
+ // Update addon.json
25
+ const sedCmd = enable
26
+ ? `sed -i 's/"enabled"[[:space:]]*:[[:space:]]*false/"enabled": true/g' ${addonJson}`
27
+ : `sed -i 's/"enabled"[[:space:]]*:[[:space:]]*true/"enabled": false/g' ${addonJson}`;
28
+ const result = await ssh(sedCmd, { silent: true });
29
+ if (!result.success) {
30
+ toggleSpinner.fail('Failed to update addon.json');
31
+ log.error(result.stderr);
32
+ return;
33
+ }
34
+ toggleSpinner.succeed(`Addon ${enable ? 'enabled' : 'disabled'}`);
35
+ // Clear cache
36
+ const cacheSpinner = spinner('Clearing cache...').start();
37
+ await ssh(`rm -rf /home/cores/${core}/storage/cache/addon_*`, { silent: true });
38
+ cacheSpinner.succeed('Cache cleared');
39
+ // Restart PHP
40
+ const restartSpinner = spinner('Restarting PHP...').start();
41
+ await ssh('docker restart cicore_php', { silent: true });
42
+ restartSpinner.succeed('PHP restarted');
43
+ log.blank();
44
+ log.success(`Addon "${name}" is now ${enable ? 'enabled' : 'disabled'}`);
45
+ }
46
+ //# sourceMappingURL=toggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toggle.js","sourceRoot":"","sources":["../../../src/commands/addon/toggle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,IAAY;IAC1D,GAAG,CAAC,KAAK,CAAC,iBAAiB,IAAI,OAAO,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY,EAAE,IAAY;IAC3D,GAAG,CAAC,KAAK,CAAC,kBAAkB,IAAI,OAAO,IAAI,EAAE,CAAC,CAAC;IAC/C,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,IAAY,EAAE,MAAe;IACpE,MAAM,SAAS,GAAG,eAAe,IAAI,WAAW,IAAI,EAAE,CAAC;IACvD,MAAM,SAAS,GAAG,GAAG,SAAS,aAAa,CAAC;IAE5C,qBAAqB;IACrB,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,WAAW,SAAS,mBAAmB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzF,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3C,GAAG,CAAC,KAAK,CAAC,UAAU,IAAI,kBAAkB,IAAI,EAAE,CAAC,CAAC;QAClD,OAAO;IACT,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC;IAEvF,oBAAoB;IACpB,MAAM,MAAM,GAAG,MAAM;QACnB,CAAC,CAAC,wEAAwE,SAAS,EAAE;QACrF,CAAC,CAAC,wEAAwE,SAAS,EAAE,CAAC;IAExF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAEnD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,aAAa,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAClD,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzB,OAAO;IACT,CAAC;IAED,aAAa,CAAC,OAAO,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IAElE,cAAc;IACd,MAAM,YAAY,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC,KAAK,EAAE,CAAC;IAC1D,MAAM,GAAG,CAAC,sBAAsB,IAAI,wBAAwB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAChF,YAAY,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAEtC,cAAc;IACd,MAAM,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC,KAAK,EAAE,CAAC;IAC5D,MAAM,GAAG,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,cAAc,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAExC,GAAG,CAAC,KAAK,EAAE,CAAC;IACZ,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,YAAY,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * CiCore CLI — `ci agent` (provisioning agent / execution bridge, K4)
3
+ *
4
+ * The control-plane never SSHes ad hoc. The panel (PHP) writes a *job* to
5
+ * `cp_provisioning_jobs`; a privileged agent claims it and runs the work,
6
+ * recording step logs, status, errors and an audit trail. This is that agent.
7
+ *
8
+ * - `ci agent enqueue` — write a (signed) job. The panel mirrors this INSERT
9
+ * in PHP; the CLI form is for testing + ops.
10
+ * - `ci agent run` — claim queued jobs and execute them. Run it as a cron /
11
+ * systemd timer on the host (or any box with SSH + control-plane access).
12
+ *
13
+ * Execution reuses the existing CLI commands by spawning them as child
14
+ * processes (e.g. `brand_reconcile` → `ci brand reconcile`), so the agent adds
15
+ * no second copy of the provisioning logic and a job failure can't take the
16
+ * agent down. Jobs are HMAC-signed (env `CICORE_JOB_SIGNING_SECRET`) so a
17
+ * compromised panel can't inject arbitrary work; if the secret is unset the
18
+ * agent runs in dev mode (verification skipped, with a warning).
19
+ *
20
+ * v1 job type: `brand_reconcile`. Reconcile is idempotent, so a failed job is
21
+ * safe to re-run (recovery = re-queue); true compensating rollback for
22
+ * create-type jobs (create_brand, …) is a follow-up.
23
+ */
24
+ import { Command } from 'commander';
25
+ import { type HostConfig } from '../../lib/hosts.js';
26
+ export declare function registerAgentCommands(program: Command): void;
27
+ /** Sign a job, or return '' (unsigned) when no secret is configured (dev). */
28
+ /**
29
+ * Enqueue a signed provisioning job (reusable by other commands, e.g.
30
+ * `ci addon publish` → publish_addon). Mirrors the `agent enqueue` INSERT;
31
+ * caller ensures `type` is a KNOWN_TYPES value. Returns whether the row landed.
32
+ */
33
+ export declare function enqueueJob(cfg: HostConfig, type: string, targetType: string, payload: unknown, requestedBy?: string): Promise<boolean>;
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAA;AA2BnE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoE5D;AA+ZD,8EAA8E;AAC9E;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,SAAQ,GACvF,OAAO,CAAC,OAAO,CAAC,CAWlB"}