@kitsi/cli 0.0.1

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 (534) hide show
  1. package/README.md +33 -0
  2. package/dist/bin/args/parser.d.ts +6 -0
  3. package/dist/bin/args/parser.d.ts.map +1 -0
  4. package/dist/bin/args/parser.js +23 -0
  5. package/dist/bin/args/parser.js.map +1 -0
  6. package/dist/bin/args/values.d.ts +5 -0
  7. package/dist/bin/args/values.d.ts.map +1 -0
  8. package/dist/bin/args/values.js +66 -0
  9. package/dist/bin/args/values.js.map +1 -0
  10. package/dist/bin/cli.d.ts +3 -0
  11. package/dist/bin/cli.d.ts.map +1 -0
  12. package/dist/bin/cli.js +169 -0
  13. package/dist/bin/cli.js.map +1 -0
  14. package/dist/bin/commands/base.d.ts +42 -0
  15. package/dist/bin/commands/base.d.ts.map +1 -0
  16. package/dist/bin/commands/base.js +86 -0
  17. package/dist/bin/commands/base.js.map +1 -0
  18. package/dist/bin/commands/cache/clear.d.ts +19 -0
  19. package/dist/bin/commands/cache/clear.d.ts.map +1 -0
  20. package/dist/bin/commands/cache/clear.js +45 -0
  21. package/dist/bin/commands/cache/clear.js.map +1 -0
  22. package/dist/bin/commands/cache/inspect.d.ts +20 -0
  23. package/dist/bin/commands/cache/inspect.d.ts.map +1 -0
  24. package/dist/bin/commands/cache/inspect.js +66 -0
  25. package/dist/bin/commands/cache/inspect.js.map +1 -0
  26. package/dist/bin/commands/cache/stats.d.ts +17 -0
  27. package/dist/bin/commands/cache/stats.d.ts.map +1 -0
  28. package/dist/bin/commands/cache/stats.js +54 -0
  29. package/dist/bin/commands/cache/stats.js.map +1 -0
  30. package/dist/bin/commands/flags.d.ts +41 -0
  31. package/dist/bin/commands/flags.d.ts.map +1 -0
  32. package/dist/bin/commands/flags.js +67 -0
  33. package/dist/bin/commands/flags.js.map +1 -0
  34. package/dist/bin/commands/github/init.d.ts +19 -0
  35. package/dist/bin/commands/github/init.d.ts.map +1 -0
  36. package/dist/bin/commands/github/init.js +93 -0
  37. package/dist/bin/commands/github/init.js.map +1 -0
  38. package/dist/bin/commands/github/secrets.d.ts +18 -0
  39. package/dist/bin/commands/github/secrets.d.ts.map +1 -0
  40. package/dist/bin/commands/github/secrets.js +61 -0
  41. package/dist/bin/commands/github/secrets.js.map +1 -0
  42. package/dist/bin/commands/graph.d.ts +21 -0
  43. package/dist/bin/commands/graph.d.ts.map +1 -0
  44. package/dist/bin/commands/graph.js +74 -0
  45. package/dist/bin/commands/graph.js.map +1 -0
  46. package/dist/bin/commands/init.d.ts +25 -0
  47. package/dist/bin/commands/init.d.ts.map +1 -0
  48. package/dist/bin/commands/init.js +129 -0
  49. package/dist/bin/commands/init.js.map +1 -0
  50. package/dist/bin/commands/list.d.ts +20 -0
  51. package/dist/bin/commands/list.d.ts.map +1 -0
  52. package/dist/bin/commands/list.js +126 -0
  53. package/dist/bin/commands/list.js.map +1 -0
  54. package/dist/bin/commands/migrate.d.ts +18 -0
  55. package/dist/bin/commands/migrate.d.ts.map +1 -0
  56. package/dist/bin/commands/migrate.js +78 -0
  57. package/dist/bin/commands/migrate.js.map +1 -0
  58. package/dist/bin/commands/profile/delete.d.ts +20 -0
  59. package/dist/bin/commands/profile/delete.d.ts.map +1 -0
  60. package/dist/bin/commands/profile/delete.js +31 -0
  61. package/dist/bin/commands/profile/delete.js.map +1 -0
  62. package/dist/bin/commands/profile/export.d.ts +22 -0
  63. package/dist/bin/commands/profile/export.d.ts.map +1 -0
  64. package/dist/bin/commands/profile/export.js +61 -0
  65. package/dist/bin/commands/profile/export.js.map +1 -0
  66. package/dist/bin/commands/profile/import.d.ts +21 -0
  67. package/dist/bin/commands/profile/import.d.ts.map +1 -0
  68. package/dist/bin/commands/profile/import.js +37 -0
  69. package/dist/bin/commands/profile/import.js.map +1 -0
  70. package/dist/bin/commands/profile/list.d.ts +17 -0
  71. package/dist/bin/commands/profile/list.d.ts.map +1 -0
  72. package/dist/bin/commands/profile/list.js +27 -0
  73. package/dist/bin/commands/profile/list.js.map +1 -0
  74. package/dist/bin/commands/profile/show.d.ts +20 -0
  75. package/dist/bin/commands/profile/show.d.ts.map +1 -0
  76. package/dist/bin/commands/profile/show.js +42 -0
  77. package/dist/bin/commands/profile/show.js.map +1 -0
  78. package/dist/bin/commands/profile/utils.d.ts +4 -0
  79. package/dist/bin/commands/profile/utils.d.ts.map +1 -0
  80. package/dist/bin/commands/profile/utils.js +15 -0
  81. package/dist/bin/commands/profile/utils.js.map +1 -0
  82. package/dist/bin/commands/run.d.ts +36 -0
  83. package/dist/bin/commands/run.d.ts.map +1 -0
  84. package/dist/bin/commands/run.js +42 -0
  85. package/dist/bin/commands/run.js.map +1 -0
  86. package/dist/bin/commands/show.d.ts +22 -0
  87. package/dist/bin/commands/show.d.ts.map +1 -0
  88. package/dist/bin/commands/show.js +131 -0
  89. package/dist/bin/commands/show.js.map +1 -0
  90. package/dist/bin/commands/types.d.ts +20 -0
  91. package/dist/bin/commands/types.d.ts.map +1 -0
  92. package/dist/bin/commands/types.js +88 -0
  93. package/dist/bin/commands/types.js.map +1 -0
  94. package/dist/bin/commands/validate.d.ts +18 -0
  95. package/dist/bin/commands/validate.d.ts.map +1 -0
  96. package/dist/bin/commands/validate.js +145 -0
  97. package/dist/bin/commands/validate.js.map +1 -0
  98. package/dist/bin/commands/watch.d.ts +38 -0
  99. package/dist/bin/commands/watch.d.ts.map +1 -0
  100. package/dist/bin/commands/watch.js +77 -0
  101. package/dist/bin/commands/watch.js.map +1 -0
  102. package/dist/bin/config/loader.d.ts +59 -0
  103. package/dist/bin/config/loader.d.ts.map +1 -0
  104. package/dist/bin/config/loader.js +114 -0
  105. package/dist/bin/config/loader.js.map +1 -0
  106. package/dist/bin/config/schema.d.ts +3 -0
  107. package/dist/bin/config/schema.d.ts.map +1 -0
  108. package/dist/bin/config/schema.js +102 -0
  109. package/dist/bin/config/schema.js.map +1 -0
  110. package/dist/bin/context.d.ts +31 -0
  111. package/dist/bin/context.d.ts.map +1 -0
  112. package/dist/bin/context.js +2 -0
  113. package/dist/bin/context.js.map +1 -0
  114. package/dist/bin/env.d.ts +3 -0
  115. package/dist/bin/env.d.ts.map +1 -0
  116. package/dist/bin/env.js +17 -0
  117. package/dist/bin/env.js.map +1 -0
  118. package/dist/bin/errors/handler.d.ts +8 -0
  119. package/dist/bin/errors/handler.d.ts.map +1 -0
  120. package/dist/bin/errors/handler.js +83 -0
  121. package/dist/bin/errors/handler.js.map +1 -0
  122. package/dist/bin/errors/index.d.ts +60 -0
  123. package/dist/bin/errors/index.d.ts.map +1 -0
  124. package/dist/bin/errors/index.js +66 -0
  125. package/dist/bin/errors/index.js.map +1 -0
  126. package/dist/bin/infrastructure/environment/reader.d.ts +13 -0
  127. package/dist/bin/infrastructure/environment/reader.d.ts.map +1 -0
  128. package/dist/bin/infrastructure/environment/reader.js +38 -0
  129. package/dist/bin/infrastructure/environment/reader.js.map +1 -0
  130. package/dist/bin/infrastructure/fs/default.d.ts +3 -0
  131. package/dist/bin/infrastructure/fs/default.d.ts.map +1 -0
  132. package/dist/bin/infrastructure/fs/default.js +12 -0
  133. package/dist/bin/infrastructure/fs/default.js.map +1 -0
  134. package/dist/bin/infrastructure/output/presenter.d.ts +21 -0
  135. package/dist/bin/infrastructure/output/presenter.d.ts.map +1 -0
  136. package/dist/bin/infrastructure/output/presenter.js +39 -0
  137. package/dist/bin/infrastructure/output/presenter.js.map +1 -0
  138. package/dist/bin/infrastructure/profiles/repository.d.ts +12 -0
  139. package/dist/bin/infrastructure/profiles/repository.d.ts.map +1 -0
  140. package/dist/bin/infrastructure/profiles/repository.js +26 -0
  141. package/dist/bin/infrastructure/profiles/repository.js.map +1 -0
  142. package/dist/bin/output/colors.d.ts +11 -0
  143. package/dist/bin/output/colors.d.ts.map +1 -0
  144. package/dist/bin/output/colors.js +11 -0
  145. package/dist/bin/output/colors.js.map +1 -0
  146. package/dist/bin/output/formatters/json.d.ts +7 -0
  147. package/dist/bin/output/formatters/json.d.ts.map +1 -0
  148. package/dist/bin/output/formatters/json.js +13 -0
  149. package/dist/bin/output/formatters/json.js.map +1 -0
  150. package/dist/bin/output/formatters/registry.d.ts +11 -0
  151. package/dist/bin/output/formatters/registry.d.ts.map +1 -0
  152. package/dist/bin/output/formatters/registry.js +31 -0
  153. package/dist/bin/output/formatters/registry.js.map +1 -0
  154. package/dist/bin/output/formatters/text.d.ts +6 -0
  155. package/dist/bin/output/formatters/text.d.ts.map +1 -0
  156. package/dist/bin/output/formatters/text.js +9 -0
  157. package/dist/bin/output/formatters/text.js.map +1 -0
  158. package/dist/bin/output/formatters/toon.d.ts +7 -0
  159. package/dist/bin/output/formatters/toon.d.ts.map +1 -0
  160. package/dist/bin/output/formatters/toon.js +103 -0
  161. package/dist/bin/output/formatters/toon.js.map +1 -0
  162. package/dist/bin/output/formatters/types.d.ts +11 -0
  163. package/dist/bin/output/formatters/types.d.ts.map +1 -0
  164. package/dist/bin/output/formatters/types.js +2 -0
  165. package/dist/bin/output/formatters/types.js.map +1 -0
  166. package/dist/bin/output/formatters/value.d.ts +2 -0
  167. package/dist/bin/output/formatters/value.d.ts.map +1 -0
  168. package/dist/bin/output/formatters/value.js +12 -0
  169. package/dist/bin/output/formatters/value.js.map +1 -0
  170. package/dist/bin/output/formatters/yaml.d.ts +6 -0
  171. package/dist/bin/output/formatters/yaml.d.ts.map +1 -0
  172. package/dist/bin/output/formatters/yaml.js +9 -0
  173. package/dist/bin/output/formatters/yaml.js.map +1 -0
  174. package/dist/bin/output/index.d.ts +34 -0
  175. package/dist/bin/output/index.d.ts.map +1 -0
  176. package/dist/bin/output/index.js +40 -0
  177. package/dist/bin/output/index.js.map +1 -0
  178. package/dist/bin/output/interactive.d.ts +29 -0
  179. package/dist/bin/output/interactive.d.ts.map +1 -0
  180. package/dist/bin/output/interactive.js +86 -0
  181. package/dist/bin/output/interactive.js.map +1 -0
  182. package/dist/bin/output/llm.d.ts +33 -0
  183. package/dist/bin/output/llm.d.ts.map +1 -0
  184. package/dist/bin/output/llm.js +115 -0
  185. package/dist/bin/output/llm.js.map +1 -0
  186. package/dist/bin/output/run-formatters/index.d.ts +4 -0
  187. package/dist/bin/output/run-formatters/index.d.ts.map +1 -0
  188. package/dist/bin/output/run-formatters/index.js +3 -0
  189. package/dist/bin/output/run-formatters/index.js.map +1 -0
  190. package/dist/bin/output/run-formatters/interactive.d.ts +54 -0
  191. package/dist/bin/output/run-formatters/interactive.d.ts.map +1 -0
  192. package/dist/bin/output/run-formatters/interactive.js +302 -0
  193. package/dist/bin/output/run-formatters/interactive.js.map +1 -0
  194. package/dist/bin/output/run-formatters/llm-collector.d.ts +9 -0
  195. package/dist/bin/output/run-formatters/llm-collector.d.ts.map +1 -0
  196. package/dist/bin/output/run-formatters/llm-collector.js +36 -0
  197. package/dist/bin/output/run-formatters/llm-collector.js.map +1 -0
  198. package/dist/bin/output/run-formatters/types.d.ts +10 -0
  199. package/dist/bin/output/run-formatters/types.d.ts.map +1 -0
  200. package/dist/bin/output/run-formatters/types.js +2 -0
  201. package/dist/bin/output/run-formatters/types.js.map +1 -0
  202. package/dist/bin/output/runner.d.ts +25 -0
  203. package/dist/bin/output/runner.d.ts.map +1 -0
  204. package/dist/bin/output/runner.js +67 -0
  205. package/dist/bin/output/runner.js.map +1 -0
  206. package/dist/bin/pipeline-authoring.d.ts +64 -0
  207. package/dist/bin/pipeline-authoring.d.ts.map +1 -0
  208. package/dist/bin/pipeline-authoring.js +151 -0
  209. package/dist/bin/pipeline-authoring.js.map +1 -0
  210. package/dist/bin/pipeline-discovery.d.ts +3 -0
  211. package/dist/bin/pipeline-discovery.d.ts.map +1 -0
  212. package/dist/bin/pipeline-discovery.js +50 -0
  213. package/dist/bin/pipeline-discovery.js.map +1 -0
  214. package/dist/bin/pipeline.d.ts +3 -0
  215. package/dist/bin/pipeline.d.ts.map +1 -0
  216. package/dist/bin/pipeline.js +67 -0
  217. package/dist/bin/pipeline.js.map +1 -0
  218. package/dist/bin/profiles/secrets/encrypted.d.ts +4 -0
  219. package/dist/bin/profiles/secrets/encrypted.d.ts.map +1 -0
  220. package/dist/bin/profiles/secrets/encrypted.js +50 -0
  221. package/dist/bin/profiles/secrets/encrypted.js.map +1 -0
  222. package/dist/bin/profiles/secrets/env.d.ts +3 -0
  223. package/dist/bin/profiles/secrets/env.d.ts.map +1 -0
  224. package/dist/bin/profiles/secrets/env.js +12 -0
  225. package/dist/bin/profiles/secrets/env.js.map +1 -0
  226. package/dist/bin/profiles/secrets/index.d.ts +12 -0
  227. package/dist/bin/profiles/secrets/index.d.ts.map +1 -0
  228. package/dist/bin/profiles/secrets/index.js +34 -0
  229. package/dist/bin/profiles/secrets/index.js.map +1 -0
  230. package/dist/bin/profiles/secrets/keychain.d.ts +4 -0
  231. package/dist/bin/profiles/secrets/keychain.d.ts.map +1 -0
  232. package/dist/bin/profiles/secrets/keychain.js +29 -0
  233. package/dist/bin/profiles/secrets/keychain.js.map +1 -0
  234. package/dist/bin/profiles/storage.d.ts +42 -0
  235. package/dist/bin/profiles/storage.d.ts.map +1 -0
  236. package/dist/bin/profiles/storage.js +94 -0
  237. package/dist/bin/profiles/storage.js.map +1 -0
  238. package/dist/bin/prompts/index.d.ts +18 -0
  239. package/dist/bin/prompts/index.d.ts.map +1 -0
  240. package/dist/bin/prompts/index.js +39 -0
  241. package/dist/bin/prompts/index.js.map +1 -0
  242. package/dist/bin/prompts/parameters.d.ts +10 -0
  243. package/dist/bin/prompts/parameters.d.ts.map +1 -0
  244. package/dist/bin/prompts/parameters.js +139 -0
  245. package/dist/bin/prompts/parameters.js.map +1 -0
  246. package/dist/bin/runtime.d.ts +47 -0
  247. package/dist/bin/runtime.d.ts.map +1 -0
  248. package/dist/bin/runtime.js +155 -0
  249. package/dist/bin/runtime.js.map +1 -0
  250. package/dist/bin/services/execution-runner.d.ts +23 -0
  251. package/dist/bin/services/execution-runner.d.ts.map +1 -0
  252. package/dist/bin/services/execution-runner.js +206 -0
  253. package/dist/bin/services/execution-runner.js.map +1 -0
  254. package/dist/bin/services/input-collector.d.ts +14 -0
  255. package/dist/bin/services/input-collector.d.ts.map +1 -0
  256. package/dist/bin/services/input-collector.js +61 -0
  257. package/dist/bin/services/input-collector.js.map +1 -0
  258. package/dist/bin/services/plan-loader.d.ts +16 -0
  259. package/dist/bin/services/plan-loader.d.ts.map +1 -0
  260. package/dist/bin/services/plan-loader.js +48 -0
  261. package/dist/bin/services/plan-loader.js.map +1 -0
  262. package/dist/bin/services/run-orchestrator.d.ts +33 -0
  263. package/dist/bin/services/run-orchestrator.d.ts.map +1 -0
  264. package/dist/bin/services/run-orchestrator.js +303 -0
  265. package/dist/bin/services/run-orchestrator.js.map +1 -0
  266. package/dist/bin/templates/pipeline-templates.d.ts +2 -0
  267. package/dist/bin/templates/pipeline-templates.d.ts.map +1 -0
  268. package/dist/bin/templates/pipeline-templates.js +71 -0
  269. package/dist/bin/templates/pipeline-templates.js.map +1 -0
  270. package/dist/dsl/analysis.d.ts +20 -0
  271. package/dist/dsl/analysis.d.ts.map +1 -0
  272. package/dist/dsl/analysis.js +209 -0
  273. package/dist/dsl/analysis.js.map +1 -0
  274. package/dist/dsl/image.d.ts +14 -0
  275. package/dist/dsl/image.d.ts.map +1 -0
  276. package/dist/dsl/image.js +14 -0
  277. package/dist/dsl/image.js.map +1 -0
  278. package/dist/dsl/index.d.ts +21 -0
  279. package/dist/dsl/index.d.ts.map +1 -0
  280. package/dist/dsl/index.js +12 -0
  281. package/dist/dsl/index.js.map +1 -0
  282. package/dist/dsl/kit.d.ts +20 -0
  283. package/dist/dsl/kit.d.ts.map +1 -0
  284. package/dist/dsl/kit.js +33 -0
  285. package/dist/dsl/kit.js.map +1 -0
  286. package/dist/dsl/module.d.ts +4 -0
  287. package/dist/dsl/module.d.ts.map +1 -0
  288. package/dist/dsl/module.js +4 -0
  289. package/dist/dsl/module.js.map +1 -0
  290. package/dist/dsl/plan-repository.d.ts +10 -0
  291. package/dist/dsl/plan-repository.d.ts.map +1 -0
  292. package/dist/dsl/plan-repository.js +24 -0
  293. package/dist/dsl/plan-repository.js.map +1 -0
  294. package/dist/dsl/plan.d.ts +46 -0
  295. package/dist/dsl/plan.d.ts.map +1 -0
  296. package/dist/dsl/plan.js +95 -0
  297. package/dist/dsl/plan.js.map +1 -0
  298. package/dist/dsl/registry.d.ts +6 -0
  299. package/dist/dsl/registry.d.ts.map +1 -0
  300. package/dist/dsl/registry.js +4 -0
  301. package/dist/dsl/registry.js.map +1 -0
  302. package/dist/dsl/service.d.ts +24 -0
  303. package/dist/dsl/service.d.ts.map +1 -0
  304. package/dist/dsl/service.js +20 -0
  305. package/dist/dsl/service.js.map +1 -0
  306. package/dist/dsl/step.d.ts +10 -0
  307. package/dist/dsl/step.d.ts.map +1 -0
  308. package/dist/dsl/step.js +17 -0
  309. package/dist/dsl/step.js.map +1 -0
  310. package/dist/dsl/task.d.ts +37 -0
  311. package/dist/dsl/task.d.ts.map +1 -0
  312. package/dist/dsl/task.js +66 -0
  313. package/dist/dsl/task.js.map +1 -0
  314. package/dist/dsl/types.d.ts +13 -0
  315. package/dist/dsl/types.d.ts.map +1 -0
  316. package/dist/dsl/types.js +2 -0
  317. package/dist/dsl/types.js.map +1 -0
  318. package/dist/dsl/utils.d.ts +2 -0
  319. package/dist/dsl/utils.d.ts.map +1 -0
  320. package/dist/dsl/utils.js +7 -0
  321. package/dist/dsl/utils.js.map +1 -0
  322. package/dist/engine/cache/analyze.d.ts +12 -0
  323. package/dist/engine/cache/analyze.d.ts.map +1 -0
  324. package/dist/engine/cache/analyze.js +225 -0
  325. package/dist/engine/cache/analyze.js.map +1 -0
  326. package/dist/engine/cache/coordinator.d.ts +99 -0
  327. package/dist/engine/cache/coordinator.d.ts.map +1 -0
  328. package/dist/engine/cache/coordinator.js +800 -0
  329. package/dist/engine/cache/coordinator.js.map +1 -0
  330. package/dist/engine/cache/hasher.d.ts +9 -0
  331. package/dist/engine/cache/hasher.d.ts.map +1 -0
  332. package/dist/engine/cache/hasher.js +50 -0
  333. package/dist/engine/cache/hasher.js.map +1 -0
  334. package/dist/engine/cache/inference.d.ts +3 -0
  335. package/dist/engine/cache/inference.d.ts.map +1 -0
  336. package/dist/engine/cache/inference.js +43 -0
  337. package/dist/engine/cache/inference.js.map +1 -0
  338. package/dist/engine/cache/serialize.d.ts +2 -0
  339. package/dist/engine/cache/serialize.d.ts.map +1 -0
  340. package/dist/engine/cache/serialize.js +21 -0
  341. package/dist/engine/cache/serialize.js.map +1 -0
  342. package/dist/engine/cache/store.d.ts +75 -0
  343. package/dist/engine/cache/store.d.ts.map +1 -0
  344. package/dist/engine/cache/store.js +208 -0
  345. package/dist/engine/cache/store.js.map +1 -0
  346. package/dist/engine/executor/command-runner.d.ts +26 -0
  347. package/dist/engine/executor/command-runner.d.ts.map +1 -0
  348. package/dist/engine/executor/command-runner.js +151 -0
  349. package/dist/engine/executor/command-runner.js.map +1 -0
  350. package/dist/engine/executor/executor.d.ts +6 -0
  351. package/dist/engine/executor/executor.d.ts.map +1 -0
  352. package/dist/engine/executor/executor.js +29 -0
  353. package/dist/engine/executor/executor.js.map +1 -0
  354. package/dist/engine/executor/file-system.d.ts +5 -0
  355. package/dist/engine/executor/file-system.d.ts.map +1 -0
  356. package/dist/engine/executor/file-system.js +50 -0
  357. package/dist/engine/executor/file-system.js.map +1 -0
  358. package/dist/engine/executor/index.d.ts +3 -0
  359. package/dist/engine/executor/index.d.ts.map +1 -0
  360. package/dist/engine/executor/index.js +2 -0
  361. package/dist/engine/executor/index.js.map +1 -0
  362. package/dist/engine/executor/plan-runner.d.ts +35 -0
  363. package/dist/engine/executor/plan-runner.d.ts.map +1 -0
  364. package/dist/engine/executor/plan-runner.js +405 -0
  365. package/dist/engine/executor/plan-runner.js.map +1 -0
  366. package/dist/engine/executor/types.d.ts +73 -0
  367. package/dist/engine/executor/types.d.ts.map +1 -0
  368. package/dist/engine/executor/types.js +2 -0
  369. package/dist/engine/executor/types.js.map +1 -0
  370. package/dist/engine/executor/value-resolver.d.ts +14 -0
  371. package/dist/engine/executor/value-resolver.d.ts.map +1 -0
  372. package/dist/engine/executor/value-resolver.js +63 -0
  373. package/dist/engine/executor/value-resolver.js.map +1 -0
  374. package/dist/engine/handlers/annotate-handler.d.ts +8 -0
  375. package/dist/engine/handlers/annotate-handler.d.ts.map +1 -0
  376. package/dist/engine/handlers/annotate-handler.js +8 -0
  377. package/dist/engine/handlers/annotate-handler.js.map +1 -0
  378. package/dist/engine/handlers/artifact-download-handler.d.ts +8 -0
  379. package/dist/engine/handlers/artifact-download-handler.d.ts.map +1 -0
  380. package/dist/engine/handlers/artifact-download-handler.js +38 -0
  381. package/dist/engine/handlers/artifact-download-handler.js.map +1 -0
  382. package/dist/engine/handlers/artifact-upload-handler.d.ts +8 -0
  383. package/dist/engine/handlers/artifact-upload-handler.d.ts.map +1 -0
  384. package/dist/engine/handlers/artifact-upload-handler.js +26 -0
  385. package/dist/engine/handlers/artifact-upload-handler.js.map +1 -0
  386. package/dist/engine/handlers/bind-service-handler.d.ts +8 -0
  387. package/dist/engine/handlers/bind-service-handler.d.ts.map +1 -0
  388. package/dist/engine/handlers/bind-service-handler.js +8 -0
  389. package/dist/engine/handlers/bind-service-handler.js.map +1 -0
  390. package/dist/engine/handlers/cache-mount-handler.d.ts +8 -0
  391. package/dist/engine/handlers/cache-mount-handler.d.ts.map +1 -0
  392. package/dist/engine/handlers/cache-mount-handler.js +16 -0
  393. package/dist/engine/handlers/cache-mount-handler.js.map +1 -0
  394. package/dist/engine/handlers/command-handler.d.ts +10 -0
  395. package/dist/engine/handlers/command-handler.d.ts.map +1 -0
  396. package/dist/engine/handlers/command-handler.js +11 -0
  397. package/dist/engine/handlers/command-handler.js.map +1 -0
  398. package/dist/engine/handlers/emit-handler.d.ts +8 -0
  399. package/dist/engine/handlers/emit-handler.d.ts.map +1 -0
  400. package/dist/engine/handlers/emit-handler.js +8 -0
  401. package/dist/engine/handlers/emit-handler.js.map +1 -0
  402. package/dist/engine/handlers/env-handler.d.ts +8 -0
  403. package/dist/engine/handlers/env-handler.d.ts.map +1 -0
  404. package/dist/engine/handlers/env-handler.js +9 -0
  405. package/dist/engine/handlers/env-handler.js.map +1 -0
  406. package/dist/engine/handlers/handler.d.ts +18 -0
  407. package/dist/engine/handlers/handler.d.ts.map +1 -0
  408. package/dist/engine/handlers/handler.js +2 -0
  409. package/dist/engine/handlers/handler.js.map +1 -0
  410. package/dist/engine/handlers/pack-handler.d.ts +8 -0
  411. package/dist/engine/handlers/pack-handler.d.ts.map +1 -0
  412. package/dist/engine/handlers/pack-handler.js +16 -0
  413. package/dist/engine/handlers/pack-handler.js.map +1 -0
  414. package/dist/engine/handlers/registry.d.ts +9 -0
  415. package/dist/engine/handlers/registry.d.ts.map +1 -0
  416. package/dist/engine/handlers/registry.js +14 -0
  417. package/dist/engine/handlers/registry.js.map +1 -0
  418. package/dist/engine/handlers/report-handler.d.ts +8 -0
  419. package/dist/engine/handlers/report-handler.d.ts.map +1 -0
  420. package/dist/engine/handlers/report-handler.js +13 -0
  421. package/dist/engine/handlers/report-handler.js.map +1 -0
  422. package/dist/engine/handlers/summary-handler.d.ts +8 -0
  423. package/dist/engine/handlers/summary-handler.d.ts.map +1 -0
  424. package/dist/engine/handlers/summary-handler.js +8 -0
  425. package/dist/engine/handlers/summary-handler.js.map +1 -0
  426. package/dist/engine/handlers/unpack-handler.d.ts +12 -0
  427. package/dist/engine/handlers/unpack-handler.d.ts.map +1 -0
  428. package/dist/engine/handlers/unpack-handler.js +31 -0
  429. package/dist/engine/handlers/unpack-handler.js.map +1 -0
  430. package/dist/engine/handlers/use-handler.d.ts +12 -0
  431. package/dist/engine/handlers/use-handler.d.ts.map +1 -0
  432. package/dist/engine/handlers/use-handler.js +29 -0
  433. package/dist/engine/handlers/use-handler.js.map +1 -0
  434. package/dist/engine/index.d.ts +5 -0
  435. package/dist/engine/index.d.ts.map +1 -0
  436. package/dist/engine/index.js +3 -0
  437. package/dist/engine/index.js.map +1 -0
  438. package/dist/engine/providers/artifact.d.ts +5 -0
  439. package/dist/engine/providers/artifact.d.ts.map +1 -0
  440. package/dist/engine/providers/artifact.js +2 -0
  441. package/dist/engine/providers/artifact.js.map +1 -0
  442. package/dist/engine/providers/cache.d.ts +6 -0
  443. package/dist/engine/providers/cache.d.ts.map +1 -0
  444. package/dist/engine/providers/cache.js +2 -0
  445. package/dist/engine/providers/cache.js.map +1 -0
  446. package/dist/engine/providers/index.d.ts +5 -0
  447. package/dist/engine/providers/index.d.ts.map +1 -0
  448. package/dist/engine/providers/index.js +2 -0
  449. package/dist/engine/providers/index.js.map +1 -0
  450. package/dist/engine/providers/local.d.ts +16 -0
  451. package/dist/engine/providers/local.d.ts.map +1 -0
  452. package/dist/engine/providers/local.js +81 -0
  453. package/dist/engine/providers/local.js.map +1 -0
  454. package/dist/engine/providers/types.d.ts +20 -0
  455. package/dist/engine/providers/types.d.ts.map +1 -0
  456. package/dist/engine/providers/types.js +2 -0
  457. package/dist/engine/providers/types.js.map +1 -0
  458. package/dist/index.d.ts +6 -0
  459. package/dist/index.d.ts.map +1 -0
  460. package/dist/index.js +7 -0
  461. package/dist/index.js.map +1 -0
  462. package/dist/ops/annotate.d.ts +17 -0
  463. package/dist/ops/annotate.d.ts.map +1 -0
  464. package/dist/ops/annotate.js +12 -0
  465. package/dist/ops/annotate.js.map +1 -0
  466. package/dist/ops/artifact.d.ts +30 -0
  467. package/dist/ops/artifact.d.ts.map +1 -0
  468. package/dist/ops/artifact.js +33 -0
  469. package/dist/ops/artifact.js.map +1 -0
  470. package/dist/ops/base.d.ts +21 -0
  471. package/dist/ops/base.d.ts.map +1 -0
  472. package/dist/ops/base.js +2 -0
  473. package/dist/ops/base.js.map +1 -0
  474. package/dist/ops/bind.d.ts +8 -0
  475. package/dist/ops/bind.d.ts.map +1 -0
  476. package/dist/ops/bind.js +7 -0
  477. package/dist/ops/bind.js.map +1 -0
  478. package/dist/ops/bundle.d.ts +20 -0
  479. package/dist/ops/bundle.d.ts.map +1 -0
  480. package/dist/ops/bundle.js +24 -0
  481. package/dist/ops/bundle.js.map +1 -0
  482. package/dist/ops/cache.d.ts +46 -0
  483. package/dist/ops/cache.d.ts.map +1 -0
  484. package/dist/ops/cache.js +33 -0
  485. package/dist/ops/cache.js.map +1 -0
  486. package/dist/ops/env.d.ts +8 -0
  487. package/dist/ops/env.d.ts.map +1 -0
  488. package/dist/ops/env.js +6 -0
  489. package/dist/ops/env.js.map +1 -0
  490. package/dist/ops/errors.d.ts +35 -0
  491. package/dist/ops/errors.d.ts.map +1 -0
  492. package/dist/ops/errors.js +40 -0
  493. package/dist/ops/errors.js.map +1 -0
  494. package/dist/ops/index.d.ts +30 -0
  495. package/dist/ops/index.d.ts.map +1 -0
  496. package/dist/ops/index.js +15 -0
  497. package/dist/ops/index.js.map +1 -0
  498. package/dist/ops/output.d.ts +24 -0
  499. package/dist/ops/output.d.ts.map +1 -0
  500. package/dist/ops/output.js +17 -0
  501. package/dist/ops/output.js.map +1 -0
  502. package/dist/ops/param.d.ts +4 -0
  503. package/dist/ops/param.d.ts.map +1 -0
  504. package/dist/ops/param.js +3 -0
  505. package/dist/ops/param.js.map +1 -0
  506. package/dist/ops/ref.d.ts +21 -0
  507. package/dist/ops/ref.d.ts.map +1 -0
  508. package/dist/ops/ref.js +23 -0
  509. package/dist/ops/ref.js.map +1 -0
  510. package/dist/ops/report.d.ts +10 -0
  511. package/dist/ops/report.d.ts.map +1 -0
  512. package/dist/ops/report.js +13 -0
  513. package/dist/ops/report.js.map +1 -0
  514. package/dist/ops/secret.d.ts +4 -0
  515. package/dist/ops/secret.d.ts.map +1 -0
  516. package/dist/ops/secret.js +2 -0
  517. package/dist/ops/secret.js.map +1 -0
  518. package/dist/ops/shell.d.ts +48 -0
  519. package/dist/ops/shell.d.ts.map +1 -0
  520. package/dist/ops/shell.js +55 -0
  521. package/dist/ops/shell.js.map +1 -0
  522. package/dist/ops/summary.d.ts +9 -0
  523. package/dist/ops/summary.d.ts.map +1 -0
  524. package/dist/ops/summary.js +8 -0
  525. package/dist/ops/summary.js.map +1 -0
  526. package/dist/ops/types.d.ts +23 -0
  527. package/dist/ops/types.d.ts.map +1 -0
  528. package/dist/ops/types.js +5 -0
  529. package/dist/ops/types.js.map +1 -0
  530. package/dist/version.d.ts +2 -0
  531. package/dist/version.d.ts.map +1 -0
  532. package/dist/version.js +2 -0
  533. package/dist/version.js.map +1 -0
  534. package/package.json +86 -0
@@ -0,0 +1,800 @@
1
+ import { join } from 'node:path';
2
+ import { StepBuilder } from '../../dsl/step.js';
3
+ import { OpErrors } from '../../ops/errors.js';
4
+ import { CommandBuilder } from '../../ops/shell.js';
5
+ import { isParamRef, isSecretRef, isValueRef } from '../../ops/types.js';
6
+ import { VERSION } from '../../version.js';
7
+ import { collectFiles, writeFiles } from '../executor/file-system.js';
8
+ import { analyzeTaskSteps } from './analyze.js';
9
+ import { hashFiles, hashNamedValues, hashObject, hashString } from './hasher.js';
10
+ import { inferInputsFromCommand, inferOutputsFromCommand } from './inference.js';
11
+ import { CacheStore } from './store.js';
12
+ export class CacheCoordinator {
13
+ workspace;
14
+ settings;
15
+ logger;
16
+ reporter;
17
+ resolver;
18
+ params;
19
+ getTaskState;
20
+ findTask;
21
+ executeTask;
22
+ cacheStore;
23
+ pendingOpSaves = new Map();
24
+ taskCacheState = new Map();
25
+ constructor(opts) {
26
+ this.workspace = opts.workspace;
27
+ this.settings = opts.settings ?? {};
28
+ this.logger = opts.logger;
29
+ this.reporter = opts.reporter;
30
+ this.resolver = opts.resolver;
31
+ this.params = opts.params;
32
+ this.getTaskState = opts.getTaskState;
33
+ this.findTask = opts.findTask;
34
+ this.executeTask = opts.executeTask;
35
+ const cacheEnabled = this.settings.enabled !== false;
36
+ const cacheRoot = this.settings.directory ?? join(this.workspace, '.kitsi', 'cache');
37
+ this.cacheStore = cacheEnabled ? new CacheStore(cacheRoot) : null;
38
+ }
39
+ async beforeTask(task, env, state) {
40
+ if (!this.shouldAttemptTaskCache(task))
41
+ return null;
42
+ this.ensureCacheStore(task);
43
+ if (!this.cacheAllowedForTask(task)) {
44
+ return this.handleCacheDisabled(task);
45
+ }
46
+ const decision = await this.computeTaskCacheDecision(task, env);
47
+ if (!decision.cacheable) {
48
+ return await this.handleUncacheableDecision(task, decision);
49
+ }
50
+ return await this.tryRestoreTaskCache(task, decision, state);
51
+ }
52
+ async afterStep(task) {
53
+ if (!this.cacheAllowedForTask(task))
54
+ return;
55
+ await this.flushPendingOpSaves(task.config.name);
56
+ }
57
+ async afterTask(task, state, decision) {
58
+ if (!this.cacheAllowedForTask(task))
59
+ return;
60
+ await this.flushPendingOpSaves(task.config.name);
61
+ if (!decision?.cacheable || decision.hit || !this.cacheStore)
62
+ return;
63
+ const outputFiles = decision.outputPatterns.length > 0
64
+ ? await collectFiles(this.workspace, decision.outputPatterns)
65
+ : {};
66
+ const outputs = {};
67
+ for (const [key, value] of state.outputs.entries()) {
68
+ outputs[key] = value;
69
+ }
70
+ const meta = {
71
+ key: decision.key,
72
+ task: task.config.name,
73
+ createdAt: new Date().toISOString(),
74
+ components: decision.components,
75
+ inputs: decision.inputs,
76
+ outputs,
77
+ summaries: state.summaries,
78
+ bundles: Array.from(state.bundles.keys()),
79
+ };
80
+ await this.cacheStore.saveTask(task.config.name, decision.key, {
81
+ meta,
82
+ bundles: state.bundles,
83
+ outputFiles,
84
+ });
85
+ this.recordTaskCacheState(task.config.name, {
86
+ key: decision.key,
87
+ fingerprint: decision.key,
88
+ });
89
+ }
90
+ async tryExecuteOp(op, task, context, state, executeBaseOp, executeOp) {
91
+ if (op.kind === 'cache') {
92
+ const hit = await this.executeCacheOp(op, task, context, state);
93
+ return { handled: true, value: hit };
94
+ }
95
+ if (op.kind === 'cache-or') {
96
+ const hit = await this.executeCacheOrOp(op, task, context, state, executeOp);
97
+ return { handled: true, value: hit };
98
+ }
99
+ if (op.kind === 'command' && op.cache?.enabled === true) {
100
+ const result = await this.executeCachedCommand(op, task, context, state, executeBaseOp);
101
+ return { handled: true, value: result };
102
+ }
103
+ return null;
104
+ }
105
+ wasTaskCached(taskName) {
106
+ return this.taskCacheState.get(taskName)?.hit ?? false;
107
+ }
108
+ shouldAttemptTaskCache(task) {
109
+ if (this.settings.cacheOnly) {
110
+ return (task.config.cache !== undefined ||
111
+ task.config.cacheEnv.length > 0 ||
112
+ task.config.cacheBust !== undefined ||
113
+ task.config.inputs.length > 0 ||
114
+ Boolean(this.settings.inputs?.[task.config.name]?.length));
115
+ }
116
+ return true;
117
+ }
118
+ cacheAllowedForTask(task) {
119
+ if (!this.cacheStore)
120
+ return false;
121
+ if (this.settings.enabled === false)
122
+ return false;
123
+ if (task.config.cache?.enabled === false)
124
+ return false;
125
+ return true;
126
+ }
127
+ cacheExcludes() {
128
+ const defaults = ['.kitsi/**', '.git/**'];
129
+ const configExcludes = this.settings.exclude ?? [];
130
+ return [...defaults, ...configExcludes];
131
+ }
132
+ ensureCacheStore(task) {
133
+ if (this.settings.cacheOnly && !this.cacheStore) {
134
+ throw OpErrors.cache('Cache-only mode requires caching to be enabled')
135
+ .inTask(task.config.name)
136
+ .build();
137
+ }
138
+ }
139
+ handleCacheDisabled(task) {
140
+ if (this.settings.cacheOnly) {
141
+ throw OpErrors.cache(`Caching disabled for task "${task.config.name}"`)
142
+ .inTask(task.config.name)
143
+ .build();
144
+ }
145
+ return null;
146
+ }
147
+ async handleUncacheableDecision(task, decision) {
148
+ if (this.settings.cacheOnly) {
149
+ throw OpErrors.cache(decision.reason ?? 'Task cache is unavailable')
150
+ .inTask(task.config.name)
151
+ .build();
152
+ }
153
+ if (this.settings.debug) {
154
+ await this.emitCacheDebug(task.config.name, decision, 'SKIP');
155
+ }
156
+ return decision;
157
+ }
158
+ async tryRestoreTaskCache(task, decision, state) {
159
+ const entry = await this.cacheStore?.readTask(task.config.name, decision.key, decision.ttlMs);
160
+ const hit = Boolean(entry);
161
+ decision.hit = hit;
162
+ if (hit && entry) {
163
+ await this.restoreTaskCacheEntry(entry, state);
164
+ this.reporter?.emit('cache_hit', { cache: task.config.name, scope: 'task' });
165
+ this.recordTaskCacheState(task.config.name, {
166
+ key: decision.key,
167
+ hit: true,
168
+ fingerprint: decision.key,
169
+ });
170
+ }
171
+ else {
172
+ this.reporter?.emit('cache_miss', { cache: task.config.name, scope: 'task' });
173
+ this.recordTaskCacheState(task.config.name, { key: decision.key, hit: false });
174
+ if (this.settings.cacheOnly) {
175
+ throw OpErrors.cache(`Cache miss for task "${task.config.name}"`)
176
+ .inTask(task.config.name)
177
+ .build();
178
+ }
179
+ }
180
+ if (this.settings.debug) {
181
+ await this.emitCacheDebug(task.config.name, decision, hit ? 'HIT' : 'MISS');
182
+ }
183
+ return decision;
184
+ }
185
+ async restoreTaskCacheEntry(entry, state) {
186
+ if (!entry)
187
+ return;
188
+ state.outputs = new Map(Object.entries(entry.meta.outputs));
189
+ state.summaries = entry.meta.summaries ?? [];
190
+ state.bundles = entry.bundles;
191
+ if (Object.keys(entry.outputFiles).length > 0) {
192
+ await writeFiles(this.workspace, entry.outputFiles);
193
+ }
194
+ }
195
+ async flushPendingOpSaves(taskName) {
196
+ if (!this.cacheStore)
197
+ return;
198
+ const pending = this.pendingOpSaves.get(taskName);
199
+ if (!pending || pending.length === 0)
200
+ return;
201
+ this.pendingOpSaves.set(taskName, []);
202
+ for (const entry of pending) {
203
+ const existing = await this.cacheStore.readOp(entry.key, this.settings.ttlMs ?? null);
204
+ if (existing)
205
+ continue;
206
+ const files = await collectFiles(this.workspace, entry.paths);
207
+ await this.cacheStore.saveOp(entry.key, {
208
+ meta: {
209
+ key: entry.key,
210
+ createdAt: new Date().toISOString(),
211
+ kind: 'cache',
212
+ outputs: entry.paths,
213
+ },
214
+ files,
215
+ });
216
+ }
217
+ }
218
+ recordTaskCacheState(taskName, patch) {
219
+ const current = this.taskCacheState.get(taskName) ?? {};
220
+ const next = { ...current, ...patch };
221
+ this.taskCacheState.set(taskName, next);
222
+ return next;
223
+ }
224
+ async computeTaskCacheDecision(task, env) {
225
+ const analysis = analyzeTaskSteps(task, this.workspace);
226
+ const taskName = task.config.name;
227
+ if (analysis.dynamic) {
228
+ return {
229
+ key: '',
230
+ cacheable: false,
231
+ reason: 'Task uses runtime values to define operations',
232
+ components: {},
233
+ inputs: { patterns: [], files: {} },
234
+ outputPatterns: [],
235
+ };
236
+ }
237
+ const patterns = this.collectTaskInputPatterns(task, analysis, taskName);
238
+ const { inputPatterns, inputPatternsHash, inputs } = await this.resolveTaskInputs(taskName, patterns);
239
+ const envHash = this.hashCacheEnv(task, env);
240
+ const secrets = new Set(analysis.secrets);
241
+ const params = new Set(analysis.params);
242
+ const hasValueRefs = this.collectTaskRefs(task, secrets, params);
243
+ if (hasValueRefs) {
244
+ return {
245
+ key: '',
246
+ cacheable: false,
247
+ reason: 'Task env uses runtime values',
248
+ components: {},
249
+ inputs: { patterns: inputPatterns, files: inputs.files },
250
+ outputPatterns: task.config.cache?.outputs ?? [],
251
+ };
252
+ }
253
+ const secretsHash = hashString(Array.from(secrets).sort().join('\n'));
254
+ const paramsHash = this.hashParams(params);
255
+ const depsHash = await this.hashDependencies(task, analysis.dependencies);
256
+ const opsHash = hashObject(analysis.ops);
257
+ const imageRef = task.config.image?.config.ref ?? 'local';
258
+ const workdir = task.config.image?.config.workdir ?? '';
259
+ const envConfigHash = this.hashEnvConfig(task);
260
+ const outputPatterns = task.config.cache?.outputs ?? [];
261
+ const outputPatternsHash = hashString(outputPatterns.join('\n'));
262
+ const components = {
263
+ taskName,
264
+ image: imageRef,
265
+ workdir,
266
+ inputsHash: inputs.hash,
267
+ inputPatternsHash,
268
+ envHash,
269
+ envConfigHash,
270
+ secretsHash,
271
+ paramsHash,
272
+ depsHash,
273
+ opsHash,
274
+ cacheBust: this.buildCacheBust(task),
275
+ outputPatternsHash,
276
+ version: this.cacheVersion(),
277
+ };
278
+ const key = hashObject(components);
279
+ return {
280
+ key,
281
+ cacheable: true,
282
+ components,
283
+ inputs: { patterns: inputPatterns, files: inputs.files },
284
+ outputPatterns,
285
+ ttlMs: this.resolveTtl(task.config.cache?.ttl),
286
+ };
287
+ }
288
+ collectTaskInputPatterns(task, analysis, taskName) {
289
+ const explicitPatterns = new Set();
290
+ for (const pattern of task.config.inputs)
291
+ explicitPatterns.add(pattern);
292
+ for (const pattern of task.config.cache?.inputs ?? [])
293
+ explicitPatterns.add(pattern);
294
+ for (const pattern of analysis.inputs)
295
+ explicitPatterns.add(pattern);
296
+ for (const pattern of this.settings.inputs?.[taskName] ?? []) {
297
+ explicitPatterns.add(pattern);
298
+ }
299
+ if (explicitPatterns.size > 0)
300
+ return Array.from(explicitPatterns);
301
+ const inferred = new Set();
302
+ let hasUnknownCommand = false;
303
+ for (const signature of analysis.commandSignatures) {
304
+ const patterns = inferInputsFromCommand(signature);
305
+ if (patterns.length === 0) {
306
+ hasUnknownCommand = true;
307
+ continue;
308
+ }
309
+ for (const pattern of patterns)
310
+ inferred.add(pattern);
311
+ }
312
+ if (hasUnknownCommand) {
313
+ inferred.add('**/*');
314
+ }
315
+ return Array.from(inferred);
316
+ }
317
+ async resolveTaskInputs(taskName, patterns) {
318
+ const inputPatterns = patterns.length > 0 ? patterns : ['**/*'];
319
+ if (patterns.length === 0) {
320
+ this.logger.info(this.resolver.redactSecrets(`Cache inputs not detected for task "${taskName}". Consider declaring inputs.`));
321
+ }
322
+ const inputPatternsHash = hashString(inputPatterns.join('\n'));
323
+ const inputs = await hashFiles(this.workspace, inputPatterns, this.cacheExcludes());
324
+ return { inputPatterns, inputPatternsHash, inputs };
325
+ }
326
+ hashCacheEnv(task, env) {
327
+ const cacheEnv = new Set(task.config.cacheEnv);
328
+ for (const name of task.config.cache?.env ?? [])
329
+ cacheEnv.add(name);
330
+ const secretEnv = this.collectSecretEnvNames(task);
331
+ const envValues = {};
332
+ for (const name of cacheEnv) {
333
+ envValues[name] = secretEnv.has(name) ? '__secret__' : (env[name] ?? '__unset__');
334
+ }
335
+ return hashNamedValues(envValues);
336
+ }
337
+ buildCacheBust(task) {
338
+ const cacheBust = [this.settings.bust, task.config.cacheBust, task.config.cache?.key]
339
+ .filter(Boolean)
340
+ .join(':');
341
+ return cacheBust || '';
342
+ }
343
+ collectTaskRefs(task, secrets, params) {
344
+ let hasValueRef = false;
345
+ const collect = (value) => {
346
+ if (isSecretRef(value))
347
+ secrets.add(value.name);
348
+ if (isParamRef(value))
349
+ params.add(value.name);
350
+ if (isValueRef(value)) {
351
+ hasValueRef = true;
352
+ }
353
+ };
354
+ for (const value of Object.values(task.config.env)) {
355
+ collect(value);
356
+ }
357
+ for (const value of Object.values(task.config.image?.config.env ?? {})) {
358
+ collect(value);
359
+ }
360
+ return hasValueRef;
361
+ }
362
+ collectSecretEnvNames(task) {
363
+ const names = new Set();
364
+ for (const [key, value] of Object.entries(task.config.env)) {
365
+ if (isSecretRef(value))
366
+ names.add(key);
367
+ }
368
+ for (const [key, value] of Object.entries(task.config.image?.config.env ?? {})) {
369
+ if (isSecretRef(value))
370
+ names.add(key);
371
+ }
372
+ return names;
373
+ }
374
+ hashParams(params) {
375
+ const values = {};
376
+ for (const name of params) {
377
+ if (Object.prototype.hasOwnProperty.call(this.params, name)) {
378
+ values[name] = JSON.stringify(this.params[name]);
379
+ }
380
+ else {
381
+ values[name] = '__unset__';
382
+ }
383
+ }
384
+ return hashNamedValues(values);
385
+ }
386
+ hashEnvConfig(task) {
387
+ const normalize = (value) => {
388
+ if (typeof value === 'string' || typeof value === 'number')
389
+ return value;
390
+ if (isSecretRef(value))
391
+ return { kind: 'secret', name: value.name };
392
+ if (isParamRef(value))
393
+ return { kind: 'param', name: value.name };
394
+ if (isValueRef(value))
395
+ return { kind: 'value', name: value.name };
396
+ return String(value);
397
+ };
398
+ const taskEnv = {};
399
+ for (const [name, value] of Object.entries(task.config.env)) {
400
+ taskEnv[name] = normalize(value);
401
+ }
402
+ const imageEnv = {};
403
+ for (const [name, value] of Object.entries(task.config.image?.config.env ?? {})) {
404
+ imageEnv[name] = normalize(value);
405
+ }
406
+ return hashObject({ taskEnv, imageEnv });
407
+ }
408
+ async hashDependencies(task, discovered) {
409
+ const names = this.collectDependencyNames(task, discovered);
410
+ const fingerprints = {};
411
+ for (const name of names) {
412
+ fingerprints[name] = await this.resolveDependencyFingerprint(name);
413
+ }
414
+ return hashObject(fingerprints);
415
+ }
416
+ collectDependencyNames(task, discovered) {
417
+ const names = new Set(task.config.needs);
418
+ for (const name of discovered)
419
+ names.add(name);
420
+ return Array.from(names);
421
+ }
422
+ async resolveDependencyFingerprint(name) {
423
+ let state = this.getTaskState(name);
424
+ if (!state || state.status === 'pending' || state.status === 'running') {
425
+ const depTask = this.findTask(name);
426
+ if (depTask) {
427
+ await this.executeTask(depTask);
428
+ }
429
+ state = this.getTaskState(name);
430
+ }
431
+ if (!state)
432
+ return 'missing';
433
+ if (state.status === 'failed')
434
+ return 'failed';
435
+ const cacheState = this.taskCacheState.get(name);
436
+ if (cacheState?.key)
437
+ return cacheState.key;
438
+ if (!cacheState?.fingerprint) {
439
+ const fingerprint = this.computeStateFingerprint(state);
440
+ this.recordTaskCacheState(name, { fingerprint });
441
+ }
442
+ return this.taskCacheState.get(name)?.fingerprint ?? 'missing';
443
+ }
444
+ computeStateFingerprint(state) {
445
+ const outputs = {};
446
+ for (const [key, value] of state.outputs.entries()) {
447
+ outputs[key] = value;
448
+ }
449
+ const bundleHashes = {};
450
+ for (const [name, bundle] of state.bundles.entries()) {
451
+ const fileHashes = {};
452
+ for (const [path, content] of Object.entries(bundle.files)) {
453
+ fileHashes[path] = hashString(Buffer.from(content).toString('base64'));
454
+ }
455
+ bundleHashes[name] = hashObject(fileHashes);
456
+ }
457
+ return hashObject({ outputs, bundles: bundleHashes });
458
+ }
459
+ cacheVersion() {
460
+ const [major] = VERSION.split('.');
461
+ return major ?? VERSION;
462
+ }
463
+ resolveTtl(value) {
464
+ if (!value)
465
+ return this.settings.ttlMs ?? null;
466
+ const parsed = this.parseDuration(value);
467
+ return parsed ?? this.settings.ttlMs ?? null;
468
+ }
469
+ parseDuration(value) {
470
+ const match = value.trim().match(/^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/);
471
+ if (!match)
472
+ return null;
473
+ const amount = Number(match[1]);
474
+ if (!Number.isFinite(amount))
475
+ return null;
476
+ const multipliers = {
477
+ ms: 1,
478
+ s: 1000,
479
+ m: 60_000,
480
+ h: 3_600_000,
481
+ d: 86_400_000,
482
+ };
483
+ const unit = match[2];
484
+ if (!unit)
485
+ return null;
486
+ return amount * (multipliers[unit] ?? 1);
487
+ }
488
+ async executeCacheOp(op, task, context, _state, recordPending = true) {
489
+ if (!this.cacheAllowedForTask(task)) {
490
+ if (this.settings.cacheOnly) {
491
+ throw OpErrors.cache(`Cache disabled for task "${task.config.name}"`)
492
+ .inTask(context.task)
493
+ .inStep(context.step)
494
+ .build();
495
+ }
496
+ return false;
497
+ }
498
+ const decision = await this.computeCacheOpDecision(op, context, task);
499
+ const entry = await this.cacheStore?.readOp(decision.key, this.settings.ttlMs ?? null);
500
+ if (entry) {
501
+ if (Object.keys(entry.files).length > 0) {
502
+ await writeFiles(context.workspace, entry.files);
503
+ }
504
+ this.reporter?.emit('cache_hit', { cache: op.name, scope: 'op' });
505
+ return true;
506
+ }
507
+ this.reporter?.emit('cache_miss', { cache: op.name, scope: 'op' });
508
+ if (this.settings.cacheOnly) {
509
+ throw OpErrors.cache(`Cache miss for "${op.name}"`)
510
+ .inTask(context.task)
511
+ .inStep(context.step)
512
+ .build();
513
+ }
514
+ if (recordPending) {
515
+ this.enqueuePendingSave(task.config.name, {
516
+ key: decision.key,
517
+ name: op.name,
518
+ paths: op.paths,
519
+ });
520
+ }
521
+ return false;
522
+ }
523
+ async executeCacheOrOp(op, task, context, state, executeOp) {
524
+ if (!this.cacheAllowedForTask(task)) {
525
+ if (this.settings.cacheOnly) {
526
+ throw OpErrors.cache(`Cache disabled for task "${task.config.name}"`)
527
+ .inTask(context.task)
528
+ .inStep(context.step)
529
+ .build();
530
+ }
531
+ await this.executeInline(op.compute, task, context, state, executeOp);
532
+ return false;
533
+ }
534
+ const cacheHit = await this.executeCacheOp(op, task, context, state, false);
535
+ if (cacheHit)
536
+ return true;
537
+ if (this.settings.cacheOnly) {
538
+ throw OpErrors.cache(`Cache miss for "${op.name}"`)
539
+ .inTask(context.task)
540
+ .inStep(context.step)
541
+ .build();
542
+ }
543
+ await this.executeInline(op.compute, task, context, state, executeOp);
544
+ await this.saveCacheOpSnapshot(op, context, task);
545
+ return false;
546
+ }
547
+ async executeCachedCommand(op, task, context, _state, executeBaseOp) {
548
+ if (!this.cacheAllowedForTask(task)) {
549
+ if (this.settings.cacheOnly) {
550
+ throw OpErrors.cache(`Cache disabled for task "${task.config.name}"`)
551
+ .inTask(context.task)
552
+ .inStep(context.step)
553
+ .build();
554
+ }
555
+ return executeBaseOp(op);
556
+ }
557
+ const decision = await this.computeCommandCacheDecision(op, context, task);
558
+ if (!decision) {
559
+ return executeBaseOp(op);
560
+ }
561
+ const entry = await this.cacheStore?.readOp(decision.key, this.settings.ttlMs ?? null);
562
+ if (entry) {
563
+ if (Object.keys(entry.files).length > 0) {
564
+ await writeFiles(context.workspace, entry.files);
565
+ }
566
+ this.reporter?.emit('cache_hit', { cache: decision.name, scope: 'command' });
567
+ return entry.result;
568
+ }
569
+ this.reporter?.emit('cache_miss', { cache: decision.name, scope: 'command' });
570
+ if (this.settings.cacheOnly) {
571
+ throw OpErrors.cache(`Cache miss for command "${decision.name}"`)
572
+ .inTask(context.task)
573
+ .inStep(context.step)
574
+ .build();
575
+ }
576
+ const result = await executeBaseOp(op);
577
+ if (this.shouldCacheCommandResult(op, result)) {
578
+ const files = await collectFiles(context.workspace, decision.outputs);
579
+ await this.cacheStore?.saveOp(decision.key, {
580
+ meta: {
581
+ key: decision.key,
582
+ createdAt: new Date().toISOString(),
583
+ kind: 'command',
584
+ command: decision.command,
585
+ inputs: decision.inputs,
586
+ outputs: decision.outputs,
587
+ },
588
+ result,
589
+ files,
590
+ });
591
+ }
592
+ return result;
593
+ }
594
+ async executeInline(compute, task, context, state, executeOp) {
595
+ const iterator = compute({ task, workspace: this.workspace });
596
+ const inlineStep = new StepBuilder(context.step, () => iterator, []);
597
+ let cursor = iterator.next();
598
+ while (!cursor.done) {
599
+ const op = this.toOp(cursor.value);
600
+ const result = await executeOp(op, task, inlineStep, context.env, state);
601
+ cursor = iterator.next(result);
602
+ }
603
+ }
604
+ toOp(value) {
605
+ if (value instanceof CommandBuilder) {
606
+ return value.op;
607
+ }
608
+ if (value && typeof value === 'object' && 'op' in value) {
609
+ const maybeOp = value.op;
610
+ if (maybeOp && typeof maybeOp === 'object' && 'kind' in maybeOp) {
611
+ return maybeOp;
612
+ }
613
+ }
614
+ return value;
615
+ }
616
+ async computeCacheOpDecision(op, context, task) {
617
+ if (op.paths.length === 0) {
618
+ throw OpErrors.cache(`Cache "${op.name}" has no paths`)
619
+ .inTask(context.task)
620
+ .inStep(context.step)
621
+ .build();
622
+ }
623
+ const fileHash = op.key?.files
624
+ ? await hashFiles(this.workspace, op.key.files, this.cacheExcludes())
625
+ : { hash: hashString(''), files: {} };
626
+ const secretEnv = this.collectSecretEnvNames(task);
627
+ const envValues = {};
628
+ for (const name of op.key?.env ?? []) {
629
+ envValues[name] = secretEnv.has(name) ? '__secret__' : (context.env[name] ?? '__unset__');
630
+ }
631
+ const envHash = hashNamedValues(envValues);
632
+ const keyComponents = {
633
+ name: op.name,
634
+ paths: op.paths,
635
+ files: fileHash.hash,
636
+ filePatternsHash: hashString((op.key?.files ?? []).join('\n')),
637
+ env: envHash,
638
+ value: op.key?.value ?? '',
639
+ bust: this.settings.bust ?? '',
640
+ version: this.cacheVersion(),
641
+ };
642
+ return { key: hashObject(keyComponents) };
643
+ }
644
+ async saveCacheOpSnapshot(op, context, task) {
645
+ const decision = await this.computeCacheOpDecision(op, context, task);
646
+ const files = await collectFiles(this.workspace, op.paths);
647
+ await this.cacheStore?.saveOp(decision.key, {
648
+ meta: {
649
+ key: decision.key,
650
+ createdAt: new Date().toISOString(),
651
+ kind: 'cache',
652
+ outputs: op.paths,
653
+ },
654
+ files,
655
+ });
656
+ }
657
+ async computeCommandCacheDecision(op, context, task) {
658
+ const cacheOptions = op.cache;
659
+ if (!cacheOptions)
660
+ return null;
661
+ const { template, signature } = this.normalizeCommandTemplate(op.template);
662
+ const resolvedOutputs = this.resolveCommandOutputs(cacheOptions, signature);
663
+ if (resolvedOutputs.length === 0)
664
+ return null;
665
+ const uniqueInputs = this.resolveCommandInputs(cacheOptions, signature);
666
+ if (uniqueInputs.length === 0)
667
+ return null;
668
+ const inputs = await hashFiles(this.workspace, uniqueInputs, this.cacheExcludes());
669
+ const envHash = this.hashCommandEnv(cacheOptions, context.env, task);
670
+ const outputsHash = hashString(resolvedOutputs.join('\n'));
671
+ const keyComponents = {
672
+ task: context.task,
673
+ step: context.step,
674
+ capture: op.capture,
675
+ command: template,
676
+ inputs: inputs.hash,
677
+ inputPatternsHash: hashString(uniqueInputs.join('\n')),
678
+ outputsHash,
679
+ env: envHash,
680
+ value: cacheOptions.key?.value ?? '',
681
+ bust: this.settings.bust ?? '',
682
+ version: this.cacheVersion(),
683
+ };
684
+ return {
685
+ key: hashObject(keyComponents),
686
+ name: signature || `${context.task}:${context.step}`,
687
+ outputs: resolvedOutputs,
688
+ command: { capture: op.capture, template },
689
+ inputs: { patterns: uniqueInputs, files: inputs.files },
690
+ };
691
+ }
692
+ normalizeCommandTemplate(template) {
693
+ const normalized = template.map((part) => ({
694
+ type: part.type,
695
+ ...(part.type === 'text' || part.type === 'interpolated'
696
+ ? { value: part.value }
697
+ : part.type === 'secret'
698
+ ? { name: part.name }
699
+ : { name: part.ref.name }),
700
+ }));
701
+ const signature = template
702
+ .map((part) => {
703
+ if (part.type === 'text')
704
+ return part.value;
705
+ if (part.type === 'interpolated')
706
+ return String(part.value);
707
+ if (part.type === 'secret')
708
+ return `<secret:${part.name}>`;
709
+ if (part.type === 'param')
710
+ return `<param:${part.ref.name}>`;
711
+ return `<value:${part.ref.name}>`;
712
+ })
713
+ .join('')
714
+ .replace(/\s+/g, ' ')
715
+ .trim();
716
+ return { template: normalized, signature };
717
+ }
718
+ resolveCommandOutputs(cacheOptions, signature) {
719
+ if (cacheOptions.outputs && cacheOptions.outputs.length > 0) {
720
+ return cacheOptions.outputs;
721
+ }
722
+ return inferOutputsFromCommand(signature);
723
+ }
724
+ resolveCommandInputs(cacheOptions, signature) {
725
+ const inputPatterns = [...(cacheOptions.inputs ?? []), ...(cacheOptions.key?.files ?? [])];
726
+ const resolvedInputs = inputPatterns.length > 0 ? inputPatterns : inferInputsFromCommand(signature);
727
+ return Array.from(new Set(resolvedInputs));
728
+ }
729
+ hashCommandEnv(cacheOptions, env, task) {
730
+ const envValues = {};
731
+ const envNames = new Set(cacheOptions.env ?? []);
732
+ for (const name of cacheOptions.key?.env ?? [])
733
+ envNames.add(name);
734
+ const secretEnv = this.collectSecretEnvNames(task);
735
+ for (const name of envNames) {
736
+ envValues[name] = secretEnv.has(name) ? '__secret__' : (env[name] ?? '__unset__');
737
+ }
738
+ return hashNamedValues(envValues);
739
+ }
740
+ shouldCacheCommandResult(op, result) {
741
+ if (op.capture === 'ok')
742
+ return result === true;
743
+ if (op.capture === 'code')
744
+ return result === 0;
745
+ if (op.capture === 'result') {
746
+ return Boolean(result && typeof result === 'object' && result.ok);
747
+ }
748
+ return true;
749
+ }
750
+ async emitCacheDebug(taskName, decision, status) {
751
+ const meta = await this.cacheStore?.latestTaskMeta(taskName);
752
+ const changes = this.diffInputFiles(decision.inputs.files, meta?.inputs.files ?? {});
753
+ const lines = [
754
+ `Task: ${taskName}`,
755
+ ` Cache key: sha256:${decision.key}`,
756
+ ' Components:',
757
+ ...Object.entries(decision.components).map(([key, value]) => ` ${key}: sha256:${value}`),
758
+ ` Status: ${status}${decision.reason ? ` (${decision.reason})` : ''}`,
759
+ ];
760
+ if (changes.length > 0) {
761
+ lines.push(' Changed files:');
762
+ for (const change of changes) {
763
+ lines.push(` - ${change}`);
764
+ }
765
+ }
766
+ if (this.reporter) {
767
+ this.reporter.emit('cache_debug', { task: taskName, lines });
768
+ }
769
+ else {
770
+ for (const line of lines) {
771
+ this.logger.info(this.resolver.redactSecrets(line));
772
+ }
773
+ }
774
+ }
775
+ diffInputFiles(current, previous) {
776
+ const changes = [];
777
+ const currentKeys = new Set(Object.keys(current));
778
+ const previousKeys = new Set(Object.keys(previous));
779
+ for (const key of currentKeys) {
780
+ if (!previousKeys.has(key)) {
781
+ changes.push(`${key} (added)`);
782
+ }
783
+ else if (current[key] !== previous[key]) {
784
+ changes.push(`${key} (modified)`);
785
+ }
786
+ }
787
+ for (const key of previousKeys) {
788
+ if (!currentKeys.has(key)) {
789
+ changes.push(`${key} (removed)`);
790
+ }
791
+ }
792
+ return changes;
793
+ }
794
+ enqueuePendingSave(taskName, entry) {
795
+ const existing = this.pendingOpSaves.get(taskName) ?? [];
796
+ existing.push(entry);
797
+ this.pendingOpSaves.set(taskName, existing);
798
+ }
799
+ }
800
+ //# sourceMappingURL=coordinator.js.map