@owlmeans/viable-common 0.0.4

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 (453) hide show
  1. package/README.md +68 -0
  2. package/agent-meta/manifest.json +16 -0
  3. package/agent-meta/skills/viable-common/SKILL.md +179 -0
  4. package/build/agent/index.d.ts +4 -0
  5. package/build/agent/index.d.ts.map +1 -0
  6. package/build/agent/index.js +3 -0
  7. package/build/agent/index.js.map +1 -0
  8. package/build/agent/memory.d.ts +12 -0
  9. package/build/agent/memory.d.ts.map +1 -0
  10. package/build/agent/memory.js +11 -0
  11. package/build/agent/memory.js.map +1 -0
  12. package/build/agent/spectator/consts.d.ts +9 -0
  13. package/build/agent/spectator/consts.d.ts.map +1 -0
  14. package/build/agent/spectator/consts.js +10 -0
  15. package/build/agent/spectator/consts.js.map +1 -0
  16. package/build/agent/spectator/index.d.ts +3 -0
  17. package/build/agent/spectator/index.d.ts.map +1 -0
  18. package/build/agent/spectator/index.js +2 -0
  19. package/build/agent/spectator/index.js.map +1 -0
  20. package/build/agent/spectator/types.d.ts +13 -0
  21. package/build/agent/spectator/types.d.ts.map +1 -0
  22. package/build/agent/spectator/types.js +2 -0
  23. package/build/agent/spectator/types.js.map +1 -0
  24. package/build/agent/types.d.ts +10 -0
  25. package/build/agent/types.d.ts.map +1 -0
  26. package/build/agent/types.js +2 -0
  27. package/build/agent/types.js.map +1 -0
  28. package/build/areas/consts.d.ts +88 -0
  29. package/build/areas/consts.d.ts.map +1 -0
  30. package/build/areas/consts.js +106 -0
  31. package/build/areas/consts.js.map +1 -0
  32. package/build/areas/index.d.ts +3 -0
  33. package/build/areas/index.d.ts.map +1 -0
  34. package/build/areas/index.js +2 -0
  35. package/build/areas/index.js.map +1 -0
  36. package/build/areas/types.d.ts +28 -0
  37. package/build/areas/types.d.ts.map +1 -0
  38. package/build/areas/types.js +2 -0
  39. package/build/areas/types.js.map +1 -0
  40. package/build/ba/consts.d.ts +38 -0
  41. package/build/ba/consts.d.ts.map +1 -0
  42. package/build/ba/consts.js +41 -0
  43. package/build/ba/consts.js.map +1 -0
  44. package/build/ba/helpers.d.ts +41 -0
  45. package/build/ba/helpers.d.ts.map +1 -0
  46. package/build/ba/helpers.js +79 -0
  47. package/build/ba/helpers.js.map +1 -0
  48. package/build/ba/index.d.ts +5 -0
  49. package/build/ba/index.d.ts.map +1 -0
  50. package/build/ba/index.js +4 -0
  51. package/build/ba/index.js.map +1 -0
  52. package/build/ba/schemas.d.ts +13 -0
  53. package/build/ba/schemas.d.ts.map +1 -0
  54. package/build/ba/schemas.js +181 -0
  55. package/build/ba/schemas.js.map +1 -0
  56. package/build/ba/types.d.ts +113 -0
  57. package/build/ba/types.d.ts.map +1 -0
  58. package/build/ba/types.js +2 -0
  59. package/build/ba/types.js.map +1 -0
  60. package/build/blueprint/case.d.ts +73 -0
  61. package/build/blueprint/case.d.ts.map +1 -0
  62. package/build/blueprint/case.js +244 -0
  63. package/build/blueprint/case.js.map +1 -0
  64. package/build/blueprint/consts.d.ts +11 -0
  65. package/build/blueprint/consts.d.ts.map +1 -0
  66. package/build/blueprint/consts.js +11 -0
  67. package/build/blueprint/consts.js.map +1 -0
  68. package/build/blueprint/index.d.ts +6 -0
  69. package/build/blueprint/index.d.ts.map +1 -0
  70. package/build/blueprint/index.js +6 -0
  71. package/build/blueprint/index.js.map +1 -0
  72. package/build/blueprint/resolve.d.ts +51 -0
  73. package/build/blueprint/resolve.d.ts.map +1 -0
  74. package/build/blueprint/resolve.js +108 -0
  75. package/build/blueprint/resolve.js.map +1 -0
  76. package/build/blueprint/schemas.d.ts +41 -0
  77. package/build/blueprint/schemas.d.ts.map +1 -0
  78. package/build/blueprint/schemas.js +27 -0
  79. package/build/blueprint/schemas.js.map +1 -0
  80. package/build/blueprint/types.d.ts +186 -0
  81. package/build/blueprint/types.d.ts.map +1 -0
  82. package/build/blueprint/types.js +32 -0
  83. package/build/blueprint/types.js.map +1 -0
  84. package/build/branding.d.ts +19 -0
  85. package/build/branding.d.ts.map +1 -0
  86. package/build/branding.js +32 -0
  87. package/build/branding.js.map +1 -0
  88. package/build/connect/consts.d.ts +378 -0
  89. package/build/connect/consts.d.ts.map +1 -0
  90. package/build/connect/consts.js +425 -0
  91. package/build/connect/consts.js.map +1 -0
  92. package/build/connect/entrypoints.d.ts +41 -0
  93. package/build/connect/entrypoints.d.ts.map +1 -0
  94. package/build/connect/entrypoints.js +141 -0
  95. package/build/connect/entrypoints.js.map +1 -0
  96. package/build/connect/errors.d.ts +50 -0
  97. package/build/connect/errors.d.ts.map +1 -0
  98. package/build/connect/errors.js +77 -0
  99. package/build/connect/errors.js.map +1 -0
  100. package/build/connect/index.d.ts +8 -0
  101. package/build/connect/index.d.ts.map +1 -0
  102. package/build/connect/index.js +6 -0
  103. package/build/connect/index.js.map +1 -0
  104. package/build/connect/ops.d.ts +192 -0
  105. package/build/connect/ops.d.ts.map +1 -0
  106. package/build/connect/ops.js +2 -0
  107. package/build/connect/ops.js.map +1 -0
  108. package/build/connect/references.d.ts +194 -0
  109. package/build/connect/references.d.ts.map +1 -0
  110. package/build/connect/references.js +62 -0
  111. package/build/connect/references.js.map +1 -0
  112. package/build/connect/schemas.d.ts +59 -0
  113. package/build/connect/schemas.d.ts.map +1 -0
  114. package/build/connect/schemas.js +346 -0
  115. package/build/connect/schemas.js.map +1 -0
  116. package/build/connect/types.d.ts +428 -0
  117. package/build/connect/types.d.ts.map +1 -0
  118. package/build/connect/types.js +2 -0
  119. package/build/connect/types.js.map +1 -0
  120. package/build/consts.d.ts +9 -0
  121. package/build/consts.d.ts.map +1 -0
  122. package/build/consts.js +31 -0
  123. package/build/consts.js.map +1 -0
  124. package/build/convert/consts.d.ts +539 -0
  125. package/build/convert/consts.d.ts.map +1 -0
  126. package/build/convert/consts.js +630 -0
  127. package/build/convert/consts.js.map +1 -0
  128. package/build/convert/helpers.d.ts +91 -0
  129. package/build/convert/helpers.d.ts.map +1 -0
  130. package/build/convert/helpers.js +301 -0
  131. package/build/convert/helpers.js.map +1 -0
  132. package/build/convert/index.d.ts +11 -0
  133. package/build/convert/index.d.ts.map +1 -0
  134. package/build/convert/index.js +4 -0
  135. package/build/convert/index.js.map +1 -0
  136. package/build/convert/schemas.d.ts +62 -0
  137. package/build/convert/schemas.d.ts.map +1 -0
  138. package/build/convert/schemas.js +626 -0
  139. package/build/convert/schemas.js.map +1 -0
  140. package/build/convert/types.d.ts +683 -0
  141. package/build/convert/types.d.ts.map +1 -0
  142. package/build/convert/types.js +2 -0
  143. package/build/convert/types.js.map +1 -0
  144. package/build/design/consts.d.ts +25 -0
  145. package/build/design/consts.d.ts.map +1 -0
  146. package/build/design/consts.js +26 -0
  147. package/build/design/consts.js.map +1 -0
  148. package/build/design/helpers.d.ts +60 -0
  149. package/build/design/helpers.d.ts.map +1 -0
  150. package/build/design/helpers.js +221 -0
  151. package/build/design/helpers.js.map +1 -0
  152. package/build/design/index.d.ts +6 -0
  153. package/build/design/index.d.ts.map +1 -0
  154. package/build/design/index.js +5 -0
  155. package/build/design/index.js.map +1 -0
  156. package/build/design/runtime.d.ts +126 -0
  157. package/build/design/runtime.d.ts.map +1 -0
  158. package/build/design/runtime.js +65 -0
  159. package/build/design/runtime.js.map +1 -0
  160. package/build/design/schemas.d.ts +21 -0
  161. package/build/design/schemas.d.ts.map +1 -0
  162. package/build/design/schemas.js +369 -0
  163. package/build/design/schemas.js.map +1 -0
  164. package/build/design/types.d.ts +199 -0
  165. package/build/design/types.d.ts.map +1 -0
  166. package/build/design/types.js +2 -0
  167. package/build/design/types.js.map +1 -0
  168. package/build/dev/consts.d.ts +32 -0
  169. package/build/dev/consts.d.ts.map +1 -0
  170. package/build/dev/consts.js +33 -0
  171. package/build/dev/consts.js.map +1 -0
  172. package/build/dev/index.d.ts +4 -0
  173. package/build/dev/index.d.ts.map +1 -0
  174. package/build/dev/index.js +3 -0
  175. package/build/dev/index.js.map +1 -0
  176. package/build/dev/schemas.d.ts +15 -0
  177. package/build/dev/schemas.d.ts.map +1 -0
  178. package/build/dev/schemas.js +116 -0
  179. package/build/dev/schemas.js.map +1 -0
  180. package/build/dev/types.d.ts +42 -0
  181. package/build/dev/types.d.ts.map +1 -0
  182. package/build/dev/types.js +2 -0
  183. package/build/dev/types.js.map +1 -0
  184. package/build/execution/consts.d.ts +36 -0
  185. package/build/execution/consts.d.ts.map +1 -0
  186. package/build/execution/consts.js +37 -0
  187. package/build/execution/consts.js.map +1 -0
  188. package/build/execution/index.d.ts +3 -0
  189. package/build/execution/index.d.ts.map +1 -0
  190. package/build/execution/index.js +2 -0
  191. package/build/execution/index.js.map +1 -0
  192. package/build/execution/types.d.ts +50 -0
  193. package/build/execution/types.d.ts.map +1 -0
  194. package/build/execution/types.js +2 -0
  195. package/build/execution/types.js.map +1 -0
  196. package/build/index.d.ts +22 -0
  197. package/build/index.d.ts.map +1 -0
  198. package/build/index.js +21 -0
  199. package/build/index.js.map +1 -0
  200. package/build/integrity/consts.d.ts +226 -0
  201. package/build/integrity/consts.d.ts.map +1 -0
  202. package/build/integrity/consts.js +401 -0
  203. package/build/integrity/consts.js.map +1 -0
  204. package/build/integrity/index.d.ts +4 -0
  205. package/build/integrity/index.d.ts.map +1 -0
  206. package/build/integrity/index.js +3 -0
  207. package/build/integrity/index.js.map +1 -0
  208. package/build/integrity/types.d.ts +35 -0
  209. package/build/integrity/types.d.ts.map +1 -0
  210. package/build/integrity/types.js +2 -0
  211. package/build/integrity/types.js.map +1 -0
  212. package/build/integrity/verify.d.ts +23 -0
  213. package/build/integrity/verify.d.ts.map +1 -0
  214. package/build/integrity/verify.js +198 -0
  215. package/build/integrity/verify.js.map +1 -0
  216. package/build/metadata/consts.d.ts +101 -0
  217. package/build/metadata/consts.d.ts.map +1 -0
  218. package/build/metadata/consts.js +104 -0
  219. package/build/metadata/consts.js.map +1 -0
  220. package/build/metadata/index.d.ts +3 -0
  221. package/build/metadata/index.d.ts.map +1 -0
  222. package/build/metadata/index.js +3 -0
  223. package/build/metadata/index.js.map +1 -0
  224. package/build/metadata/types.d.ts +286 -0
  225. package/build/metadata/types.d.ts.map +1 -0
  226. package/build/metadata/types.js +39 -0
  227. package/build/metadata/types.js.map +1 -0
  228. package/build/moderation/consts.d.ts +58 -0
  229. package/build/moderation/consts.d.ts.map +1 -0
  230. package/build/moderation/consts.js +60 -0
  231. package/build/moderation/consts.js.map +1 -0
  232. package/build/moderation/index.d.ts +5 -0
  233. package/build/moderation/index.d.ts.map +1 -0
  234. package/build/moderation/index.js +4 -0
  235. package/build/moderation/index.js.map +1 -0
  236. package/build/moderation/schemas.d.ts +19 -0
  237. package/build/moderation/schemas.d.ts.map +1 -0
  238. package/build/moderation/schemas.js +26 -0
  239. package/build/moderation/schemas.js.map +1 -0
  240. package/build/moderation/types.d.ts +64 -0
  241. package/build/moderation/types.d.ts.map +1 -0
  242. package/build/moderation/types.js +2 -0
  243. package/build/moderation/types.js.map +1 -0
  244. package/build/moderation/utils.d.ts +21 -0
  245. package/build/moderation/utils.d.ts.map +1 -0
  246. package/build/moderation/utils.js +31 -0
  247. package/build/moderation/utils.js.map +1 -0
  248. package/build/preview/consts.d.ts +10 -0
  249. package/build/preview/consts.d.ts.map +1 -0
  250. package/build/preview/consts.js +11 -0
  251. package/build/preview/consts.js.map +1 -0
  252. package/build/preview/index.d.ts +3 -0
  253. package/build/preview/index.d.ts.map +1 -0
  254. package/build/preview/index.js +2 -0
  255. package/build/preview/index.js.map +1 -0
  256. package/build/preview/types.d.ts +60 -0
  257. package/build/preview/types.d.ts.map +1 -0
  258. package/build/preview/types.js +2 -0
  259. package/build/preview/types.js.map +1 -0
  260. package/build/scaffold/consts.d.ts +25 -0
  261. package/build/scaffold/consts.d.ts.map +1 -0
  262. package/build/scaffold/consts.js +26 -0
  263. package/build/scaffold/consts.js.map +1 -0
  264. package/build/scaffold/helpers.d.ts +35 -0
  265. package/build/scaffold/helpers.d.ts.map +1 -0
  266. package/build/scaffold/helpers.js +54 -0
  267. package/build/scaffold/helpers.js.map +1 -0
  268. package/build/scaffold/index.d.ts +5 -0
  269. package/build/scaffold/index.d.ts.map +1 -0
  270. package/build/scaffold/index.js +4 -0
  271. package/build/scaffold/index.js.map +1 -0
  272. package/build/scaffold/schemas.d.ts +5 -0
  273. package/build/scaffold/schemas.d.ts.map +1 -0
  274. package/build/scaffold/schemas.js +273 -0
  275. package/build/scaffold/schemas.js.map +1 -0
  276. package/build/scaffold/types.d.ts +144 -0
  277. package/build/scaffold/types.d.ts.map +1 -0
  278. package/build/scaffold/types.js +2 -0
  279. package/build/scaffold/types.js.map +1 -0
  280. package/build/skills/catalogue.d.ts +47 -0
  281. package/build/skills/catalogue.d.ts.map +1 -0
  282. package/build/skills/catalogue.js +1566 -0
  283. package/build/skills/catalogue.js.map +1 -0
  284. package/build/skills/consts.d.ts +104 -0
  285. package/build/skills/consts.d.ts.map +1 -0
  286. package/build/skills/consts.js +170 -0
  287. package/build/skills/consts.js.map +1 -0
  288. package/build/skills/index.d.ts +4 -0
  289. package/build/skills/index.d.ts.map +1 -0
  290. package/build/skills/index.js +4 -0
  291. package/build/skills/index.js.map +1 -0
  292. package/build/skills/roles.d.ts +52 -0
  293. package/build/skills/roles.d.ts.map +1 -0
  294. package/build/skills/roles.js +256 -0
  295. package/build/skills/roles.js.map +1 -0
  296. package/build/slot/consts.d.ts +305 -0
  297. package/build/slot/consts.d.ts.map +1 -0
  298. package/build/slot/consts.js +376 -0
  299. package/build/slot/consts.js.map +1 -0
  300. package/build/slot/helpers.d.ts +25 -0
  301. package/build/slot/helpers.d.ts.map +1 -0
  302. package/build/slot/helpers.js +27 -0
  303. package/build/slot/helpers.js.map +1 -0
  304. package/build/slot/index.d.ts +6 -0
  305. package/build/slot/index.d.ts.map +1 -0
  306. package/build/slot/index.js +5 -0
  307. package/build/slot/index.js.map +1 -0
  308. package/build/slot/layout.d.ts +72 -0
  309. package/build/slot/layout.d.ts.map +1 -0
  310. package/build/slot/layout.js +82 -0
  311. package/build/slot/layout.js.map +1 -0
  312. package/build/slot/schemas.d.ts +12 -0
  313. package/build/slot/schemas.d.ts.map +1 -0
  314. package/build/slot/schemas.js +43 -0
  315. package/build/slot/schemas.js.map +1 -0
  316. package/build/slot/types.d.ts +147 -0
  317. package/build/slot/types.d.ts.map +1 -0
  318. package/build/slot/types.js +2 -0
  319. package/build/slot/types.js.map +1 -0
  320. package/build/topology/card.d.ts +23 -0
  321. package/build/topology/card.d.ts.map +1 -0
  322. package/build/topology/card.js +95 -0
  323. package/build/topology/card.js.map +1 -0
  324. package/build/topology/consts.d.ts +32 -0
  325. package/build/topology/consts.d.ts.map +1 -0
  326. package/build/topology/consts.js +55 -0
  327. package/build/topology/consts.js.map +1 -0
  328. package/build/topology/helpers.d.ts +44 -0
  329. package/build/topology/helpers.d.ts.map +1 -0
  330. package/build/topology/helpers.js +112 -0
  331. package/build/topology/helpers.js.map +1 -0
  332. package/build/topology/index.d.ts +5 -0
  333. package/build/topology/index.d.ts.map +1 -0
  334. package/build/topology/index.js +4 -0
  335. package/build/topology/index.js.map +1 -0
  336. package/build/topology/types.d.ts +83 -0
  337. package/build/topology/types.d.ts.map +1 -0
  338. package/build/topology/types.js +2 -0
  339. package/build/topology/types.js.map +1 -0
  340. package/build/types.d.ts +88 -0
  341. package/build/types.d.ts.map +1 -0
  342. package/build/types.js +2 -0
  343. package/build/types.js.map +1 -0
  344. package/build/ux/consts.d.ts +5 -0
  345. package/build/ux/consts.d.ts.map +1 -0
  346. package/build/ux/consts.js +6 -0
  347. package/build/ux/consts.js.map +1 -0
  348. package/build/ux/index.d.ts +4 -0
  349. package/build/ux/index.d.ts.map +1 -0
  350. package/build/ux/index.js +3 -0
  351. package/build/ux/index.js.map +1 -0
  352. package/build/ux/schemas.d.ts +8 -0
  353. package/build/ux/schemas.d.ts.map +1 -0
  354. package/build/ux/schemas.js +91 -0
  355. package/build/ux/schemas.js.map +1 -0
  356. package/build/ux/types.d.ts +21 -0
  357. package/build/ux/types.d.ts.map +1 -0
  358. package/build/ux/types.js +2 -0
  359. package/build/ux/types.js.map +1 -0
  360. package/package.json +71 -0
  361. package/src/agent/index.ts +4 -0
  362. package/src/agent/memory.ts +16 -0
  363. package/src/agent/spectator/consts.ts +10 -0
  364. package/src/agent/spectator/index.ts +3 -0
  365. package/src/agent/spectator/types.ts +14 -0
  366. package/src/agent/types.ts +10 -0
  367. package/src/areas/consts.ts +112 -0
  368. package/src/areas/index.ts +3 -0
  369. package/src/areas/types.ts +29 -0
  370. package/src/ba/consts.ts +40 -0
  371. package/src/ba/helpers.ts +93 -0
  372. package/src/ba/index.ts +5 -0
  373. package/src/ba/schemas.ts +196 -0
  374. package/src/ba/types.ts +125 -0
  375. package/src/blueprint/case.ts +272 -0
  376. package/src/blueprint/consts.ts +11 -0
  377. package/src/blueprint/index.ts +6 -0
  378. package/src/blueprint/resolve.ts +133 -0
  379. package/src/blueprint/schemas.ts +44 -0
  380. package/src/blueprint/types.ts +204 -0
  381. package/src/branding.ts +34 -0
  382. package/src/connect/consts.ts +441 -0
  383. package/src/connect/entrypoints.ts +291 -0
  384. package/src/connect/errors.ts +91 -0
  385. package/src/connect/index.ts +7 -0
  386. package/src/connect/ops.ts +208 -0
  387. package/src/connect/references.ts +89 -0
  388. package/src/connect/schemas.ts +384 -0
  389. package/src/connect/types.ts +456 -0
  390. package/src/consts.ts +34 -0
  391. package/src/convert/consts.ts +672 -0
  392. package/src/convert/helpers.ts +340 -0
  393. package/src/convert/index.ts +10 -0
  394. package/src/convert/schemas.ts +663 -0
  395. package/src/convert/types.ts +741 -0
  396. package/src/design/consts.ts +26 -0
  397. package/src/design/helpers.ts +255 -0
  398. package/src/design/index.ts +5 -0
  399. package/src/design/runtime.ts +142 -0
  400. package/src/design/schemas.ts +384 -0
  401. package/src/design/types.ts +191 -0
  402. package/src/dev/consts.ts +35 -0
  403. package/src/dev/index.ts +4 -0
  404. package/src/dev/schemas.ts +124 -0
  405. package/src/dev/types.ts +47 -0
  406. package/src/execution/consts.ts +37 -0
  407. package/src/execution/index.ts +3 -0
  408. package/src/execution/types.ts +55 -0
  409. package/src/index.ts +22 -0
  410. package/src/integrity/consts.ts +477 -0
  411. package/src/integrity/index.ts +3 -0
  412. package/src/integrity/types.ts +37 -0
  413. package/src/integrity/verify.ts +221 -0
  414. package/src/metadata/consts.ts +118 -0
  415. package/src/metadata/index.ts +3 -0
  416. package/src/metadata/types.ts +310 -0
  417. package/src/moderation/consts.ts +59 -0
  418. package/src/moderation/index.ts +4 -0
  419. package/src/moderation/schemas.ts +28 -0
  420. package/src/moderation/types.ts +68 -0
  421. package/src/moderation/utils.ts +35 -0
  422. package/src/preview/consts.ts +9 -0
  423. package/src/preview/index.ts +3 -0
  424. package/src/preview/types.ts +79 -0
  425. package/src/scaffold/consts.ts +26 -0
  426. package/src/scaffold/helpers.ts +84 -0
  427. package/src/scaffold/index.ts +4 -0
  428. package/src/scaffold/schemas.ts +283 -0
  429. package/src/scaffold/types.ts +118 -0
  430. package/src/skills/catalogue.ts +1617 -0
  431. package/src/skills/consts.ts +183 -0
  432. package/src/skills/index.ts +4 -0
  433. package/src/skills/roles.ts +299 -0
  434. package/src/slot/consts.ts +393 -0
  435. package/src/slot/helpers.ts +34 -0
  436. package/src/slot/index.ts +5 -0
  437. package/src/slot/layout.ts +141 -0
  438. package/src/slot/schemas.ts +46 -0
  439. package/src/slot/types.ts +164 -0
  440. package/src/topology/card.ts +106 -0
  441. package/src/topology/consts.ts +59 -0
  442. package/src/topology/helpers.ts +138 -0
  443. package/src/topology/index.ts +5 -0
  444. package/src/topology/types.ts +86 -0
  445. package/src/types.ts +104 -0
  446. package/src/ux/consts.ts +5 -0
  447. package/src/ux/index.ts +4 -0
  448. package/src/ux/schemas.ts +97 -0
  449. package/src/ux/types.ts +25 -0
  450. package/tests/connect-convert.spec.ts +161 -0
  451. package/tests/convert.spec.ts +318 -0
  452. package/tests/design.spec.ts +136 -0
  453. package/tsconfig.json +16 -0
@@ -0,0 +1,393 @@
1
+ /**
2
+ * The slot command vocabulary — what one process asks another to do to a target project's tree.
3
+ *
4
+ * It lives here, beside the target-shape manifest and the metadata layout, because THREE
5
+ * independent executors answer it and none of them owns it: the publisher inside an ephemeral or
6
+ * production pod, the agent's remote helper that speaks to that publisher, and the connector SDK
7
+ * that executes the same commands on a developer's own machine. A vocabulary owned by one of them
8
+ * is a vocabulary the other two copy, and a copied enum drifts silently — the last time a role
9
+ * vocabulary was duplicated, one copy answered `common` for every role the other had added and
10
+ * type checks ran against the wrong package with nothing failing.
11
+ */
12
+
13
+ /**
14
+ * Which workload a slot record describes.
15
+ *
16
+ * `Ephemeral` is the live-preview pod (publisher + one-shot builds + SSE reload), `Production`
17
+ * the hardened pod that serves real end users from prebuilt artifacts, and `Local` a target
18
+ * project that lives on a developer's own machine and has no pod at all — its file, shell and git
19
+ * commands are executed by the connector on that machine, and nothing about it is provisioned,
20
+ * routed, reconciled or published.
21
+ */
22
+ export enum WorkloadKind {
23
+ Ephemeral = 'ephemeral',
24
+ Production = 'production',
25
+ /**
26
+ * The target project is on the user's disk, reached through a connector session.
27
+ *
28
+ * A slot record still exists — it is what carries the project's slug, its OIDC client and its
29
+ * configuration — but it owns no namespace, no volume, no hostname and no certificate. Every
30
+ * cloud-only operation (run/stop/restart the sandbox, publish, push to a remote, watch files)
31
+ * refuses for it rather than half-working.
32
+ */
33
+ Local = 'local',
34
+ }
35
+
36
+ export enum SlotCommandType {
37
+ Files = 'files',
38
+ Shell = 'shell',
39
+ Git = 'git',
40
+ }
41
+
42
+ export enum SlotGitCommand {
43
+ Ensure = 'ensure',
44
+ /**
45
+ * Bring a remote repository's tree onto a volume that already exists.
46
+ *
47
+ * NOT `git clone`: a slot's directory is never empty — provisioning leaves its own metadata
48
+ * there — and `git clone` refuses a non-empty destination. The executor therefore initializes,
49
+ * adds the remote, fetches at a bounded depth and checks the branch out over the tree.
50
+ */
51
+ Clone = 'clone',
52
+ Status = 'status',
53
+ Commit = 'commit',
54
+ Log = 'log',
55
+ Discard = 'discard',
56
+ RevertTo = 'revertTo',
57
+ SetRemote = 'setRemote',
58
+ Push = 'push',
59
+ Pull = 'pull',
60
+ }
61
+
62
+ export enum SlotFileCommand {
63
+ EmptyProject = 'emptyProject',
64
+ DeleteProject = 'deleteProject',
65
+ InitializeProject = 'initializeProject',
66
+ GetSourceList = 'getSourceList',
67
+ GetStructuredList = 'getStructuredList',
68
+ ReadFile = 'readFile',
69
+ ReadSource = 'readSource',
70
+ ReadPossibleSource = 'readPossibleSource',
71
+ ReadSources = 'readSources',
72
+ WriteFile = 'writeFile',
73
+ WriteSource = 'writeSource',
74
+ DeleteFile = 'deleteFile',
75
+ FindFilesWithEnvVars = 'findFilesWithEnvVars',
76
+ GetRootPath = 'getRootPath',
77
+ /**
78
+ * List a tree with a size and a binary flag per entry, bounded by a caller-given limit.
79
+ *
80
+ * The reason it exists rather than being composed out of {@link SlotFileCommand.GetSourceList}
81
+ * plus a read per file: a foreign repository can hold a hundred thousand files, and one round
82
+ * trip each — over a signed HTTP call to a pod, or over a connector on somebody's laptop — is
83
+ * not a slower version of the same thing, it is a walk that never finishes.
84
+ */
85
+ StatTree = 'statTree',
86
+ /**
87
+ * Read the first N bytes of one file.
88
+ *
89
+ * A census classifies a file from its head; reading whole files to do it would hold a 1 MB
90
+ * export in memory to look at its first line. The answer is text, so a binary head comes back
91
+ * as whatever decoding produced — which is exactly the signal the entropy classification wants.
92
+ */
93
+ ReadHead = 'readHead',
94
+ /**
95
+ * Move everything in the project root into a subdirectory, keeping a named few in place.
96
+ *
97
+ * One command rather than a listing plus a move per file, because it must be ATOMIC from the
98
+ * caller's point of view: a relocation interrupted half way leaves a tree that is neither the
99
+ * origin nor a target, and nothing downstream can tell which files already moved. Binary-safe —
100
+ * it moves paths and never reads contents.
101
+ */
102
+ Relocate = 'relocate',
103
+ /** Delete a directory and everything under it. The purge of a relocated origin. */
104
+ RemoveTree = 'removeTree',
105
+ }
106
+
107
+ export enum SlotShellCommand {
108
+ Bun = 'bun',
109
+ /**
110
+ * Re-resolve every dependency from scratch, then install.
111
+ *
112
+ * NOT `bun install` — that reproduces the lockfile, which is the whole problem. A target's
113
+ * `@owlmeans/*` ranges are carets, but its lockfile was written once at project init and pins
114
+ * the versions that were current that day; a republished framework fix therefore never reaches
115
+ * a slot that already exists, however many times it is rebuilt. Truncating the lockfile first
116
+ * is what project initialization does, so a reinstalled slot converges on the dependency state
117
+ * a freshly created one would have.
118
+ *
119
+ * It is deliberately NOT part of {@link SlotShellCommand.Build}: that runs after every agent
120
+ * file write and has to stay seconds long. This is minutes, and only a user asking for it.
121
+ */
122
+ Reinstall = 'reinstall',
123
+ BuildCommon = 'buildCommon',
124
+ Validate = 'validate',
125
+ ValidateWithRenderer = 'validateWithRenderer',
126
+ Build = 'build',
127
+ /**
128
+ * Reconcile the target's database with its code.
129
+ *
130
+ * The target owns its own structure: every `@owlmeans/postgres` resource creates and updates its
131
+ * table while the OwlMeans context initializes. So a sync is not a command run against the source
132
+ * tree — it is *bootstrap the role/database if needed, then restart the backend* and report
133
+ * whatever DDL or migration error the boot produced. There is nothing to generate and no
134
+ * migration file to apply.
135
+ */
136
+ DbSync = 'dbSync',
137
+ /** Rollup-build the backend only — the type check the frontend renderer build cannot give it. */
138
+ ValidateBackend = 'validateBackend',
139
+ /**
140
+ * Boot the target backend for real, in isolation, and report why it failed.
141
+ *
142
+ * A foreign key that names a resource nothing registers, a service alias nobody provides, a
143
+ * context that wedges on init — none of it is visible to `tsc`, and all of it kills the app at
144
+ * startup. The check runs a SECOND backend process on its own port against a scratch schema,
145
+ * reads the target's own health verdict and kills it again, so the serving backend and the
146
+ * live preview are untouched.
147
+ *
148
+ * The command STARTS the check and returns immediately (`{ result: null, started: true }`);
149
+ * the verdict is read with {@link SlotShellCommand.BootCheckStatus}. A boot is minutes of
150
+ * build + startup, and holding one HTTP request open for it made a slot fault indistinguishable
151
+ * from a hung agent for the whole of the caller's timeout. A second start while one runs joins
152
+ * the running check rather than spawning another instance onto the port.
153
+ */
154
+ BootCheck = 'bootCheck',
155
+ /**
156
+ * Report the boot check started by {@link SlotShellCommand.BootCheck}:
157
+ * `{ running, startedAt, report }`. `report` is the last completed verdict, so a poll that
158
+ * arrives after completion still gets the answer.
159
+ */
160
+ BootCheckStatus = 'bootCheckStatus',
161
+ /**
162
+ * Report whether the sandbox still holds the generated application.
163
+ *
164
+ * Structural, cheap and model-free: a handful of file reads checked against
165
+ * `TARGET_INTEGRITY_FILES`. It exists as a command because the publisher is the only process
166
+ * with the volume in front of it, and the agent needs the same answer before it lets a git
167
+ * merge reach a build. The publisher enforces the manifest on its own before every spawn
168
+ * regardless — this command is how a caller asks first rather than finding out from a
169
+ * failed build.
170
+ */
171
+ Integrity = 'integrity',
172
+ }
173
+
174
+ /**
175
+ * A ROLE in the target project, as it travels on the wire.
176
+ *
177
+ * Not a directory name. A role is resolved to a directory per LAYOUT (see `./layout.js`); nothing
178
+ * may join these values onto a path.
179
+ *
180
+ * Two generations of vocabulary live here at once, and both arrive over the wire. `Frontend` and
181
+ * `Backend` are v1's names — "the browser side" and "the server side" — and every already-published
182
+ * slot still speaks them. `Api`, `Web` and `Worker` are what the current agent library sends, and
183
+ * `Backend` means something DIFFERENT to it: v2 split the server in two, so `backend` is the shared
184
+ * library that `api` and `worker` compile against, and `api` is the HTTP server. That is why the
185
+ * mapping is per-layout rather than a rename.
186
+ *
187
+ * Every value any sender can produce must be a member. It was the three v1 names alone while the
188
+ * library had already moved to five, and the role→directory fall-through then answered `common`
189
+ * for `api`, `web` and `worker` alike — so a type check ran against the shared package instead of
190
+ * the one under repair. Nothing failed; the answers were simply about another package.
191
+ */
192
+ export enum SubProject {
193
+ Common = 'common',
194
+ /** v1: the browser app. v2 sends {@link Web} instead; kept because old slots still send this. */
195
+ Frontend = 'frontend',
196
+ /** v1: the HTTP server. v2: the shared library `api` and `worker` are built against. */
197
+ Backend = 'backend',
198
+ /** v2: the HTTP server. */
199
+ Api = 'api',
200
+ /** v2: the browser app. */
201
+ Web = 'web',
202
+ /** v2: the queue consumer. */
203
+ Worker = 'worker',
204
+ }
205
+
206
+ /**
207
+ * The ports a generated target binds, and the marker that tells its two identical processes apart.
208
+ *
209
+ * They are contract, not preference: the publisher composes the pod's environment from them, the
210
+ * connector composes a local `.env` from the same values, and the target's own configuration reads
211
+ * them back. A local run and a slot run therefore address the app the same way.
212
+ */
213
+ export const TARGET_API_PORT = 3000
214
+ export const TARGET_WEB_PORT = 5173
215
+ export const TARGET_WORKER_PORT = 3003
216
+ export const TARGET_API_BASE = 'api'
217
+ /** The argv marker separating the worker process from the api's — both run the same `dist/index.js`. */
218
+ export const TARGET_WORKER_MARKER = '--viable-worker'
219
+ /**
220
+ * The api's own marker, so a leftover can be told from the worker and the boot check.
221
+ *
222
+ * All three run `bun dist/index.js`, and reclaiming a port by that alone would kill whichever of
223
+ * them happened to match. Only a LOCAL run passes it — in a pod the process is the container's and
224
+ * a restart is Kubernetes's business.
225
+ */
226
+ export const TARGET_API_MARKER = '--viable-api'
227
+ /** Port and schema the isolated boot check uses, so it never touches the serving backend. */
228
+ export const TARGET_BOOTCHECK_PORT = 3100
229
+ export const TARGET_BOOTCHECK_SCHEMA = 'bootcheck'
230
+ export const TARGET_BOOTCHECK_MARKER = '--viable-boot-check'
231
+
232
+ /**
233
+ * The address a LOCAL target answers at.
234
+ *
235
+ * Stored on the slot record as `host` at creation and read back from there by everything that
236
+ * routes, redirects or previews — never recomposed. A local slot's origin is `http://` because it
237
+ * is a loopback address; every other slot kind is `https://`.
238
+ */
239
+ export const LOCAL_SLOT_HOST = `localhost:${TARGET_WEB_PORT}`
240
+
241
+ /**
242
+ * EXECUTOR-side ceilings: how long the process holding the tree may spend on one command.
243
+ *
244
+ * Applied by whoever actually runs the command — the publisher in a pod, the connector on a
245
+ * developer's machine — so a wedged build fails the request instead of holding it open forever.
246
+ */
247
+ export const COMMAND_DEADLINES: Record<string, number> = {
248
+ [SlotShellCommand.Build]: 360_000,
249
+ [SlotShellCommand.Validate]: 360_000,
250
+ [SlotShellCommand.ValidateWithRenderer]: 360_000,
251
+ [SlotShellCommand.ValidateBackend]: 360_000,
252
+ [SlotShellCommand.BuildCommon]: 360_000,
253
+ [SlotShellCommand.BootCheck]: 30_000,
254
+ [SlotShellCommand.BootCheckStatus]: 10_000,
255
+ [SlotShellCommand.DbSync]: 120_000,
256
+ [SlotShellCommand.Bun]: 600_000,
257
+ // A full re-resolve fetches every dependency again, with nothing left in the lockfile to
258
+ // shortcut it — measurably longer than the incremental install `Bun` covers.
259
+ [SlotShellCommand.Reinstall]: 900_000,
260
+ // Eighteen file reads and a list of string comparisons. Anything slower than this means the
261
+ // volume itself is not answering, which is not something a longer wait improves.
262
+ [SlotShellCommand.Integrity]: 15_000,
263
+ }
264
+
265
+ export const DEFAULT_COMMAND_DEADLINE = 60_000
266
+
267
+ /**
268
+ * EXECUTOR-side ceilings for the git commands whose real duration is not a git command's.
269
+ *
270
+ * Everything git does inside a slot is local and takes seconds — except a clone, which is a
271
+ * network fetch of somebody else's repository and is measured in minutes. Bounding it by the
272
+ * generic git deadline made a conversion's very first step fail on any repository large enough
273
+ * to be worth converting.
274
+ */
275
+ export const GIT_COMMAND_DEADLINES: Partial<Record<SlotGitCommand, number>> = {
276
+ [SlotGitCommand.Clone]: 600_000,
277
+ }
278
+
279
+ /** What every other git command gets. The value the type-level branch used to hard-code. */
280
+ export const DEFAULT_GIT_COMMAND_DEADLINE = 60_000
281
+
282
+ /**
283
+ * EXECUTOR-side ceilings for the file commands that walk or move a whole tree.
284
+ *
285
+ * The other file commands are one path each and finish in milliseconds; these three are bounded
286
+ * by how big the tree is, which for an origin project is set by whoever wrote it.
287
+ */
288
+ export const FILE_COMMAND_DEADLINES: Partial<Record<SlotFileCommand, number>> = {
289
+ [SlotFileCommand.StatTree]: 120_000,
290
+ [SlotFileCommand.Relocate]: 300_000,
291
+ [SlotFileCommand.RemoveTree]: 120_000,
292
+ [SlotFileCommand.ReadHead]: 30_000,
293
+ }
294
+
295
+ /** What every other file command gets. The value the type-level branch used to hard-code. */
296
+ export const DEFAULT_FILE_COMMAND_DEADLINE = 30_000
297
+
298
+ /**
299
+ * CALLER-side ceilings per command type: how long the asker waits for an answer.
300
+ *
301
+ * Deliberately separate from {@link COMMAND_DEADLINES} and deliberately larger — the caller's
302
+ * bound must outlast the executor's, or a command that failed cleanly inside its own deadline
303
+ * reaches the caller as a timeout and the real reason is lost.
304
+ */
305
+ export const COMMAND_TIMEOUTS: Partial<Record<SlotCommandType, number>> = {
306
+ [SlotCommandType.Files]: 60_000,
307
+ [SlotCommandType.Git]: 120_000,
308
+ [SlotCommandType.Shell]: 1_200_000,
309
+ }
310
+
311
+ export const DEFAULT_COMMAND_TIMEOUT = 60_000
312
+
313
+ /**
314
+ * Per-COMMAND caller ceilings, for the shell commands whose real duration is known.
315
+ *
316
+ * The type-level ceiling has to cover `bun install`, so every shell command inherited twenty
317
+ * minutes — including a boot check the executor itself caps at eight, and a build it caps at
318
+ * five. When one of them wedged, the caller waited out the twenty regardless, and the story it
319
+ * belonged to sat frozen for the whole of it. A command with a known duration gets a bound close
320
+ * to that duration; anything not listed keeps the generous type default, which is what an
321
+ * install still needs.
322
+ */
323
+ export const SHELL_COMMAND_TIMEOUTS: Record<string, number> = {
324
+ [SlotShellCommand.BootCheck]: 45_000, // starts the job and returns
325
+ [SlotShellCommand.BootCheckStatus]: 15_000, // one status read
326
+ [SlotShellCommand.Build]: 380_000, // executor BUILD_TIMEOUT (300s) + margin
327
+ [SlotShellCommand.Validate]: 380_000,
328
+ [SlotShellCommand.ValidateWithRenderer]: 380_000,
329
+ [SlotShellCommand.ValidateBackend]: 380_000,
330
+ [SlotShellCommand.BuildCommon]: 380_000,
331
+ [SlotShellCommand.DbSync]: 130_000,
332
+ [SlotShellCommand.Reinstall]: 920_000, // executor deadline (900s) + margin
333
+ [SlotShellCommand.Integrity]: 25_000, // executor deadline (15s) + margin
334
+ }
335
+
336
+ /**
337
+ * Per-COMMAND caller ceilings for git and for files.
338
+ *
339
+ * Each is its executor deadline plus the same 40 s margin: the caller's bound must outlast the
340
+ * executor's, or a command that failed cleanly inside its own deadline reaches the caller as a
341
+ * timeout and the real reason — the one the executor took the trouble to produce — is lost.
342
+ */
343
+ export const GIT_COMMAND_TIMEOUTS: Partial<Record<SlotGitCommand, number>> = {
344
+ [SlotGitCommand.Clone]: 640_000,
345
+ }
346
+
347
+ export const FILE_COMMAND_TIMEOUTS: Partial<Record<SlotFileCommand, number>> = {
348
+ [SlotFileCommand.StatTree]: 160_000,
349
+ [SlotFileCommand.Relocate]: 340_000,
350
+ [SlotFileCommand.RemoveTree]: 160_000,
351
+ [SlotFileCommand.ReadHead]: 70_000,
352
+ }
353
+
354
+ /** The per-command caller bound for one command, or nothing where its type's default is right. */
355
+ const perCommandTimeout = (type: SlotCommandType, command: string): number | undefined => {
356
+ switch (type) {
357
+ case SlotCommandType.Shell: return SHELL_COMMAND_TIMEOUTS[command]
358
+ case SlotCommandType.Git: return GIT_COMMAND_TIMEOUTS[command as SlotGitCommand]
359
+ default: return FILE_COMMAND_TIMEOUTS[command as SlotFileCommand]
360
+ }
361
+ }
362
+
363
+ /**
364
+ * Resolve the caller-side bound for one command.
365
+ *
366
+ * One function rather than three lookups at each call site: an asker that forgets the per-command
367
+ * table inherits twenty minutes for a fifteen-second command, which is the failure this table was
368
+ * added to stop.
369
+ */
370
+ export const commandTimeout = (
371
+ type: SlotCommandType, command: string, override?: number
372
+ ): number => override
373
+ ?? perCommandTimeout(type, command)
374
+ ?? COMMAND_TIMEOUTS[type]
375
+ ?? DEFAULT_COMMAND_TIMEOUT
376
+
377
+ /**
378
+ * Resolve the executor-side deadline for one command.
379
+ *
380
+ * Per-command first, per-type second. It was per-type only, which is how a clone inherited the
381
+ * bound of a `git status` — the same shape as the shell table above, and added for the same
382
+ * reason.
383
+ */
384
+ export const commandDeadline = (type: SlotCommandType, command: string): number => {
385
+ switch (type) {
386
+ case SlotCommandType.Shell:
387
+ return COMMAND_DEADLINES[command] ?? DEFAULT_COMMAND_DEADLINE
388
+ case SlotCommandType.Git:
389
+ return GIT_COMMAND_DEADLINES[command as SlotGitCommand] ?? DEFAULT_GIT_COMMAND_DEADLINE
390
+ default:
391
+ return FILE_COMMAND_DEADLINES[command as SlotFileCommand] ?? DEFAULT_FILE_COMMAND_DEADLINE
392
+ }
393
+ }
@@ -0,0 +1,34 @@
1
+ import { WorkloadKind } from './consts.js'
2
+
3
+ /** The minimum a caller must know about a slot to address it. */
4
+ export interface AddressableSlot {
5
+ kind?: WorkloadKind
6
+ host?: string
7
+ }
8
+
9
+ /**
10
+ * The origin a slot's application answers at.
11
+ *
12
+ * Read back from the slot's stored `host`, never recomposed from a slug — a preview host is a
13
+ * CLAIMED resource with a certificate behind it, and the name a slot ended up with is not always
14
+ * the name its project would compose today. What this adds is the scheme, which is the one part
15
+ * that follows from the kind rather than from the record: a local target is a loopback address and
16
+ * therefore `http`, everything else is TLS-terminated at an edge and therefore `https`.
17
+ */
18
+ export const slotOrigin = (slot: AddressableSlot): string => {
19
+ const host = slot.host ?? ''
20
+ if (host === '') return ''
21
+ if (host.startsWith('http://') || host.startsWith('https://')) return host
22
+
23
+ return `${slot.kind === WorkloadKind.Local ? 'http' : 'https'}://${host}`
24
+ }
25
+
26
+ /**
27
+ * The exact redirect URIs a target's OIDC client must carry for one origin.
28
+ *
29
+ * Exact, because a provider matches a redirect URI literally and refuses a wildcard — and both
30
+ * entries are needed: the callback the login round trip returns to, and the bare origin, which is
31
+ * where the application's own logout lands.
32
+ */
33
+ export const targetRedirectUrisForOrigin = (origin: string, callbackPath: string): string[] =>
34
+ origin === '' ? [] : [origin, `${origin}${callbackPath}`]
@@ -0,0 +1,5 @@
1
+ export * from './consts.js'
2
+ export * from './schemas.js'
3
+ export * from './layout.js'
4
+ export * from './helpers.js'
5
+ export type * from './types.js'
@@ -0,0 +1,141 @@
1
+ import { TargetLayout } from '../integrity/index.js'
2
+ import { packageForRole, resolveTopology, topologyOf } from '../topology/index.js'
3
+ import { SubProject } from './consts.js'
4
+
5
+ /**
6
+ * Where each role lives, for one layout. Directory names are target-root-relative.
7
+ *
8
+ * The pure half of layout resolution. Whoever holds the tree — the publisher over a pod volume,
9
+ * the connector over a directory on a developer's machine — adds the two filesystem probes that
10
+ * pick the layout and turn these names into absolute paths. The TABLES are shared so the two
11
+ * cannot disagree about what a role means.
12
+ */
13
+ export interface TargetPaths {
14
+ layout: TargetLayout
15
+ /** The directory holding the workspace packages — `packages` or `sources`. */
16
+ dir: string
17
+ /** The package whose `dist/index.js` runs as the target's HTTP server. */
18
+ api: string
19
+ /** The package whose `dist/` is served to a browser. */
20
+ web: string
21
+ /** The shared library the other two compile against. */
22
+ common: string
23
+ /**
24
+ * The package whose `dist/index.js` runs as the target's queue worker, when the target has one.
25
+ *
26
+ * Absent for v1, which had no such package and never will — a target's tree is the one it was
27
+ * initialized with. Present for v2 as a NAME, not as a promise: every caller checks the disk
28
+ * before acting on it.
29
+ */
30
+ worker?: string
31
+ /**
32
+ * Every package a full build runs, in dependency order.
33
+ *
34
+ * Longer than the three roles for v2, whose `backend` is a library that both `api` and `worker`
35
+ * import. A caller skips whatever is not on disk — a target need not have a worker.
36
+ */
37
+ build: string[]
38
+ /**
39
+ * The packages built with `tsc -b` and consumed through their `build/` output, in dependency
40
+ * order — never bundled, so their output has to be on disk at RUN time, not only at build time.
41
+ *
42
+ * The bundled packages keep every dependency external, so `bun dist/index.js` resolves
43
+ * `project-backend` from `node_modules` at startup, follows its `main` to `build/index.js` — and
44
+ * if nothing built it, Bun answers `Cannot find package 'project-backend'` and the target exits 1
45
+ * with a message that names a dependency rather than a missing build.
46
+ *
47
+ * v1 got away without this list: it had ONE library and the template shipped its `build/`
48
+ * prebuilt. v2 deleted those artifacts and added a second library, so every path that builds a
49
+ * target has to build these first or it can never start.
50
+ */
51
+ libraries: string[]
52
+ }
53
+
54
+ /**
55
+ * Where every role lives, per layout — DERIVED from that layout's topology.
56
+ *
57
+ * These were two hand-written records, and the pair could disagree with each other and with the
58
+ * tree: `build` listed the packages in an order somebody maintained by hand beside the graph that
59
+ * actually decides it, and `libraries` was a second copy of "which of these are built with
60
+ * `tsc -b`". Both are now read off {@link LAYOUT_TOPOLOGIES}, so a package added to a topology
61
+ * appears in the build order, in the library order and in the role map at once, or in none of them.
62
+ *
63
+ * The VALUES are unchanged, and `topology.spec.ts` pins them against the tables they replaced.
64
+ */
65
+ const pathsOfTopology = (layout: TargetLayout): TargetPaths => {
66
+ const topology = resolveTopology(topologyOf(layout))
67
+ const dirOf = (role: SubProject): string | undefined => packageForRole(topology, role)?.name
68
+
69
+ return {
70
+ layout,
71
+ dir: topology.dir,
72
+ // The three roles every arrangement has. A topology without one is not a target, so the
73
+ // fallback is the role's own name rather than a silent `undefined` reaching a path join.
74
+ api: dirOf(SubProject.Api) ?? SubProject.Api,
75
+ web: dirOf(SubProject.Web) ?? SubProject.Web,
76
+ common: dirOf(SubProject.Common) ?? SubProject.Common,
77
+ // A NAME, not a promise — every caller checks the disk before acting on it.
78
+ ...(dirOf(SubProject.Worker) != null ? { worker: dirOf(SubProject.Worker) } : {}),
79
+ build: topology.build,
80
+ libraries: topology.libraries,
81
+ }
82
+ }
83
+
84
+ export const LAYOUTS: Record<TargetLayout, TargetPaths> = {
85
+ [TargetLayout.V1]: pathsOfTopology(TargetLayout.V1),
86
+ [TargetLayout.V2]: pathsOfTopology(TargetLayout.V2),
87
+ }
88
+
89
+ /**
90
+ * Role → directory, per layout. Total over {@link SubProject} in both layouts, deliberately.
91
+ *
92
+ * The v2 role names have v1 equivalents (`api` is v1's `backend`, `web` its `frontend`) and are
93
+ * mapped to them, so a current sender talking to an old tree still reaches the right package. The
94
+ * one role with no v1 equivalent is `worker`, and it maps to a directory that does not exist there
95
+ * rather than to a plausible one: a command aimed at a package this tree does not have must fail
96
+ * where it is issued. Answering `common` instead — which is what the missing entries used to do —
97
+ * runs it somewhere real and wrong.
98
+ *
99
+ * Totality is what a topology cannot give on its own (it maps only the roles its packages hold),
100
+ * so an unmapped role falls back to its own name here, which is that same visible failure.
101
+ */
102
+ const roleDirsOfTopology = (layout: TargetLayout): Record<SubProject, string> => {
103
+ const topology = resolveTopology(topologyOf(layout))
104
+
105
+ return Object.values(SubProject).reduce<Record<SubProject, string>>((dirs, role) => {
106
+ dirs[role] = packageForRole(topology, role)?.name ?? role
107
+
108
+ return dirs
109
+ }, {} as Record<SubProject, string>)
110
+ }
111
+
112
+ export const ROLE_DIRS: Record<TargetLayout, Record<SubProject, string>> = {
113
+ [TargetLayout.V1]: roleDirsOfTopology(TargetLayout.V1),
114
+ [TargetLayout.V2]: roleDirsOfTopology(TargetLayout.V2),
115
+ }
116
+
117
+ /**
118
+ * The one marker per layout, chosen because it exists in that layout and in no other.
119
+ *
120
+ * `sources/api` cannot appear in a v1 tree and `packages/backend` cannot appear in a v2 one, so a
121
+ * single `stat` settles it. Deliberately not `sources/` alone: v1 packages each have their own
122
+ * `src`, and a directory name that differs by one letter is not something to hang a runtime path
123
+ * resolution on. Ordered — the first marker found wins.
124
+ */
125
+ export const LAYOUT_MARKERS: Array<[TargetLayout, string]> = [
126
+ [TargetLayout.V2, 'sources/api'],
127
+ [TargetLayout.V1, 'packages/backend'],
128
+ ]
129
+
130
+ /**
131
+ * Resolve a wire-level role to the directory it names in a given layout.
132
+ *
133
+ * An unknown value — a role from a sender newer than this reader — falls back to the role's own
134
+ * name, which is the honest guess for a layout whose packages are named after their roles, and
135
+ * which fails visibly rather than resolving to some other package's directory.
136
+ */
137
+ export const subprojectDirOf = (layout: TargetLayout, role: SubProject): string =>
138
+ ROLE_DIRS[layout][role] ?? role
139
+
140
+ /** Where every role lives, for a layout already decided. */
141
+ export const pathsOf = (layout: TargetLayout): TargetPaths => LAYOUTS[layout]
@@ -0,0 +1,46 @@
1
+ import type { JSONSchemaType } from 'ajv'
2
+ import { SlotCommandType, SlotFileCommand, SlotGitCommand, SlotShellCommand } from './consts.js'
3
+ import type { SlotCommandPayload, SlotGitCloneArgs } from './types.js'
4
+
5
+ export const SlotCommandPayloadSchema = {
6
+ type: 'object',
7
+ properties: {
8
+ type: {
9
+ type: 'string',
10
+ enum: Object.values(SlotCommandType)
11
+ },
12
+ command: {
13
+ oneOf: [
14
+ { type: 'string', enum: Object.values(SlotFileCommand) },
15
+ { type: 'string', enum: Object.values(SlotShellCommand) },
16
+ { type: 'string', enum: Object.values(SlotGitCommand) },
17
+ ]
18
+ },
19
+ args: {
20
+ type: 'object',
21
+ nullable: true,
22
+ additionalProperties: true
23
+ }
24
+ },
25
+ required: ['type', 'command'],
26
+ additionalProperties: false
27
+ } as JSONSchemaType<SlotCommandPayload>
28
+
29
+ /**
30
+ * The clone command's arguments, as a signed body carries them.
31
+ *
32
+ * `token` is declared because it is SENT — a body field the schema does not declare is stripped
33
+ * by validation and then verified against a signature the sender made over the whole thing, which
34
+ * the guard reports as a 401 rather than as the validation gap it is.
35
+ */
36
+ export const SlotGitCloneArgsSchema = {
37
+ type: 'object',
38
+ properties: {
39
+ remoteUrl: { type: 'string', minLength: 1, maxLength: 2048 },
40
+ branch: { type: 'string', maxLength: 256, nullable: true },
41
+ depth: { type: 'number', minimum: 0, nullable: true },
42
+ token: { type: 'string', maxLength: 4096, nullable: true },
43
+ },
44
+ required: ['remoteUrl'],
45
+ additionalProperties: false,
46
+ } as unknown as JSONSchemaType<SlotGitCloneArgs>