@shrkcrft/cli 0.1.0-alpha.2

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 (450) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +15 -0
  3. package/dist/asset-preview/apply-action-hint-stub.d.ts +28 -0
  4. package/dist/asset-preview/apply-action-hint-stub.d.ts.map +1 -0
  5. package/dist/asset-preview/apply-action-hint-stub.js +170 -0
  6. package/dist/asset-preview/apply-asset-preview.d.ts +31 -0
  7. package/dist/asset-preview/apply-asset-preview.d.ts.map +1 -0
  8. package/dist/asset-preview/apply-asset-preview.js +210 -0
  9. package/dist/asset-preview/apply-knowledge-stale-fix.d.ts +37 -0
  10. package/dist/asset-preview/apply-knowledge-stale-fix.d.ts.map +1 -0
  11. package/dist/asset-preview/apply-knowledge-stale-fix.js +344 -0
  12. package/dist/asset-preview/apply-missing-barrel.d.ts +15 -0
  13. package/dist/asset-preview/apply-missing-barrel.d.ts.map +1 -0
  14. package/dist/asset-preview/apply-missing-barrel.js +65 -0
  15. package/dist/asset-preview/apply-template-drift-fix.d.ts +21 -0
  16. package/dist/asset-preview/apply-template-drift-fix.d.ts.map +1 -0
  17. package/dist/asset-preview/apply-template-drift-fix.js +125 -0
  18. package/dist/asset-preview/apply-template-update.d.ts +43 -0
  19. package/dist/asset-preview/apply-template-update.d.ts.map +1 -0
  20. package/dist/asset-preview/apply-template-update.js +257 -0
  21. package/dist/asset-preview/entry-mutator.d.ts +106 -0
  22. package/dist/asset-preview/entry-mutator.d.ts.map +1 -0
  23. package/dist/asset-preview/entry-mutator.js +428 -0
  24. package/dist/authoring/authoring-kit.d.ts +36 -0
  25. package/dist/authoring/authoring-kit.d.ts.map +1 -0
  26. package/dist/authoring/authoring-kit.js +106 -0
  27. package/dist/command-registry.d.ts +158 -0
  28. package/dist/command-registry.d.ts.map +1 -0
  29. package/dist/command-registry.js +348 -0
  30. package/dist/commands/apply.command.d.ts +3 -0
  31. package/dist/commands/apply.command.d.ts.map +1 -0
  32. package/dist/commands/apply.command.js +879 -0
  33. package/dist/commands/architecture.command.d.ts +5 -0
  34. package/dist/commands/architecture.command.d.ts.map +1 -0
  35. package/dist/commands/architecture.command.js +141 -0
  36. package/dist/commands/ask.command.d.ts +3 -0
  37. package/dist/commands/ask.command.d.ts.map +1 -0
  38. package/dist/commands/ask.command.js +58 -0
  39. package/dist/commands/audit.command.d.ts +3 -0
  40. package/dist/commands/audit.command.d.ts.map +1 -0
  41. package/dist/commands/audit.command.js +141 -0
  42. package/dist/commands/biome.command.d.ts +7 -0
  43. package/dist/commands/biome.command.d.ts.map +1 -0
  44. package/dist/commands/biome.command.js +350 -0
  45. package/dist/commands/boundaries.command.d.ts +9 -0
  46. package/dist/commands/boundaries.command.d.ts.map +1 -0
  47. package/dist/commands/boundaries.command.js +314 -0
  48. package/dist/commands/brief.command.d.ts +3 -0
  49. package/dist/commands/brief.command.d.ts.map +1 -0
  50. package/dist/commands/brief.command.js +206 -0
  51. package/dist/commands/bundle.command.d.ts +3 -0
  52. package/dist/commands/bundle.command.d.ts.map +1 -0
  53. package/dist/commands/bundle.command.js +1183 -0
  54. package/dist/commands/changes.command.d.ts +3 -0
  55. package/dist/commands/changes.command.d.ts.map +1 -0
  56. package/dist/commands/changes.command.js +155 -0
  57. package/dist/commands/check.command.d.ts +3 -0
  58. package/dist/commands/check.command.d.ts.map +1 -0
  59. package/dist/commands/check.command.js +553 -0
  60. package/dist/commands/checks.command.d.ts +29 -0
  61. package/dist/commands/checks.command.d.ts.map +1 -0
  62. package/dist/commands/checks.command.js +521 -0
  63. package/dist/commands/ci.command.d.ts +3 -0
  64. package/dist/commands/ci.command.d.ts.map +1 -0
  65. package/dist/commands/ci.command.js +680 -0
  66. package/dist/commands/codemod.command.d.ts +3 -0
  67. package/dist/commands/codemod.command.d.ts.map +1 -0
  68. package/dist/commands/codemod.command.js +130 -0
  69. package/dist/commands/command-catalog.d.ts +265 -0
  70. package/dist/commands/command-catalog.d.ts.map +1 -0
  71. package/dist/commands/command-catalog.js +3242 -0
  72. package/dist/commands/commands.command.d.ts +92 -0
  73. package/dist/commands/commands.command.d.ts.map +1 -0
  74. package/dist/commands/commands.command.js +1208 -0
  75. package/dist/commands/constructs.command.d.ts +15 -0
  76. package/dist/commands/constructs.command.d.ts.map +1 -0
  77. package/dist/commands/constructs.command.js +669 -0
  78. package/dist/commands/context.command.d.ts +3 -0
  79. package/dist/commands/context.command.d.ts.map +1 -0
  80. package/dist/commands/context.command.js +120 -0
  81. package/dist/commands/contract-gate.command.d.ts +5 -0
  82. package/dist/commands/contract-gate.command.d.ts.map +1 -0
  83. package/dist/commands/contract-gate.command.js +208 -0
  84. package/dist/commands/contract-templates.command.d.ts +8 -0
  85. package/dist/commands/contract-templates.command.d.ts.map +1 -0
  86. package/dist/commands/contract-templates.command.js +151 -0
  87. package/dist/commands/contract.command.d.ts +3 -0
  88. package/dist/commands/contract.command.d.ts.map +1 -0
  89. package/dist/commands/contract.command.js +105 -0
  90. package/dist/commands/conventions.command.d.ts +8 -0
  91. package/dist/commands/conventions.command.d.ts.map +1 -0
  92. package/dist/commands/conventions.command.js +169 -0
  93. package/dist/commands/coverage.command.d.ts +3 -0
  94. package/dist/commands/coverage.command.d.ts.map +1 -0
  95. package/dist/commands/coverage.command.js +56 -0
  96. package/dist/commands/daily.commands.d.ts +5 -0
  97. package/dist/commands/daily.commands.d.ts.map +1 -0
  98. package/dist/commands/daily.commands.js +224 -0
  99. package/dist/commands/dashboard-export.command.d.ts +4 -0
  100. package/dist/commands/dashboard-export.command.d.ts.map +1 -0
  101. package/dist/commands/dashboard-export.command.js +86 -0
  102. package/dist/commands/dashboard.command.d.ts +3 -0
  103. package/dist/commands/dashboard.command.d.ts.map +1 -0
  104. package/dist/commands/dashboard.command.js +106 -0
  105. package/dist/commands/dev.command.d.ts +3 -0
  106. package/dist/commands/dev.command.d.ts.map +1 -0
  107. package/dist/commands/dev.command.js +1392 -0
  108. package/dist/commands/diagnostics.command.d.ts +5 -0
  109. package/dist/commands/diagnostics.command.d.ts.map +1 -0
  110. package/dist/commands/diagnostics.command.js +97 -0
  111. package/dist/commands/docs.command.d.ts +4 -0
  112. package/dist/commands/docs.command.d.ts.map +1 -0
  113. package/dist/commands/docs.command.js +34 -0
  114. package/dist/commands/doctor.command.d.ts +7 -0
  115. package/dist/commands/doctor.command.d.ts.map +1 -0
  116. package/dist/commands/doctor.command.js +681 -0
  117. package/dist/commands/drift.command.d.ts +3 -0
  118. package/dist/commands/drift.command.d.ts.map +1 -0
  119. package/dist/commands/drift.command.js +124 -0
  120. package/dist/commands/eslint.command.d.ts +7 -0
  121. package/dist/commands/eslint.command.d.ts.map +1 -0
  122. package/dist/commands/eslint.command.js +423 -0
  123. package/dist/commands/explore.command.d.ts +3 -0
  124. package/dist/commands/explore.command.d.ts.map +1 -0
  125. package/dist/commands/explore.command.js +65 -0
  126. package/dist/commands/export-bundle.command.d.ts +6 -0
  127. package/dist/commands/export-bundle.command.d.ts.map +1 -0
  128. package/dist/commands/export-bundle.command.js +96 -0
  129. package/dist/commands/export.command.d.ts +3 -0
  130. package/dist/commands/export.command.d.ts.map +1 -0
  131. package/dist/commands/export.command.js +83 -0
  132. package/dist/commands/feedback-dispatch.command.d.ts +12 -0
  133. package/dist/commands/feedback-dispatch.command.d.ts.map +1 -0
  134. package/dist/commands/feedback-dispatch.command.js +63 -0
  135. package/dist/commands/feedback.command.d.ts +11 -0
  136. package/dist/commands/feedback.command.d.ts.map +1 -0
  137. package/dist/commands/feedback.command.js +336 -0
  138. package/dist/commands/fix.command.d.ts +3 -0
  139. package/dist/commands/fix.command.d.ts.map +1 -0
  140. package/dist/commands/fix.command.js +776 -0
  141. package/dist/commands/gen.command.d.ts +3 -0
  142. package/dist/commands/gen.command.d.ts.map +1 -0
  143. package/dist/commands/gen.command.js +136 -0
  144. package/dist/commands/git.command.d.ts +6 -0
  145. package/dist/commands/git.command.d.ts.map +1 -0
  146. package/dist/commands/git.command.js +81 -0
  147. package/dist/commands/graph.command.d.ts +3 -0
  148. package/dist/commands/graph.command.d.ts.map +1 -0
  149. package/dist/commands/graph.command.js +287 -0
  150. package/dist/commands/grounding.command.d.ts +7 -0
  151. package/dist/commands/grounding.command.d.ts.map +1 -0
  152. package/dist/commands/grounding.command.js +54 -0
  153. package/dist/commands/help.command.d.ts +20 -0
  154. package/dist/commands/help.command.d.ts.map +1 -0
  155. package/dist/commands/help.command.js +127 -0
  156. package/dist/commands/helper.command.d.ts +6 -0
  157. package/dist/commands/helper.command.d.ts.map +1 -0
  158. package/dist/commands/helper.command.js +170 -0
  159. package/dist/commands/ide.command.d.ts +6 -0
  160. package/dist/commands/ide.command.d.ts.map +1 -0
  161. package/dist/commands/ide.command.js +340 -0
  162. package/dist/commands/impact.command.d.ts +3 -0
  163. package/dist/commands/impact.command.d.ts.map +1 -0
  164. package/dist/commands/impact.command.js +819 -0
  165. package/dist/commands/import.command.d.ts +3 -0
  166. package/dist/commands/import.command.d.ts.map +1 -0
  167. package/dist/commands/import.command.js +115 -0
  168. package/dist/commands/infer.command.d.ts +3 -0
  169. package/dist/commands/infer.command.d.ts.map +1 -0
  170. package/dist/commands/infer.command.js +227 -0
  171. package/dist/commands/ingest.command.d.ts +6 -0
  172. package/dist/commands/ingest.command.d.ts.map +1 -0
  173. package/dist/commands/ingest.command.js +532 -0
  174. package/dist/commands/init.command.d.ts +3 -0
  175. package/dist/commands/init.command.d.ts.map +1 -0
  176. package/dist/commands/init.command.js +301 -0
  177. package/dist/commands/inspect.command.d.ts +3 -0
  178. package/dist/commands/inspect.command.d.ts.map +1 -0
  179. package/dist/commands/inspect.command.js +122 -0
  180. package/dist/commands/knowledge-author.command.d.ts +22 -0
  181. package/dist/commands/knowledge-author.command.d.ts.map +1 -0
  182. package/dist/commands/knowledge-author.command.js +366 -0
  183. package/dist/commands/knowledge-propose.command.d.ts +3 -0
  184. package/dist/commands/knowledge-propose.command.d.ts.map +1 -0
  185. package/dist/commands/knowledge-propose.command.js +125 -0
  186. package/dist/commands/knowledge.command.d.ts +18 -0
  187. package/dist/commands/knowledge.command.d.ts.map +1 -0
  188. package/dist/commands/knowledge.command.js +538 -0
  189. package/dist/commands/languages.command.d.ts +3 -0
  190. package/dist/commands/languages.command.d.ts.map +1 -0
  191. package/dist/commands/languages.command.js +300 -0
  192. package/dist/commands/lint.command.d.ts +15 -0
  193. package/dist/commands/lint.command.d.ts.map +1 -0
  194. package/dist/commands/lint.command.js +194 -0
  195. package/dist/commands/mcp.command.d.ts +3 -0
  196. package/dist/commands/mcp.command.d.ts.map +1 -0
  197. package/dist/commands/mcp.command.js +74 -0
  198. package/dist/commands/memory.command.d.ts +11 -0
  199. package/dist/commands/memory.command.d.ts.map +1 -0
  200. package/dist/commands/memory.command.js +264 -0
  201. package/dist/commands/onboard.command.d.ts +3 -0
  202. package/dist/commands/onboard.command.d.ts.map +1 -0
  203. package/dist/commands/onboard.command.js +650 -0
  204. package/dist/commands/orchestrate.command.d.ts +3 -0
  205. package/dist/commands/orchestrate.command.d.ts.map +1 -0
  206. package/dist/commands/orchestrate.command.js +49 -0
  207. package/dist/commands/owners.command.d.ts +5 -0
  208. package/dist/commands/owners.command.d.ts.map +1 -0
  209. package/dist/commands/owners.command.js +113 -0
  210. package/dist/commands/ownership.command.d.ts +5 -0
  211. package/dist/commands/ownership.command.d.ts.map +1 -0
  212. package/dist/commands/ownership.command.js +117 -0
  213. package/dist/commands/pack-author.command.d.ts +30 -0
  214. package/dist/commands/pack-author.command.d.ts.map +1 -0
  215. package/dist/commands/pack-author.command.js +242 -0
  216. package/dist/commands/packs-new.d.ts +27 -0
  217. package/dist/commands/packs-new.d.ts.map +1 -0
  218. package/dist/commands/packs-new.js +805 -0
  219. package/dist/commands/packs.command.d.ts +15 -0
  220. package/dist/commands/packs.command.d.ts.map +1 -0
  221. package/dist/commands/packs.command.js +958 -0
  222. package/dist/commands/paths.command.d.ts +6 -0
  223. package/dist/commands/paths.command.d.ts.map +1 -0
  224. package/dist/commands/paths.command.js +97 -0
  225. package/dist/commands/pipelines.command.d.ts +9 -0
  226. package/dist/commands/pipelines.command.d.ts.map +1 -0
  227. package/dist/commands/pipelines.command.js +308 -0
  228. package/dist/commands/plan-check.command.d.ts +27 -0
  229. package/dist/commands/plan-check.command.d.ts.map +1 -0
  230. package/dist/commands/plan-check.command.js +150 -0
  231. package/dist/commands/plan-simulate.command.d.ts +3 -0
  232. package/dist/commands/plan-simulate.command.d.ts.map +1 -0
  233. package/dist/commands/plan-simulate.command.js +60 -0
  234. package/dist/commands/plan.command.d.ts +8 -0
  235. package/dist/commands/plan.command.d.ts.map +1 -0
  236. package/dist/commands/plan.command.js +139 -0
  237. package/dist/commands/playbooks.command.d.ts +10 -0
  238. package/dist/commands/playbooks.command.d.ts.map +1 -0
  239. package/dist/commands/playbooks.command.js +296 -0
  240. package/dist/commands/plugin.command.d.ts +11 -0
  241. package/dist/commands/plugin.command.d.ts.map +1 -0
  242. package/dist/commands/plugin.command.js +394 -0
  243. package/dist/commands/policy.command.d.ts +8 -0
  244. package/dist/commands/policy.command.d.ts.map +1 -0
  245. package/dist/commands/policy.command.js +451 -0
  246. package/dist/commands/pr.command.d.ts +3 -0
  247. package/dist/commands/pr.command.d.ts.map +1 -0
  248. package/dist/commands/pr.command.js +132 -0
  249. package/dist/commands/preflight.command.d.ts +3 -0
  250. package/dist/commands/preflight.command.d.ts.map +1 -0
  251. package/dist/commands/preflight.command.js +102 -0
  252. package/dist/commands/presets.command.d.ts +17 -0
  253. package/dist/commands/presets.command.d.ts.map +1 -0
  254. package/dist/commands/presets.command.js +647 -0
  255. package/dist/commands/profiles.command.d.ts +7 -0
  256. package/dist/commands/profiles.command.d.ts.map +1 -0
  257. package/dist/commands/profiles.command.js +151 -0
  258. package/dist/commands/provenance.command.d.ts +26 -0
  259. package/dist/commands/provenance.command.d.ts.map +1 -0
  260. package/dist/commands/provenance.command.js +237 -0
  261. package/dist/commands/quality.command.d.ts +5 -0
  262. package/dist/commands/quality.command.d.ts.map +1 -0
  263. package/dist/commands/quality.command.js +69 -0
  264. package/dist/commands/recommend.command.d.ts +4 -0
  265. package/dist/commands/recommend.command.d.ts.map +1 -0
  266. package/dist/commands/recommend.command.js +270 -0
  267. package/dist/commands/registrations.command.d.ts +3 -0
  268. package/dist/commands/registrations.command.d.ts.map +1 -0
  269. package/dist/commands/registrations.command.js +300 -0
  270. package/dist/commands/registry.command.d.ts +4 -0
  271. package/dist/commands/registry.command.d.ts.map +1 -0
  272. package/dist/commands/registry.command.js +37 -0
  273. package/dist/commands/release.command.d.ts +4 -0
  274. package/dist/commands/release.command.d.ts.map +1 -0
  275. package/dist/commands/release.command.js +639 -0
  276. package/dist/commands/repo.command.d.ts +3 -0
  277. package/dist/commands/repo.command.d.ts.map +1 -0
  278. package/dist/commands/repo.command.js +24 -0
  279. package/dist/commands/report.command.d.ts +3 -0
  280. package/dist/commands/report.command.d.ts.map +1 -0
  281. package/dist/commands/report.command.js +511 -0
  282. package/dist/commands/reposet.command.d.ts +6 -0
  283. package/dist/commands/reposet.command.d.ts.map +1 -0
  284. package/dist/commands/reposet.command.js +120 -0
  285. package/dist/commands/review.command.d.ts +3 -0
  286. package/dist/commands/review.command.d.ts.map +1 -0
  287. package/dist/commands/review.command.js +354 -0
  288. package/dist/commands/risk.command.d.ts +3 -0
  289. package/dist/commands/risk.command.d.ts.map +1 -0
  290. package/dist/commands/risk.command.js +56 -0
  291. package/dist/commands/rounds.command.d.ts +8 -0
  292. package/dist/commands/rounds.command.d.ts.map +1 -0
  293. package/dist/commands/rounds.command.js +180 -0
  294. package/dist/commands/rules.command.d.ts +49 -0
  295. package/dist/commands/rules.command.d.ts.map +1 -0
  296. package/dist/commands/rules.command.js +435 -0
  297. package/dist/commands/runtime.command.d.ts +3 -0
  298. package/dist/commands/runtime.command.d.ts.map +1 -0
  299. package/dist/commands/runtime.command.js +56 -0
  300. package/dist/commands/safety.command.d.ts +3 -0
  301. package/dist/commands/safety.command.d.ts.map +1 -0
  302. package/dist/commands/safety.command.js +117 -0
  303. package/dist/commands/scaffolds.command.d.ts +5 -0
  304. package/dist/commands/scaffolds.command.d.ts.map +1 -0
  305. package/dist/commands/scaffolds.command.js +122 -0
  306. package/dist/commands/schemas.command.d.ts +21 -0
  307. package/dist/commands/schemas.command.d.ts.map +1 -0
  308. package/dist/commands/schemas.command.js +296 -0
  309. package/dist/commands/search.command.d.ts +12 -0
  310. package/dist/commands/search.command.d.ts.map +1 -0
  311. package/dist/commands/search.command.js +275 -0
  312. package/dist/commands/self-config.command.d.ts +7 -0
  313. package/dist/commands/self-config.command.d.ts.map +1 -0
  314. package/dist/commands/self-config.command.js +156 -0
  315. package/dist/commands/self.command.d.ts +3 -0
  316. package/dist/commands/self.command.d.ts.map +1 -0
  317. package/dist/commands/self.command.js +117 -0
  318. package/dist/commands/simulate.command.d.ts +3 -0
  319. package/dist/commands/simulate.command.d.ts.map +1 -0
  320. package/dist/commands/simulate.command.js +54 -0
  321. package/dist/commands/spec.command.d.ts +29 -0
  322. package/dist/commands/spec.command.d.ts.map +1 -0
  323. package/dist/commands/spec.command.js +985 -0
  324. package/dist/commands/start-here.command.d.ts +3 -0
  325. package/dist/commands/start-here.command.d.ts.map +1 -0
  326. package/dist/commands/start-here.command.js +35 -0
  327. package/dist/commands/stats.command.d.ts +3 -0
  328. package/dist/commands/stats.command.d.ts.map +1 -0
  329. package/dist/commands/stats.command.js +88 -0
  330. package/dist/commands/surface.command.d.ts +15 -0
  331. package/dist/commands/surface.command.d.ts.map +1 -0
  332. package/dist/commands/surface.command.js +328 -0
  333. package/dist/commands/task-context.command.d.ts +7 -0
  334. package/dist/commands/task-context.command.d.ts.map +1 -0
  335. package/dist/commands/task-context.command.js +646 -0
  336. package/dist/commands/task.command.d.ts +3 -0
  337. package/dist/commands/task.command.d.ts.map +1 -0
  338. package/dist/commands/task.command.js +301 -0
  339. package/dist/commands/template-quality.command.d.ts +5 -0
  340. package/dist/commands/template-quality.command.d.ts.map +1 -0
  341. package/dist/commands/template-quality.command.js +128 -0
  342. package/dist/commands/templates.command.d.ts +26 -0
  343. package/dist/commands/templates.command.d.ts.map +1 -0
  344. package/dist/commands/templates.command.js +964 -0
  345. package/dist/commands/test.command.d.ts +3 -0
  346. package/dist/commands/test.command.d.ts.map +1 -0
  347. package/dist/commands/test.command.js +262 -0
  348. package/dist/commands/tests.command.d.ts +5 -0
  349. package/dist/commands/tests.command.d.ts.map +1 -0
  350. package/dist/commands/tests.command.js +97 -0
  351. package/dist/commands/trace.command.d.ts +3 -0
  352. package/dist/commands/trace.command.d.ts.map +1 -0
  353. package/dist/commands/trace.command.js +121 -0
  354. package/dist/commands/upgrade.command.d.ts +4 -0
  355. package/dist/commands/upgrade.command.d.ts.map +1 -0
  356. package/dist/commands/upgrade.command.js +43 -0
  357. package/dist/commands/version.command.d.ts +3 -0
  358. package/dist/commands/version.command.d.ts.map +1 -0
  359. package/dist/commands/version.command.js +10 -0
  360. package/dist/commands/why.command.d.ts +24 -0
  361. package/dist/commands/why.command.d.ts.map +1 -0
  362. package/dist/commands/why.command.js +119 -0
  363. package/dist/dashboard/dashboard-api-server.d.ts +21 -0
  364. package/dist/dashboard/dashboard-api-server.d.ts.map +1 -0
  365. package/dist/dashboard/dashboard-api-server.js +410 -0
  366. package/dist/dashboard/live-session-server.d.ts +18 -0
  367. package/dist/dashboard/live-session-server.d.ts.map +1 -0
  368. package/dist/dashboard/live-session-server.js +133 -0
  369. package/dist/diff/collect-changed-paths.d.ts +27 -0
  370. package/dist/diff/collect-changed-paths.d.ts.map +1 -0
  371. package/dist/diff/collect-changed-paths.js +68 -0
  372. package/dist/doctor/doctor-tags.d.ts +63 -0
  373. package/dist/doctor/doctor-tags.d.ts.map +1 -0
  374. package/dist/doctor/doctor-tags.js +146 -0
  375. package/dist/export/export-formats.d.ts +22 -0
  376. package/dist/export/export-formats.d.ts.map +1 -0
  377. package/dist/export/export-formats.js +135 -0
  378. package/dist/index.d.ts +22 -0
  379. package/dist/index.d.ts.map +1 -0
  380. package/dist/index.js +21 -0
  381. package/dist/init/detected-block.d.ts +57 -0
  382. package/dist/init/detected-block.d.ts.map +1 -0
  383. package/dist/init/detected-block.js +197 -0
  384. package/dist/init/gitignore.d.ts +30 -0
  385. package/dist/init/gitignore.d.ts.map +1 -0
  386. package/dist/init/gitignore.js +110 -0
  387. package/dist/init/init-templates.d.ts +6 -0
  388. package/dist/init/init-templates.d.ts.map +1 -0
  389. package/dist/init/init-templates.js +413 -0
  390. package/dist/main.d.ts +18 -0
  391. package/dist/main.d.ts.map +1 -0
  392. package/dist/main.js +699 -0
  393. package/dist/output/failure-hints.d.ts +55 -0
  394. package/dist/output/failure-hints.d.ts.map +1 -0
  395. package/dist/output/failure-hints.js +159 -0
  396. package/dist/output/format-output.d.ts +9 -0
  397. package/dist/output/format-output.d.ts.map +1 -0
  398. package/dist/output/format-output.js +26 -0
  399. package/dist/output/print-error.d.ts +3 -0
  400. package/dist/output/print-error.d.ts.map +1 -0
  401. package/dist/output/print-error.js +14 -0
  402. package/dist/output/watch-loop.d.ts +37 -0
  403. package/dist/output/watch-loop.d.ts.map +1 -0
  404. package/dist/output/watch-loop.js +115 -0
  405. package/dist/schemas/json-schemas.d.ts +1630 -0
  406. package/dist/schemas/json-schemas.d.ts.map +1 -0
  407. package/dist/schemas/json-schemas.js +811 -0
  408. package/dist/surface/about.d.ts +10 -0
  409. package/dist/surface/about.d.ts.map +1 -0
  410. package/dist/surface/about.js +53 -0
  411. package/dist/surface/load-surface-context.d.ts +34 -0
  412. package/dist/surface/load-surface-context.d.ts.map +1 -0
  413. package/dist/surface/load-surface-context.js +100 -0
  414. package/dist/surface/no-args-landing.d.ts +7 -0
  415. package/dist/surface/no-args-landing.d.ts.map +1 -0
  416. package/dist/surface/no-args-landing.js +36 -0
  417. package/dist/surface/not-enabled-error.d.ts +24 -0
  418. package/dist/surface/not-enabled-error.d.ts.map +1 -0
  419. package/dist/surface/not-enabled-error.js +36 -0
  420. package/dist/surface/profiles.d.ts +37 -0
  421. package/dist/surface/profiles.d.ts.map +1 -0
  422. package/dist/surface/profiles.js +151 -0
  423. package/dist/surface/shape-defaults.d.ts +21 -0
  424. package/dist/surface/shape-defaults.d.ts.map +1 -0
  425. package/dist/surface/shape-defaults.js +50 -0
  426. package/dist/surface/spine-extractor.d.ts +38 -0
  427. package/dist/surface/spine-extractor.d.ts.map +1 -0
  428. package/dist/surface/spine-extractor.js +100 -0
  429. package/dist/surface/surface-config-writer.d.ts +59 -0
  430. package/dist/surface/surface-config-writer.d.ts.map +1 -0
  431. package/dist/surface/surface-config-writer.js +135 -0
  432. package/dist/surface/surface-summary.d.ts +66 -0
  433. package/dist/surface/surface-summary.d.ts.map +1 -0
  434. package/dist/surface/surface-summary.js +162 -0
  435. package/dist/surface/tier.d.ts +100 -0
  436. package/dist/surface/tier.d.ts.map +1 -0
  437. package/dist/surface/tier.js +172 -0
  438. package/dist/task-next/apply-batch-runner.d.ts +42 -0
  439. package/dist/task-next/apply-batch-runner.d.ts.map +1 -0
  440. package/dist/task-next/apply-batch-runner.js +192 -0
  441. package/dist/task-next/task-next-ranker.d.ts +75 -0
  442. package/dist/task-next/task-next-ranker.d.ts.map +1 -0
  443. package/dist/task-next/task-next-ranker.js +179 -0
  444. package/dist/usage/usage-log.d.ts +54 -0
  445. package/dist/usage/usage-log.d.ts.map +1 -0
  446. package/dist/usage/usage-log.js +105 -0
  447. package/dist/validation/run-validation-loop.d.ts +38 -0
  448. package/dist/validation/run-validation-loop.d.ts.map +1 -0
  449. package/dist/validation/run-validation-loop.js +100 -0
  450. package/package.json +73 -0
@@ -0,0 +1,879 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import * as nodePath from 'node:path';
3
+ import { ApplyExitCategory, AssetProvenanceOperation, AssetProvenanceSource, buildApplyDispatchTrace, buildApplyGateResult, computeDevNextAction, DevSessionPhase, DevSessionPlanStatus, DevSessionSignatureStatus, detectSessionFromPlanPath, inspectSharkcraft, recomputePhase, recordAppliedPlan, recordProvenance, recordReportFile, recordValidation, renderApplyDispatchTraceText, scanDevSession, setDevNextAction, setDevSessionPhase, upsertDevPlanEntry, writeDevSessionState, } from '@shrkcrft/inspector';
4
+ import { applyAssetPreview } from "../asset-preview/apply-asset-preview.js";
5
+ import { ApplyBatchPlanError, parseApplyBatchPlan, runApplyBatch, } from "../task-next/apply-batch-runner.js";
6
+ import { applyFolderOps, checkFolderOpSafety, diffPlanChanges, diffPlanFolderOps, evaluateSavedPlanInPlace, FileChangeType, FolderOpSafety, generate, isSyntheticTemplateId, OverwriteStrategy, readPlanFromFile, verifyPlan, writeSyntheticPlan, } from '@shrkcrft/generator';
7
+ import { flagBool, flagList, flagString, resolveCwd, } from "../command-registry.js";
8
+ import { asJson, header } from "../output/format-output.js";
9
+ import { printError } from "../output/print-error.js";
10
+ import { runValidationLoop } from "../validation/run-validation-loop.js";
11
+ const CHANGE_LABEL = {
12
+ [FileChangeType.Create]: 'CREATE',
13
+ [FileChangeType.Update]: 'UPDATE',
14
+ [FileChangeType.Skip]: 'SKIP ',
15
+ [FileChangeType.Conflict]: 'CONFL ',
16
+ [FileChangeType.Append]: 'APPEND',
17
+ [FileChangeType.InsertAfter]: 'INSAFT',
18
+ [FileChangeType.InsertBefore]: 'INSBEF',
19
+ [FileChangeType.Replace]: 'REPL ',
20
+ [FileChangeType.Export]: 'EXPORT',
21
+ [FileChangeType.RenameFolder]: 'RMFLDR',
22
+ [FileChangeType.DeleteFolder]: 'DELFLD',
23
+ };
24
+ /**
25
+ * `shrk apply --asset-preview <draft.ts> --target <file>`.
26
+ *
27
+ * Takes a draft (typically under `.sharkcraft/authoring/`) produced by
28
+ * the authoring CLI (`knowledge add`, `rules scaffold`, etc.) and inserts
29
+ * it into the canonical asset file. Dry-run by default; `--write` to
30
+ * persist. Records provenance, surfaces signature status, prints
31
+ * validation commands.
32
+ */
33
+ async function runAssetPreviewApply(args, draftPath) {
34
+ const target = flagString(args, 'target');
35
+ if (!target) {
36
+ process.stderr.write('apply --asset-preview <draft.ts> requires --target <file>.\n');
37
+ return 2;
38
+ }
39
+ const wantJson = flagBool(args, 'json');
40
+ const cwd = resolveCwd(args);
41
+ const write = flagBool(args, 'write');
42
+ const allowUnknownTarget = flagBool(args, 'allow-unknown-target');
43
+ const reason = flagString(args, 'reason') ?? undefined;
44
+ const result = applyAssetPreview({
45
+ cwd,
46
+ draftPath,
47
+ targetPath: target,
48
+ write,
49
+ allowUnknownTarget,
50
+ });
51
+ if (!result.ok) {
52
+ if (wantJson) {
53
+ process.stdout.write(asJson({ schema: 'sharkcraft.asset-preview/v1', ...result }));
54
+ }
55
+ else {
56
+ process.stderr.write(`Refused: ${result.refusal}\n`);
57
+ }
58
+ return 1;
59
+ }
60
+ // Record provenance when we actually wrote (or always for previews? Per
61
+ // spec: "record provenance" on apply paths; dry-run is preview, not apply).
62
+ if (result.wrote) {
63
+ try {
64
+ recordProvenance({
65
+ projectRoot: cwd,
66
+ entry: {
67
+ operation: AssetProvenanceOperation.Apply,
68
+ assetKind: result.targetKind === 'unknown' ? 'unknown' : result.targetKind,
69
+ assetId: nodePath.basename(result.draftAbs).replace(/\.draft\.ts$/, ''),
70
+ targetFile: nodePath.relative(cwd, result.targetAbs),
71
+ source: process.env['SHARKCRAFT_AGENT'] ? AssetProvenanceSource.Agent : AssetProvenanceSource.Cli,
72
+ previewPath: nodePath.relative(cwd, result.draftAbs),
73
+ ...(reason ? { reason } : {}),
74
+ },
75
+ });
76
+ }
77
+ catch (e) {
78
+ // Provenance failures are advisory — do not block the apply.
79
+ process.stderr.write(`(warning) failed to record provenance: ${e instanceof Error ? e.message : String(e)}\n`);
80
+ }
81
+ }
82
+ if (wantJson) {
83
+ process.stdout.write(asJson({
84
+ schema: 'sharkcraft.asset-preview/v1',
85
+ ...result,
86
+ }));
87
+ return 0;
88
+ }
89
+ process.stdout.write(header(`apply --asset-preview${result.wrote ? '' : ' (dry-run)'}`));
90
+ process.stdout.write(` draft: ${nodePath.relative(cwd, result.draftAbs)}\n`);
91
+ process.stdout.write(` target: ${nodePath.relative(cwd, result.targetAbs)}\n`);
92
+ process.stdout.write(` target kind: ${result.targetKind}\n`);
93
+ process.stdout.write(` diff: +${result.diff?.added ?? 0} / -${result.diff?.removed ?? 0} lines\n`);
94
+ process.stdout.write(` wrote: ${result.wrote ? 'yes' : 'no (pass --write to persist)'}\n`);
95
+ if (result.diff) {
96
+ process.stdout.write('\n--- diff preview ---\n');
97
+ process.stdout.write(result.diff.preview);
98
+ process.stdout.write('\n--------------------\n');
99
+ }
100
+ process.stdout.write('\nNext (after review):\n');
101
+ if (result.wrote) {
102
+ if (result.targetKind === 'knowledge' || result.targetKind === 'rules' || result.targetKind === 'templates') {
103
+ process.stdout.write(` $ shrk packs signature-status # pack assets may have changed\n`);
104
+ }
105
+ for (const v of result.validationCommands) {
106
+ process.stdout.write(` $ ${v}\n`);
107
+ }
108
+ }
109
+ else {
110
+ process.stdout.write(` $ shrk apply --asset-preview ${nodePath.relative(cwd, result.draftAbs)} --target ${nodePath.relative(cwd, result.targetAbs)} --write\n`);
111
+ }
112
+ return 0;
113
+ }
114
+ /**
115
+ * `shrk apply --batch <plan.json>` thin CLI wrapper around the pure
116
+ * batch runner. Reads the plan, validates it, then dispatches each step
117
+ * via subprocess. The runner records the batchId in environment so each
118
+ * step's provenance can be grouped (callers may inspect
119
+ * SHARKCRAFT_BATCH_ID in their provenance writers, which is a no-op
120
+ * today — provenance grouping comes for free since the report carries
121
+ * the batchId).
122
+ */
123
+ async function runApplyBatchFromCli(args, batchPath) {
124
+ const wantJson = flagBool(args, 'json');
125
+ const cwd = resolveCwd(args);
126
+ const allowDivergent = flagBool(args, 'allow-divergent');
127
+ const dryRun = flagBool(args, 'dry-run');
128
+ let raw;
129
+ try {
130
+ raw = readFileSync(nodePath.resolve(cwd, batchPath), 'utf8');
131
+ }
132
+ catch (e) {
133
+ process.stderr.write(`Failed to read batch plan: ${e.message}\n`);
134
+ return 1;
135
+ }
136
+ let plan;
137
+ try {
138
+ plan = parseApplyBatchPlan(raw);
139
+ }
140
+ catch (e) {
141
+ if (e instanceof ApplyBatchPlanError) {
142
+ if (wantJson) {
143
+ process.stdout.write(asJson({ ok: false, refusal: e.message }) + '\n');
144
+ }
145
+ else {
146
+ process.stderr.write(`Refused: ${e.message}\n`);
147
+ }
148
+ return 2;
149
+ }
150
+ throw e;
151
+ }
152
+ // Use the current process's argv[1] as the shrk binary — this preserves
153
+ // the bun-direct invocation pattern used in dev and the symlinked
154
+ // `shrk` in the user's PATH.
155
+ const shrkBin = process.argv[1] ?? 'shrk';
156
+ const report = runApplyBatch({
157
+ plan,
158
+ allowDivergent,
159
+ dryRun,
160
+ cwd,
161
+ shrkBin,
162
+ });
163
+ if (wantJson) {
164
+ process.stdout.write(asJson(report) + '\n');
165
+ return report.success ? 0 : 1;
166
+ }
167
+ process.stdout.write(header(`apply --batch (${plan.steps.length} step(s))`));
168
+ process.stdout.write(` batchId: ${report.batchId}\n`);
169
+ process.stdout.write(` allowDivergent: ${report.allowDivergent ? 'yes' : 'no'}\n`);
170
+ process.stdout.write(` dryRun: ${dryRun ? 'yes' : 'no'}\n\n`);
171
+ for (const s of report.steps) {
172
+ process.stdout.write(` step ${s.stepIndex} ${s.kind.padEnd(18)} ${s.outcome.padEnd(8)} (exit=${s.exitCode})\n`);
173
+ }
174
+ if (report.stopped) {
175
+ process.stdout.write('\nStopped on first refusal. Pass --allow-divergent to skip refused steps and continue.\n');
176
+ }
177
+ return report.success ? 0 : 1;
178
+ }
179
+ export const applyCommand = {
180
+ name: 'apply',
181
+ description: 'Apply a previously-saved generation plan (sharkcraft.plan/v1 JSON). The CLI is the only write path; MCP never writes. Plans that live under .sharkcraft/sessions/<id>/plans/ automatically update the session metadata (signature + divergence + applied + validation).',
182
+ usage: 'shrk [--cwd <dir>] apply <plan.json> [--session <id>] [--force] [--allow-divergent] [--verify-signature] [--require-signature] [--dry-run] [--validate] [--report] [--json] [--trace] [--explain-dispatch] | shrk apply --asset-preview <draft.ts> --target <file> [--write] [--allow-unknown-target] [--reason <text>] | shrk apply --batch <plan.json> [--allow-divergent] [--dry-run] [--json]',
183
+ async run(args) {
184
+ // Asset-preview flow: paste-with-review for authoring drafts.
185
+ // Distinct from the plan-based apply path: takes a TS draft and a
186
+ // target asset file, shows a diff, optionally writes.
187
+ const assetPreview = flagString(args, 'asset-preview');
188
+ if (assetPreview) {
189
+ return await runAssetPreviewApply(args, assetPreview);
190
+ }
191
+ // Batch fix-chain runner. Reads a structured JSON plan, runs
192
+ // each step via the existing `shrk fix --<kind> --apply --json`
193
+ // surface, groups provenance under a content-hash batchId.
194
+ const batchPath = flagString(args, 'batch');
195
+ if (batchPath) {
196
+ return await runApplyBatchFromCli(args, batchPath);
197
+ }
198
+ const planArg = args.positional[0];
199
+ if (!planArg) {
200
+ process.stderr.write('Usage: shrk apply <plan.json>\n');
201
+ return 2;
202
+ }
203
+ const planPath = nodePath.resolve(planArg);
204
+ const planResult = readPlanFromFile(planPath);
205
+ if (!planResult.ok) {
206
+ printError(planResult.error);
207
+ return 1;
208
+ }
209
+ const saved = planResult.value;
210
+ const force = flagBool(args, 'force');
211
+ const allowDivergent = flagBool(args, 'allow-divergent');
212
+ const wantJson = flagBool(args, 'json');
213
+ const dryRun = flagBool(args, 'dry-run');
214
+ const verifySig = flagBool(args, 'verify-signature') || flagBool(args, 'require-signature');
215
+ const requireSig = flagBool(args, 'require-signature');
216
+ const explicitSession = flagString(args, 'session');
217
+ // Folder-op safety gates (default off).
218
+ const allowFolderOps = flagBool(args, 'allow-folder-ops');
219
+ const allowDeleteFolder = flagBool(args, 'allow-delete-folder');
220
+ // Dispatch trace (read-only output, no behaviour change).
221
+ const wantTrace = flagBool(args, 'trace') || flagBool(args, 'explain-dispatch');
222
+ const explainOnly = flagBool(args, 'explain-dispatch');
223
+ let signatureStatus = DevSessionSignatureStatus.NotChecked;
224
+ let signatureMessage;
225
+ if (verifySig) {
226
+ const result = verifyPlan(saved);
227
+ if (result.ok === true) {
228
+ signatureStatus = DevSessionSignatureStatus.Verified;
229
+ if (!wantJson)
230
+ process.stdout.write(`Signature: verified ✓\n`);
231
+ }
232
+ else if (result.status === 'missing-signature' && !requireSig) {
233
+ signatureStatus = DevSessionSignatureStatus.Unsigned;
234
+ signatureMessage = result.message;
235
+ if (!wantJson) {
236
+ process.stdout.write(`Signature: not present (plan is unsigned). Pass --require-signature to refuse.\n`);
237
+ }
238
+ }
239
+ else {
240
+ if (wantJson) {
241
+ const gateResult = buildApplyGateResult({
242
+ exitCategory: ApplyExitCategory.BlockedSignature,
243
+ signatureStatus: { status: result.status, message: result.message },
244
+ suggestedNextCommand: 'shrk gen --sign # then re-run apply',
245
+ });
246
+ process.stdout.write(asJson({ signatureStatus: result.status, message: result.message, gateResult }) + '\n');
247
+ }
248
+ else {
249
+ process.stderr.write(`Signature check failed (${result.status}): ${result.message}\n`);
250
+ }
251
+ return 1;
252
+ }
253
+ }
254
+ // The plan's projectRoot is authoritative for the apply, but the user
255
+ // can pass --cwd to override (for moved repos / new clone locations).
256
+ // resolveCwd defaults to process.cwd(); only override the plan when the
257
+ // user explicitly set --cwd.
258
+ const explicitCwd = typeof args.flags.get('cwd') === 'string' || args.globalCwd !== undefined;
259
+ const projectRoot = explicitCwd ? resolveCwd(args) : saved.projectRoot;
260
+ // Detect whether the plan lives under .sharkcraft/sessions/<id>/plans/. The
261
+ // --session flag overrides the path-based detection; both produce the same
262
+ // metadata writes below.
263
+ let sessionId = null;
264
+ let sessionPlanFile = null;
265
+ const detected = detectSessionFromPlanPath(planPath, projectRoot);
266
+ if (explicitSession) {
267
+ sessionId = explicitSession;
268
+ sessionPlanFile = detected?.planFile ?? nodePath.basename(planPath);
269
+ }
270
+ else if (detected) {
271
+ sessionId = detected.sessionId;
272
+ sessionPlanFile = detected.planFile;
273
+ }
274
+ if (!wantJson) {
275
+ process.stdout.write(header(`Applying plan: ${saved.templateId}`));
276
+ process.stdout.write(` source ${planPath}\n`);
277
+ process.stdout.write(` project root ${projectRoot}\n`);
278
+ if (sessionId)
279
+ process.stdout.write(` session ${sessionId}\n`);
280
+ if (saved.name)
281
+ process.stdout.write(` name ${saved.name}\n`);
282
+ if (Object.keys(saved.variables).length) {
283
+ process.stdout.write(` variables ${Object.entries(saved.variables)
284
+ .map(([k, v]) => `${k}=${v}`)
285
+ .join(', ')}\n`);
286
+ }
287
+ process.stdout.write(` saved at ${saved.createdAt}\n\n`);
288
+ }
289
+ const inspection = await inspectSharkcraft({ cwd: projectRoot });
290
+ // Build dispatch trace early so --explain-dispatch can short-circuit
291
+ // before any contract / template lookup. Trace describes the path the
292
+ // apply *would* take given the current flags.
293
+ let dispatchTrace = null;
294
+ if (wantTrace) {
295
+ dispatchTrace = buildApplyDispatchTrace({
296
+ plan: saved,
297
+ inspection,
298
+ dryRun,
299
+ allowFolderOps,
300
+ allowDeleteFolder,
301
+ verifySignature: verifySig,
302
+ diverged: false,
303
+ });
304
+ if (explainOnly) {
305
+ if (wantJson) {
306
+ process.stdout.write(asJson({ dispatchTrace }) + '\n');
307
+ }
308
+ else {
309
+ process.stdout.write(renderApplyDispatchTraceText(dispatchTrace));
310
+ }
311
+ return 0;
312
+ }
313
+ if (!wantJson) {
314
+ process.stdout.write(renderApplyDispatchTraceText(dispatchTrace));
315
+ process.stdout.write('\n');
316
+ }
317
+ }
318
+ // Opt-in contract gate. When --contract is supplied, the plan must
319
+ // pass `shrk contract check` before apply will write anything. Without
320
+ // --contract the apply behaviour is unchanged (no implicit gate).
321
+ const contractFlag = flagString(args, 'contract');
322
+ if (contractFlag) {
323
+ const { checkAgentContract, renderContractCheckText } = await import('@shrkcrft/inspector');
324
+ const absContract = nodePath.isAbsolute(contractFlag)
325
+ ? contractFlag
326
+ : nodePath.resolve(projectRoot, contractFlag);
327
+ let contract;
328
+ try {
329
+ contract = JSON.parse(readFileSync(absContract, 'utf8'));
330
+ }
331
+ catch (e) {
332
+ process.stderr.write(`Failed to read contract: ${e.message}\n`);
333
+ return 1;
334
+ }
335
+ const approvalFlag = flagString(args, 'approval');
336
+ const approvalPath = approvalFlag
337
+ ? nodePath.isAbsolute(approvalFlag)
338
+ ? approvalFlag
339
+ : nodePath.resolve(projectRoot, approvalFlag)
340
+ : undefined;
341
+ const gate = await checkAgentContract(inspection, contract, {
342
+ planPath,
343
+ ...(approvalPath ? { approvalPath } : {}),
344
+ });
345
+ if (!gate.pass) {
346
+ if (wantJson) {
347
+ const failures = gate.gates
348
+ .filter((g) => g.status === 'fail' || g.status === 'requires-approval')
349
+ .map((g) => {
350
+ const out = { id: g.id, status: g.status };
351
+ if (g.detail !== undefined)
352
+ out.detail = g.detail;
353
+ return out;
354
+ });
355
+ const gateResult = buildApplyGateResult({
356
+ exitCategory: ApplyExitCategory.BlockedContractGate,
357
+ contractGateFailures: failures,
358
+ suggestedNextCommand: `shrk contract approve ${nodePath.relative(projectRoot, absContract)} --by <you> --reason "<why>" --expires-in 2d --output <approval.json>`,
359
+ });
360
+ process.stdout.write(asJson({ contractGate: gate, gateResult }) + '\n');
361
+ }
362
+ else {
363
+ process.stdout.write(renderContractCheckText(gate));
364
+ process.stderr.write(`\nContract gate BLOCKED apply. Resolve the blocking gates or run with an --approval.\n`);
365
+ }
366
+ return 1;
367
+ }
368
+ if (!wantJson) {
369
+ process.stdout.write(`Contract gate: PASS (${gate.contractHash.slice(0, 12)}…)\n`);
370
+ }
371
+ }
372
+ const synthetic = isSyntheticTemplateId(saved.templateId);
373
+ const template = synthetic ? null : inspection.templateRegistry.get(saved.templateId);
374
+ if (!synthetic && !template) {
375
+ process.stderr.write(`Template "${saved.templateId}" is no longer registered in ${projectRoot}.\n`);
376
+ return 1;
377
+ }
378
+ // Regenerate the plan fresh against current templates + project state.
379
+ // Synthetic plans (templateId prefixed with `__`) evaluate their saved
380
+ // operations against the current file system instead of running a
381
+ // template renderer — there is no template to look up.
382
+ let livePlan;
383
+ if (synthetic) {
384
+ livePlan = evaluateSavedPlanInPlace(saved, projectRoot);
385
+ }
386
+ else {
387
+ const result = generate(template, {
388
+ templateId: saved.templateId,
389
+ name: saved.name,
390
+ variables: saved.variables,
391
+ projectRoot,
392
+ overwriteStrategy: force ? OverwriteStrategy.Overwrite : OverwriteStrategy.Never,
393
+ write: false,
394
+ });
395
+ if (!result.ok) {
396
+ printError(result.error);
397
+ return 1;
398
+ }
399
+ livePlan = result.value.plan;
400
+ }
401
+ const diff = diffPlanChanges(saved, livePlan);
402
+ if (diff.length > 0 && !allowDivergent && !force) {
403
+ if (!wantJson) {
404
+ process.stdout.write('Plan diverged from the saved version:\n');
405
+ for (const d of diff) {
406
+ process.stdout.write(` ${d.kind.padEnd(13)} ${d.relativePath}`);
407
+ if (d.detail)
408
+ process.stdout.write(` (${d.detail})`);
409
+ process.stdout.write('\n');
410
+ }
411
+ process.stdout.write('\nRefusing to apply. Re-run with --allow-divergent to apply the live plan, or regenerate the plan first.\n');
412
+ }
413
+ else {
414
+ const gateResult = buildApplyGateResult({
415
+ exitCategory: ApplyExitCategory.BlockedDivergence,
416
+ suggestedNextCommand: 'shrk apply --allow-divergent # accept live plan',
417
+ });
418
+ process.stdout.write(asJson({ diverged: true, diff, gateResult }) + '\n');
419
+ }
420
+ // Refused divergence: session.json untouched per spec.
421
+ return 1;
422
+ }
423
+ if (livePlan.hasConflicts) {
424
+ const conflicts = livePlan.changes
425
+ .filter((c) => c.type === FileChangeType.Conflict)
426
+ .map((c) => c.relativePath);
427
+ if (!wantJson) {
428
+ process.stdout.write('Live plan has conflicts. Apply refused.\n');
429
+ for (const change of livePlan.changes) {
430
+ if (change.type === FileChangeType.Conflict) {
431
+ process.stdout.write(` ${CHANGE_LABEL[change.type]} ${change.relativePath} — ${change.reason}\n`);
432
+ }
433
+ }
434
+ }
435
+ else {
436
+ const gateResult = buildApplyGateResult({
437
+ exitCategory: ApplyExitCategory.BlockedConflict,
438
+ notes: conflicts.map((c) => `Conflict: ${c}`),
439
+ suggestedNextCommand: 'shrk plan simulate <plan.json> --include-boundaries # inspect conflicts',
440
+ });
441
+ process.stdout.write(asJson({ conflicts: true, conflictFiles: conflicts, plan: livePlan, gateResult }) + '\n');
442
+ }
443
+ // Conflicts: session.json untouched per spec.
444
+ return 1;
445
+ }
446
+ // ─── Folder-op preflight ─────────────────────────────────────────────
447
+ // Folder ops carried by saved plans must pass *all* checks before any
448
+ // file or folder mutation happens. If a folder op is unsafe or the
449
+ // allow flag is missing, refuse the whole apply (mixed file+folder).
450
+ const plannedFolderOps = saved.folderOps ?? [];
451
+ // Live folder ops: today we don't regenerate them from a template. We
452
+ // use the saved set; divergence detection treats `saved.folderOps` ==
453
+ // `livePlan.folderOps` for v1 wiring. Plugin-lifecycle plans (Part 2)
454
+ // continue to carry their structured folderOps verbatim.
455
+ const liveFolderOps = plannedFolderOps;
456
+ const folderOpDiff = diffPlanFolderOps(saved, liveFolderOps);
457
+ if (folderOpDiff.length > 0 && !allowDivergent && !force) {
458
+ if (!wantJson) {
459
+ process.stdout.write('Folder-op set diverged from the saved version:\n');
460
+ for (const d of folderOpDiff) {
461
+ process.stdout.write(` ${d.kind.padEnd(13)} ${d.relativePath}`);
462
+ if (d.detail)
463
+ process.stdout.write(` (${d.detail})`);
464
+ process.stdout.write('\n');
465
+ }
466
+ process.stdout.write('\nRefusing to apply. Re-run with --allow-divergent to accept the live folder-op set, or regenerate the plan first.\n');
467
+ }
468
+ else {
469
+ const gateResult = buildApplyGateResult({
470
+ exitCategory: ApplyExitCategory.BlockedDivergence,
471
+ suggestedNextCommand: 'shrk apply --allow-divergent # accept live plan',
472
+ });
473
+ process.stdout.write(asJson({ diverged: true, folderOpDiff, gateResult }) + '\n');
474
+ }
475
+ return 1;
476
+ }
477
+ const folderPreflight = [];
478
+ for (const op of plannedFolderOps) {
479
+ const sopts = {};
480
+ if (allowDeleteFolder)
481
+ sopts.allowDeleteFolder = true;
482
+ const s = checkFolderOpSafety(projectRoot, op.targetPath, op.kind, sopts);
483
+ const entry = { op, safety: s.safety };
484
+ if (s.reason !== undefined)
485
+ entry.reason = s.reason;
486
+ folderPreflight.push(entry);
487
+ }
488
+ const unsafeOps = folderPreflight.filter((f) => f.safety !== FolderOpSafety.Safe);
489
+ const needsAllowFlag = plannedFolderOps.length > 0 && !allowFolderOps;
490
+ if (unsafeOps.length > 0 || needsAllowFlag) {
491
+ const exit = unsafeOps.length > 0
492
+ ? ApplyExitCategory.BlockedFolderOpUnsafe
493
+ : ApplyExitCategory.BlockedFolderOpAllowFlag;
494
+ const suggested = unsafeOps.length > 0
495
+ ? 'Resolve unsafe folder ops before re-running apply.'
496
+ : 'shrk apply ... --allow-folder-ops # enable folder ops';
497
+ if (!wantJson) {
498
+ if (unsafeOps.length > 0) {
499
+ process.stdout.write('Folder ops are unsafe — refusing the entire plan:\n');
500
+ for (const u of unsafeOps) {
501
+ process.stdout.write(` ${u.op.kind.toUpperCase()} ${u.op.targetPath}${u.op.newPath ? ` → ${u.op.newPath}` : ''} — ${u.reason ?? u.safety}\n`);
502
+ }
503
+ }
504
+ else {
505
+ process.stdout.write('Plan contains folder operations — refusing (pass --allow-folder-ops to enable):\n');
506
+ for (const f of folderPreflight) {
507
+ process.stdout.write(` ${f.op.kind.toUpperCase()} ${f.op.targetPath}${f.op.newPath ? ` → ${f.op.newPath}` : ''}\n`);
508
+ }
509
+ }
510
+ }
511
+ else {
512
+ const gateResult = buildApplyGateResult({
513
+ exitCategory: exit,
514
+ suggestedNextCommand: suggested,
515
+ notes: folderPreflight.map((f) => `${f.op.kind}:${f.op.targetPath} = ${f.safety}${f.reason ? ' (' + f.reason + ')' : ''}`),
516
+ });
517
+ process.stdout.write(asJson({
518
+ folderOps: folderPreflight.map((f) => ({
519
+ kind: f.op.kind,
520
+ targetPath: f.op.targetPath,
521
+ ...(f.op.newPath ? { newPath: f.op.newPath } : {}),
522
+ safety: f.safety,
523
+ ...(f.reason ? { reason: f.reason } : {}),
524
+ })),
525
+ gateResult,
526
+ }) + '\n');
527
+ }
528
+ return 1;
529
+ }
530
+ // Additional gate: any delete-folder requires --allow-delete-folder (the
531
+ // safety check above only flagged when allowDeleteFolder was false).
532
+ const deleteOps = plannedFolderOps.filter((o) => o.kind === 'delete-folder');
533
+ if (deleteOps.length > 0 && !allowDeleteFolder) {
534
+ if (!wantJson) {
535
+ process.stdout.write('Plan contains delete-folder ops — refusing (pass --allow-delete-folder in addition to --allow-folder-ops):\n');
536
+ for (const op of deleteOps) {
537
+ process.stdout.write(` DELETE-FOLDER ${op.targetPath}\n`);
538
+ }
539
+ }
540
+ else {
541
+ const gateResult = buildApplyGateResult({
542
+ exitCategory: ApplyExitCategory.BlockedFolderOpAllowFlag,
543
+ suggestedNextCommand: 'shrk apply ... --allow-folder-ops --allow-delete-folder',
544
+ notes: deleteOps.map((o) => `delete-folder:${o.targetPath} requires --allow-delete-folder`),
545
+ });
546
+ process.stdout.write(asJson({
547
+ folderOps: deleteOps.map((o) => ({
548
+ kind: o.kind,
549
+ targetPath: o.targetPath,
550
+ requires: '--allow-delete-folder',
551
+ })),
552
+ gateResult,
553
+ }) + '\n');
554
+ }
555
+ return 1;
556
+ }
557
+ // ──────────────────────────────────────────────────────────────────────────
558
+ // Dry-run: report what would happen and bail before writing. Per spec,
559
+ // dry-run must NOT mark the plan applied in session.json.
560
+ if (dryRun) {
561
+ if (wantJson) {
562
+ process.stdout.write(asJson({
563
+ applied: false,
564
+ dryRun: true,
565
+ planSummary: { changes: livePlan.changes.length },
566
+ divergencesAccepted: diff.length > 0,
567
+ folderOps: plannedFolderOps.map((o) => ({
568
+ kind: o.kind,
569
+ targetPath: o.targetPath,
570
+ ...(o.newPath ? { newPath: o.newPath } : {}),
571
+ })),
572
+ session: sessionId ? { id: sessionId, planFile: sessionPlanFile } : null,
573
+ }) + '\n');
574
+ }
575
+ else {
576
+ process.stdout.write('Dry-run only — no files written.\n');
577
+ for (const change of livePlan.changes) {
578
+ process.stdout.write(`${CHANGE_LABEL[change.type] ?? change.type.toUpperCase().padEnd(6)} ${change.relativePath}\n`);
579
+ }
580
+ for (const op of plannedFolderOps) {
581
+ const label = op.kind === 'rename-folder' ? CHANGE_LABEL[FileChangeType.RenameFolder] : CHANGE_LABEL[FileChangeType.DeleteFolder];
582
+ process.stdout.write(`${label} ${op.targetPath}${op.newPath ? ` → ${op.newPath}` : ''}\n`);
583
+ }
584
+ }
585
+ return 0;
586
+ }
587
+ // Apply.
588
+ let summary;
589
+ let written;
590
+ if (synthetic) {
591
+ const sw = writeSyntheticPlan(livePlan);
592
+ if (!sw.ok) {
593
+ printError(sw.error);
594
+ return 1;
595
+ }
596
+ summary = sw.value.summary;
597
+ written = sw.value.written;
598
+ }
599
+ else {
600
+ const writeResult = generate(template, {
601
+ templateId: saved.templateId,
602
+ name: saved.name,
603
+ variables: saved.variables,
604
+ projectRoot,
605
+ overwriteStrategy: force ? OverwriteStrategy.Overwrite : OverwriteStrategy.Never,
606
+ write: true,
607
+ });
608
+ if (!writeResult.ok) {
609
+ printError(writeResult.error);
610
+ // Failed apply: session.json untouched per spec.
611
+ return 1;
612
+ }
613
+ summary = writeResult.value.summary;
614
+ written = writeResult.value.written;
615
+ }
616
+ // Execute folder ops after files. Safety has already been verified
617
+ // and allow flags are present.
618
+ const folderOpReport = plannedFolderOps.length > 0
619
+ ? applyFolderOps(plannedFolderOps.map((o) => {
620
+ const entry = { kind: o.kind, targetPath: o.targetPath };
621
+ if (o.newPath !== undefined)
622
+ entry.newPath = o.newPath;
623
+ return entry;
624
+ }), {
625
+ projectRoot,
626
+ dryRun: false,
627
+ ...(allowFolderOps ? { allowFolderOps: true } : {}),
628
+ ...(allowDeleteFolder ? { allowDeleteFolder: true } : {}),
629
+ })
630
+ : null;
631
+ if (folderOpReport && folderOpReport.rejected.length > 0) {
632
+ if (!wantJson) {
633
+ process.stdout.write('Some folder ops failed during apply:\n');
634
+ for (const r of folderOpReport.rejected) {
635
+ process.stdout.write(` ${r.op.kind.toUpperCase()} ${r.op.targetPath}${r.op.newPath ? ` → ${r.op.newPath}` : ''} — ${r.reason ?? 'unknown'}\n`);
636
+ }
637
+ }
638
+ else {
639
+ const gateResult = buildApplyGateResult({
640
+ exitCategory: ApplyExitCategory.BlockedFolderOpUnsafe,
641
+ suggestedNextCommand: 'Inspect rejected folder ops and re-run apply.',
642
+ });
643
+ process.stdout.write(asJson({ folderOpReport, gateResult }) + '\n');
644
+ }
645
+ return 1;
646
+ }
647
+ // ─── Session-aware bookkeeping ────────────────────────────────────────────
648
+ // The CLI is the only write path; if this plan lives in a session, mark it
649
+ // applied with full provenance: changed files, signature, divergence.
650
+ let updatedNextAction = null;
651
+ if (sessionId && sessionPlanFile) {
652
+ const updated = updateSessionAfterApply({
653
+ cwd: projectRoot,
654
+ sessionId,
655
+ planFile: sessionPlanFile,
656
+ changedFiles: written.map((w) => w.relativePath),
657
+ signatureStatus,
658
+ divergenceAccepted: diff.length > 0,
659
+ });
660
+ updatedNextAction = updated?.nextAction ?? null;
661
+ }
662
+ if (wantJson && !flagBool(args, 'validate')) {
663
+ process.stdout.write(asJson({
664
+ applied: true,
665
+ summary,
666
+ written: written.map((w) => w.relativePath),
667
+ divergencesAccepted: diff.length > 0,
668
+ signatureStatus,
669
+ ...(signatureMessage ? { signatureMessage } : {}),
670
+ ...(folderOpReport
671
+ ? {
672
+ folderOps: folderOpReport.applied.map((r) => ({
673
+ kind: r.op.kind,
674
+ targetPath: r.op.targetPath,
675
+ ...(r.op.newPath ? { newPath: r.op.newPath } : {}),
676
+ applied: r.applied,
677
+ })),
678
+ }
679
+ : {}),
680
+ ...(dispatchTrace ? { dispatchTrace } : {}),
681
+ session: sessionId
682
+ ? { id: sessionId, planFile: sessionPlanFile, nextAction: updatedNextAction }
683
+ : null,
684
+ }) + '\n');
685
+ return 0;
686
+ }
687
+ if (!wantJson) {
688
+ for (const change of written) {
689
+ process.stdout.write(`${CHANGE_LABEL[change.type]} ${change.relativePath} (${change.sizeBytes} bytes)\n`);
690
+ }
691
+ if (folderOpReport) {
692
+ for (const r of folderOpReport.applied) {
693
+ const label = r.op.kind === 'rename-folder' ? CHANGE_LABEL[FileChangeType.RenameFolder] : CHANGE_LABEL[FileChangeType.DeleteFolder];
694
+ process.stdout.write(`${label} ${r.op.targetPath}${r.op.newPath ? ` → ${r.op.newPath}` : ''}\n`);
695
+ }
696
+ }
697
+ process.stdout.write(`\nApplied. written=${summary.written}, skipped=${summary.skipped}, conflicts=${summary.conflicts}${folderOpReport ? `, folderOps=${folderOpReport.applied.length}` : ''}\n`);
698
+ if (sessionId) {
699
+ process.stdout.write(`Session ${sessionId}: plan ${sessionPlanFile} marked applied.\n`);
700
+ if (updatedNextAction) {
701
+ process.stdout.write(`Next: ${updatedNextAction}\n`);
702
+ }
703
+ }
704
+ }
705
+ if (flagBool(args, 'validate')) {
706
+ const validateStrict = flagBool(args, 'validate-strict') || flagBool(args, 'strict');
707
+ const cmd = flagString(args, 'command');
708
+ const verificationIds = flagList(args, 'verification');
709
+ const allVerifications = flagBool(args, 'all-verifications');
710
+ const allowPackCommands = flagBool(args, 'allow-pack-commands');
711
+ const startedAt = new Date().toISOString();
712
+ const reportFileName = `apply-${startedAt.replace(/[:.]/g, '-')}.json`;
713
+ // Session-aware: write the validation report under the session's
714
+ // reports/ directory when this plan belongs to a session; otherwise
715
+ // fall back to the project-level .sharkcraft/reports/.
716
+ const reportDir = sessionId
717
+ ? nodePath.join(projectRoot, '.sharkcraft', 'sessions', sessionId, 'reports')
718
+ : flagBool(args, 'report')
719
+ ? nodePath.join(projectRoot, '.sharkcraft', 'reports')
720
+ : null;
721
+ const validation = await runValidationLoop({
722
+ cwd: projectRoot,
723
+ ...(cmd ? { explicitCommand: cmd } : {}),
724
+ verificationIds,
725
+ allVerifications,
726
+ allowPackCommands,
727
+ reportDir,
728
+ reportFileName,
729
+ onCommandStart: (label) => {
730
+ if (!wantJson)
731
+ process.stdout.write(` → running: ${label}\n`);
732
+ },
733
+ });
734
+ const finishedAt = new Date().toISOString();
735
+ const failed = !validation.passed || (validateStrict && validation.warnings > 0);
736
+ // Session-aware: append validation entry to session.json, link to the
737
+ // applied plan, set phase to validated / validation_failed, recompute
738
+ // nextAction.
739
+ let validationNextAction = updatedNextAction;
740
+ if (sessionId && sessionPlanFile) {
741
+ const after = recordSessionValidation({
742
+ cwd: projectRoot,
743
+ sessionId,
744
+ planFile: sessionPlanFile,
745
+ startedAt,
746
+ finishedAt,
747
+ reportFile: reportFileName,
748
+ passed: !failed,
749
+ warnings: validation.warnings,
750
+ commandsRun: validation.commandsRun.map((c) => {
751
+ const entry = {
752
+ command: c.command,
753
+ passed: c.passed,
754
+ };
755
+ if (c.note !== undefined)
756
+ entry.note = c.note;
757
+ return entry;
758
+ }),
759
+ boundaryViolations: validation.boundaryViolations,
760
+ });
761
+ validationNextAction = after?.nextAction ?? updatedNextAction;
762
+ }
763
+ if (wantJson) {
764
+ process.stdout.write(asJson({
765
+ applied: true,
766
+ summary,
767
+ written: written.map((w) => w.relativePath),
768
+ divergencesAccepted: diff.length > 0,
769
+ signatureStatus,
770
+ ...(signatureMessage ? { signatureMessage } : {}),
771
+ validation: {
772
+ passed: !failed,
773
+ warnings: validation.warnings,
774
+ boundaryViolations: validation.boundaryViolations,
775
+ commandsRun: validation.commandsRun,
776
+ commandsFailed: validation.commandsFailed,
777
+ reportPath: validation.reportPath,
778
+ },
779
+ ...(dispatchTrace ? { dispatchTrace } : {}),
780
+ session: sessionId
781
+ ? {
782
+ id: sessionId,
783
+ planFile: sessionPlanFile,
784
+ nextAction: validationNextAction,
785
+ }
786
+ : null,
787
+ }) + '\n');
788
+ return failed ? 1 : 0;
789
+ }
790
+ process.stdout.write(`\nValidation: ${validation.commandsRun.length} command(s), ${validation.commandsFailed.length} failed, ${validation.warnings} warning(s)\n`);
791
+ for (const c of validation.commandsRun) {
792
+ process.stdout.write(` ${c.passed ? 'OK ' : 'FAIL '} ${c.command}${c.note ? ' (' + c.note + ')' : ''}\n`);
793
+ }
794
+ if (validation.boundaryViolations > 0) {
795
+ process.stdout.write(` WARN ${validation.boundaryViolations} boundary violation(s) detected\n`);
796
+ }
797
+ if (validation.reportPath) {
798
+ process.stdout.write(` Report: ${validation.reportPath}\n`);
799
+ }
800
+ if (failed) {
801
+ process.stdout.write('\nValidation: FAILED\n');
802
+ return 1;
803
+ }
804
+ process.stdout.write('\nValidation: OK ✓\n');
805
+ }
806
+ return 0;
807
+ },
808
+ };
809
+ function updateSessionAfterApply(input) {
810
+ const load = scanDevSession(input.cwd, input.sessionId);
811
+ if (!load || !load.state)
812
+ return null;
813
+ let state = load.state;
814
+ const appliedAt = new Date().toISOString();
815
+ state = recordAppliedPlan(state, {
816
+ file: input.planFile,
817
+ appliedAt,
818
+ note: input.divergenceAccepted ? 'applied with divergence accepted' : 'applied via shrk apply',
819
+ changedFiles: [...input.changedFiles],
820
+ signatureStatus: input.signatureStatus,
821
+ divergenceAccepted: input.divergenceAccepted,
822
+ conflicts: [],
823
+ });
824
+ // Promote the matching plan entry to "applied" so dev status reflects it.
825
+ const existing = load.state.plans.find((p) => p.file === input.planFile);
826
+ if (existing) {
827
+ state = upsertDevPlanEntry(state, {
828
+ name: existing.name,
829
+ templateId: existing.templateId,
830
+ ...(existing.generatedName ? { generatedName: existing.generatedName } : {}),
831
+ variables: { ...existing.variables },
832
+ missingVariables: existing.missingVariables,
833
+ status: DevSessionPlanStatus.Applied,
834
+ file: existing.file,
835
+ signed: existing.signed,
836
+ ...(existing.reviewReportFile ? { reviewReportFile: existing.reviewReportFile } : {}),
837
+ ...(existing.reviewReportMarkdownFile
838
+ ? { reviewReportMarkdownFile: existing.reviewReportMarkdownFile }
839
+ : {}),
840
+ });
841
+ }
842
+ const scanAfter = scanDevSession(input.cwd, input.sessionId);
843
+ const newPhase = recomputePhase(state, scanAfter);
844
+ state = setDevSessionPhase(state, newPhase);
845
+ const next = computeDevNextAction({ ...scanAfter, state });
846
+ state = setDevNextAction(state, next.command);
847
+ return writeDevSessionState(input.cwd, state);
848
+ }
849
+ function recordSessionValidation(input) {
850
+ const load = scanDevSession(input.cwd, input.sessionId);
851
+ if (!load || !load.state)
852
+ return null;
853
+ let state = recordValidation(load.state, {
854
+ startedAt: input.startedAt,
855
+ finishedAt: input.finishedAt,
856
+ reportFile: input.reportFile,
857
+ passed: input.passed,
858
+ warnings: input.warnings,
859
+ commandsRun: input.commandsRun.map((c) => {
860
+ const entry = {
861
+ command: c.command,
862
+ passed: c.passed,
863
+ };
864
+ if (c.note !== undefined)
865
+ entry.note = c.note;
866
+ return entry;
867
+ }),
868
+ boundaryViolations: input.boundaryViolations,
869
+ });
870
+ state = recordReportFile(state, `reports/${input.reportFile}`);
871
+ const scanAfter = scanDevSession(input.cwd, input.sessionId);
872
+ const newPhase = input.passed
873
+ ? DevSessionPhase.Validated
874
+ : DevSessionPhase.ValidationFailed;
875
+ state = setDevSessionPhase(state, newPhase);
876
+ const next = computeDevNextAction({ ...scanAfter, state });
877
+ state = setDevNextAction(state, next.command);
878
+ return writeDevSessionState(input.cwd, state);
879
+ }