@topogram/cli 0.3.63 → 0.3.65

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 (344) hide show
  1. package/package.json +1 -1
  2. package/src/adoption/plan/index.js +703 -0
  3. package/src/adoption/plan.d.ts +6 -0
  4. package/src/adoption/plan.js +12 -703
  5. package/src/adoption/reporting.d.ts +10 -0
  6. package/src/adoption/review-groups.d.ts +6 -0
  7. package/src/agent-brief.d.ts +3 -0
  8. package/src/agent-brief.js +495 -0
  9. package/src/agent-ops/query-builders/auth.js +375 -0
  10. package/src/agent-ops/query-builders/change-risk/change-plan.js +123 -0
  11. package/src/agent-ops/query-builders/change-risk/import-plan.js +49 -0
  12. package/src/agent-ops/query-builders/change-risk/maintained.js +286 -0
  13. package/src/agent-ops/query-builders/change-risk/review-packets.js +123 -0
  14. package/src/agent-ops/query-builders/change-risk/risk.js +189 -0
  15. package/src/agent-ops/query-builders/change-risk.js +25 -0
  16. package/src/agent-ops/query-builders/common.js +149 -0
  17. package/src/agent-ops/query-builders/maintained-risk.js +539 -0
  18. package/src/agent-ops/query-builders/maintained-shared.js +120 -0
  19. package/src/agent-ops/query-builders/multi-agent.js +547 -0
  20. package/src/agent-ops/query-builders/projection-impacts.js +514 -0
  21. package/src/agent-ops/query-builders/work-packets.js +417 -0
  22. package/src/agent-ops/query-builders/workflow-context-shared.js +300 -0
  23. package/src/agent-ops/query-builders/workflow-context.js +398 -0
  24. package/src/agent-ops/query-builders/workflow-presets-core.js +676 -0
  25. package/src/agent-ops/query-builders/workflow-presets.js +341 -0
  26. package/src/agent-ops/query-builders.d.ts +26 -0
  27. package/src/agent-ops/query-builders.js +42 -5021
  28. package/src/archive/archive.d.ts +2 -0
  29. package/src/archive/compact.d.ts +1 -0
  30. package/src/archive/unarchive.d.ts +1 -0
  31. package/src/catalog/constants.js +10 -0
  32. package/src/catalog/copy.js +60 -0
  33. package/src/catalog/diagnostics.js +15 -0
  34. package/src/catalog/entries.js +42 -0
  35. package/src/catalog/files.js +67 -0
  36. package/src/catalog/provenance.js +122 -0
  37. package/src/catalog/source.js +150 -0
  38. package/src/catalog/validation.js +252 -0
  39. package/src/catalog.d.ts +12 -0
  40. package/src/catalog.js +18 -750
  41. package/src/cli/catalog-alias.d.ts +1 -0
  42. package/src/cli/command-parser.js +38 -0
  43. package/src/cli/command-parsers/core.js +102 -0
  44. package/src/cli/command-parsers/generator.js +39 -0
  45. package/src/cli/command-parsers/import.js +44 -0
  46. package/src/cli/command-parsers/legacy-workflow.js +21 -0
  47. package/src/cli/command-parsers/project.js +47 -0
  48. package/src/cli/command-parsers/sdlc.js +47 -0
  49. package/src/cli/command-parsers/shared.js +51 -0
  50. package/src/cli/command-parsers/template.js +48 -0
  51. package/src/cli/commands/agent.js +47 -0
  52. package/src/cli/commands/catalog/check.js +31 -0
  53. package/src/cli/commands/catalog/copy.js +59 -0
  54. package/src/cli/commands/catalog/doctor.js +248 -0
  55. package/src/cli/commands/catalog/help.js +21 -0
  56. package/src/cli/commands/catalog/list.js +52 -0
  57. package/src/cli/commands/catalog/runner.js +92 -0
  58. package/src/cli/commands/catalog/shared.js +17 -0
  59. package/src/cli/commands/catalog/show.js +134 -0
  60. package/src/cli/commands/catalog.js +32 -0
  61. package/src/cli/commands/check.js +268 -0
  62. package/src/cli/commands/doctor.js +268 -0
  63. package/src/cli/commands/emit.js +149 -0
  64. package/src/cli/commands/generate.js +96 -0
  65. package/src/cli/commands/generator-policy/package-info.js +162 -0
  66. package/src/cli/commands/generator-policy/payloads.js +372 -0
  67. package/src/cli/commands/generator-policy/printers.js +159 -0
  68. package/src/cli/commands/generator-policy/runner.js +81 -0
  69. package/src/cli/commands/generator-policy/shared.js +39 -0
  70. package/src/cli/commands/generator-policy.js +17 -0
  71. package/src/cli/commands/generator.js +443 -0
  72. package/src/cli/commands/import/adopt.js +170 -0
  73. package/src/cli/commands/import/check.js +91 -0
  74. package/src/cli/commands/import/diff.js +84 -0
  75. package/src/cli/commands/import/help.js +47 -0
  76. package/src/cli/commands/import/paths.js +277 -0
  77. package/src/cli/commands/import/plan.js +284 -0
  78. package/src/cli/commands/import/refresh.js +470 -0
  79. package/src/cli/commands/import/status-history.js +196 -0
  80. package/src/cli/commands/import/workspace.js +230 -0
  81. package/src/cli/commands/import-runner.js +157 -0
  82. package/src/cli/commands/import.js +35 -0
  83. package/src/cli/commands/inspect.js +55 -0
  84. package/src/cli/commands/new.js +94 -0
  85. package/src/cli/commands/package/constants.js +17 -0
  86. package/src/cli/commands/package/doctor.js +240 -0
  87. package/src/cli/commands/package/help.js +27 -0
  88. package/src/cli/commands/package/lockfile.js +135 -0
  89. package/src/cli/commands/package/npm.js +97 -0
  90. package/src/cli/commands/package/reporting.js +35 -0
  91. package/src/cli/commands/package/runner.js +33 -0
  92. package/src/cli/commands/package/shared.js +9 -0
  93. package/src/cli/commands/package/update-cli.js +252 -0
  94. package/src/cli/commands/package/versions.js +35 -0
  95. package/src/cli/commands/package.js +31 -0
  96. package/src/cli/commands/query/change-plan.js +68 -0
  97. package/src/cli/commands/query/definitions.js +202 -0
  98. package/src/cli/commands/query/import-adopt.js +121 -0
  99. package/src/cli/commands/query/runner/artifacts.js +102 -0
  100. package/src/cli/commands/query/runner/boundaries.js +211 -0
  101. package/src/cli/commands/query/runner/change.js +182 -0
  102. package/src/cli/commands/query/runner/import-adopt.js +111 -0
  103. package/src/cli/commands/query/runner/index.js +31 -0
  104. package/src/cli/commands/query/runner/output.js +12 -0
  105. package/src/cli/commands/query/runner/workflow.js +241 -0
  106. package/src/cli/commands/query/runner.js +3 -0
  107. package/src/cli/commands/query/workflow-context.js +5 -0
  108. package/src/cli/commands/query/workspace.js +274 -0
  109. package/src/cli/commands/query.js +11 -0
  110. package/src/cli/commands/release-rollout.js +257 -0
  111. package/src/cli/commands/release-shared.js +528 -0
  112. package/src/cli/commands/release-status.js +429 -0
  113. package/src/cli/commands/release.js +107 -0
  114. package/src/cli/commands/sdlc.js +168 -0
  115. package/src/cli/commands/setup.js +76 -0
  116. package/src/cli/commands/source.js +291 -0
  117. package/src/cli/commands/template/baseline.js +100 -0
  118. package/src/cli/commands/template/check.js +466 -0
  119. package/src/cli/commands/template/constants.js +8 -0
  120. package/src/cli/commands/template/diagnostics.js +26 -0
  121. package/src/cli/commands/template/help.js +28 -0
  122. package/src/cli/commands/template/lifecycle.js +404 -0
  123. package/src/cli/commands/template/list-show.js +287 -0
  124. package/src/cli/commands/template/policy.js +422 -0
  125. package/src/cli/commands/template/shared.js +127 -0
  126. package/src/cli/commands/template/updates.js +352 -0
  127. package/src/cli/commands/template-runner.js +198 -0
  128. package/src/cli/commands/template.js +43 -0
  129. package/src/cli/commands/trust.js +219 -0
  130. package/src/cli/commands/version.js +40 -0
  131. package/src/cli/commands/widget.js +168 -0
  132. package/src/cli/commands/workflow.js +63 -0
  133. package/src/cli/dispatcher.js +392 -0
  134. package/src/cli/help-dispatch.js +188 -0
  135. package/src/cli/help.js +296 -0
  136. package/src/cli/migration-guidance.js +59 -0
  137. package/src/cli/options.js +96 -0
  138. package/src/cli/output-safety.js +107 -0
  139. package/src/cli/path-normalization.js +29 -0
  140. package/src/cli.js +47 -11711
  141. package/src/example-implementation.d.ts +2 -0
  142. package/src/format.d.ts +1 -0
  143. package/src/generator/api/contracts.js +497 -0
  144. package/src/generator/api/metadata.js +221 -0
  145. package/src/generator/api/openapi.js +559 -0
  146. package/src/generator/api/schema.js +124 -0
  147. package/src/generator/api/types.d.ts +98 -0
  148. package/src/generator/api.js +3 -1195
  149. package/src/generator/check.d.ts +1 -0
  150. package/src/generator/context/bundle.d.ts +1 -0
  151. package/src/generator/context/shared/domain-sdlc.js +282 -0
  152. package/src/generator/context/shared/maintained-boundary.js +665 -0
  153. package/src/generator/context/shared/metrics.js +85 -0
  154. package/src/generator/context/shared/primitives.js +64 -0
  155. package/src/generator/context/shared/relationships.js +453 -0
  156. package/src/generator/context/shared/summaries.js +263 -0
  157. package/src/generator/context/shared/types.d.ts +207 -0
  158. package/src/generator/context/shared.d.ts +44 -0
  159. package/src/generator/context/shared.js +80 -1390
  160. package/src/generator/context/slice/core.js +397 -0
  161. package/src/generator/context/slice/sdlc.js +417 -0
  162. package/src/generator/context/slice/ui-packets.js +183 -0
  163. package/src/generator/context/slice.js +2 -859
  164. package/src/generator/native/parity-bundle.js +2 -1
  165. package/src/generator/registry/index.js +507 -0
  166. package/src/generator/registry.js +18 -504
  167. package/src/generator/runtime/environment/index.js +666 -0
  168. package/src/generator/runtime/environment.js +4 -666
  169. package/src/generator/runtime/runtime-check/index.js +554 -0
  170. package/src/generator/runtime/runtime-check.js +4 -554
  171. package/src/generator/runtime/shared/index.js +572 -0
  172. package/src/generator/runtime/shared.js +19 -570
  173. package/src/generator/shared.d.ts +2 -0
  174. package/src/generator/surfaces/shared.d.ts +3 -0
  175. package/src/generator/surfaces/web/html-escape.js +22 -0
  176. package/src/generator/surfaces/web/react.js +10 -8
  177. package/src/generator/surfaces/web/sveltekit.js +7 -5
  178. package/src/generator/surfaces/web/vanilla.js +8 -4
  179. package/src/generator/widget-conformance/behavior-report.js +258 -0
  180. package/src/generator/widget-conformance/checks.js +371 -0
  181. package/src/generator/widget-conformance/projection-context.js +200 -0
  182. package/src/generator/widget-conformance/report.js +166 -0
  183. package/src/generator/widget-conformance/types.d.ts +121 -0
  184. package/src/generator/widget-conformance.js +3 -824
  185. package/src/generator.d.ts +2 -0
  186. package/src/github-client.js +520 -0
  187. package/src/import/core/context.d.ts +3 -0
  188. package/src/import/core/contracts.d.ts +1 -0
  189. package/src/import/core/registry.d.ts +4 -0
  190. package/src/import/core/runner/candidates.js +217 -0
  191. package/src/import/core/runner/options.js +22 -0
  192. package/src/import/core/runner/reports.js +50 -0
  193. package/src/import/core/runner/run.js +79 -0
  194. package/src/import/core/runner/tracks.js +150 -0
  195. package/src/import/core/runner/ui-drafts.js +337 -0
  196. package/src/import/core/runner.js +3 -698
  197. package/src/import/core/shared/api-routes.js +221 -0
  198. package/src/import/core/shared/candidates.js +97 -0
  199. package/src/import/core/shared/files.js +177 -0
  200. package/src/import/core/shared/next-app.js +389 -0
  201. package/src/import/core/shared/types.d.ts +51 -0
  202. package/src/import/core/shared/ui-routes.js +230 -0
  203. package/src/import/core/shared.js +67 -910
  204. package/src/import/extractors/api/flutter-dio.js +4 -8
  205. package/src/import/extractors/api/react-native-repository.js +4 -8
  206. package/src/import/index.d.ts +4 -0
  207. package/src/import/provenance.d.ts +4 -0
  208. package/src/new-project/constants.js +128 -0
  209. package/src/new-project/create.js +83 -0
  210. package/src/new-project/json.js +28 -0
  211. package/src/new-project/metadata.js +96 -0
  212. package/src/new-project/package-spec.js +161 -0
  213. package/src/new-project/project-files.js +348 -0
  214. package/src/new-project/template-policy.js +269 -0
  215. package/src/new-project/template-resolution.js +368 -0
  216. package/src/new-project/template-snapshots.js +430 -0
  217. package/src/new-project/template-updates.js +512 -0
  218. package/src/new-project/types.d.ts +83 -0
  219. package/src/new-project.js +6 -2188
  220. package/src/npm-safety.js +79 -0
  221. package/src/parser.d.ts +87 -0
  222. package/src/parser.js +118 -0
  223. package/src/path-helpers.d.ts +1 -0
  224. package/src/path-helpers.js +20 -0
  225. package/src/policy/review-boundaries.d.ts +15 -0
  226. package/src/project-config/index.js +564 -0
  227. package/src/project-config.js +19 -560
  228. package/src/reconcile/docs.d.ts +8 -0
  229. package/src/reconcile/journeys.d.ts +1 -0
  230. package/src/resolver/enrich/acceptance-criterion.js +2 -0
  231. package/src/resolver/enrich/bug.js +2 -0
  232. package/src/resolver/enrich/pitch.js +2 -0
  233. package/src/resolver/enrich/requirement.js +2 -0
  234. package/src/resolver/enrich/task.js +2 -0
  235. package/src/resolver/index.js +19 -2089
  236. package/src/resolver/normalize.js +384 -1
  237. package/src/resolver/plans.js +168 -0
  238. package/src/resolver/projections-api.js +494 -0
  239. package/src/resolver/projections-db.js +133 -0
  240. package/src/resolver/projections-ui.js +317 -0
  241. package/src/resolver/shapes.js +251 -0
  242. package/src/resolver/shared.js +278 -0
  243. package/src/resolver/widgets.js +132 -0
  244. package/src/resolver.d.ts +1 -0
  245. package/src/runtime-support.js +29 -0
  246. package/src/sdlc/adopt.d.ts +1 -0
  247. package/src/sdlc/check.d.ts +1 -0
  248. package/src/sdlc/explain.d.ts +1 -0
  249. package/src/sdlc/release.d.ts +1 -0
  250. package/src/sdlc/scaffold.d.ts +1 -0
  251. package/src/sdlc/transition.d.ts +1 -0
  252. package/src/template-trust/constants.js +62 -0
  253. package/src/template-trust/content.js +258 -0
  254. package/src/template-trust/diff.js +92 -0
  255. package/src/template-trust/policy.js +61 -0
  256. package/src/template-trust/record.js +90 -0
  257. package/src/template-trust/status.js +182 -0
  258. package/src/template-trust.js +24 -687
  259. package/src/text-helpers.d.ts +7 -0
  260. package/src/text-helpers.js +245 -0
  261. package/src/topogram-config.js +306 -0
  262. package/src/topogram-types.d.ts +69 -0
  263. package/src/validator/common.js +488 -0
  264. package/src/validator/data-model.js +237 -0
  265. package/src/validator/docs.js +167 -0
  266. package/src/validator/expressions.js +146 -1
  267. package/src/validator/index.d.ts +23 -0
  268. package/src/validator/index.js +32 -3585
  269. package/src/validator/kinds.d.ts +41 -0
  270. package/src/validator/kinds.js +2 -0
  271. package/src/validator/model-helpers.js +46 -0
  272. package/src/validator/per-kind/acceptance-criterion.js +5 -0
  273. package/src/validator/per-kind/bug.js +6 -0
  274. package/src/validator/per-kind/domain.js +15 -2
  275. package/src/validator/per-kind/pitch.js +7 -0
  276. package/src/validator/per-kind/requirement.js +5 -0
  277. package/src/validator/per-kind/task.js +7 -0
  278. package/src/validator/per-kind/widget.js +14 -0
  279. package/src/validator/projections/api-http-async.js +410 -0
  280. package/src/validator/projections/api-http-authz.js +88 -0
  281. package/src/validator/projections/api-http-core.js +205 -0
  282. package/src/validator/projections/api-http-policies.js +339 -0
  283. package/src/validator/projections/api-http-responses.js +233 -0
  284. package/src/validator/projections/api-http.js +44 -0
  285. package/src/validator/projections/db.js +353 -0
  286. package/src/validator/projections/generator-defaults.js +45 -0
  287. package/src/validator/projections/helpers.js +87 -0
  288. package/src/validator/projections/ui-helpers.js +214 -0
  289. package/src/validator/projections/ui-navigation.js +344 -0
  290. package/src/validator/projections/ui-structure.js +364 -0
  291. package/src/validator/projections/ui-widgets.js +493 -0
  292. package/src/validator/projections/ui.js +46 -0
  293. package/src/validator/registry.js +48 -1
  294. package/src/validator/utils.d.ts +20 -0
  295. package/src/validator/utils.js +115 -12
  296. package/src/validator.d.ts +2 -0
  297. package/src/widget-behavior.d.ts +1 -0
  298. package/src/workflows/adoption/index.js +26 -0
  299. package/src/workflows/docs-generate.js +262 -0
  300. package/src/workflows/docs-scan.js +703 -0
  301. package/src/workflows/docs.js +15 -0
  302. package/src/workflows/import-app/api/collect.js +221 -0
  303. package/src/workflows/import-app/api/openapi.js +257 -0
  304. package/src/workflows/import-app/api/routes.js +327 -0
  305. package/src/workflows/import-app/api/sources.js +22 -0
  306. package/src/workflows/import-app/api.js +4 -0
  307. package/src/workflows/import-app/db.js +538 -0
  308. package/src/workflows/import-app/index.js +30 -0
  309. package/src/workflows/import-app/shared.js +218 -0
  310. package/src/workflows/import-app/ui.js +443 -0
  311. package/src/workflows/import-app/workflow.js +159 -0
  312. package/src/workflows/reconcile/adoption-plan/build.js +208 -0
  313. package/src/workflows/reconcile/adoption-plan/dependencies.js +75 -0
  314. package/src/workflows/reconcile/adoption-plan/outputs.js +143 -0
  315. package/src/workflows/reconcile/adoption-plan/paths.js +58 -0
  316. package/src/workflows/reconcile/adoption-plan/projection-patches.js +177 -0
  317. package/src/workflows/reconcile/adoption-plan/reasons.js +107 -0
  318. package/src/workflows/reconcile/adoption-plan.js +32 -0
  319. package/src/workflows/reconcile/auth/closures.js +115 -0
  320. package/src/workflows/reconcile/auth/formatters.js +142 -0
  321. package/src/workflows/reconcile/auth/inference.js +330 -0
  322. package/src/workflows/reconcile/auth/roles.js +122 -0
  323. package/src/workflows/reconcile/auth.js +37 -0
  324. package/src/workflows/reconcile/bundle-core/index.js +600 -0
  325. package/src/workflows/reconcile/bundle-core.js +14 -0
  326. package/src/workflows/reconcile/bundle-shared.js +75 -0
  327. package/src/workflows/reconcile/candidate-model.js +477 -0
  328. package/src/workflows/reconcile/canonical-surface.js +264 -0
  329. package/src/workflows/reconcile/gap-report.js +333 -0
  330. package/src/workflows/reconcile/ids.js +6 -0
  331. package/src/workflows/reconcile/impacts/adoption-plan.js +192 -0
  332. package/src/workflows/reconcile/impacts/indexes.js +101 -0
  333. package/src/workflows/reconcile/impacts/patches.js +252 -0
  334. package/src/workflows/reconcile/impacts/reports.js +80 -0
  335. package/src/workflows/reconcile/impacts.js +16 -0
  336. package/src/workflows/reconcile/index.js +7 -0
  337. package/src/workflows/reconcile/renderers.js +461 -0
  338. package/src/workflows/reconcile/summary.js +90 -0
  339. package/src/workflows/reconcile/workflow.js +309 -0
  340. package/src/workflows/shared.js +189 -0
  341. package/src/workflows/types.d.ts +93 -0
  342. package/src/workflows.d.ts +1 -0
  343. package/src/workflows.js +10 -7652
  344. package/src/workspace-docs.d.ts +29 -0
@@ -0,0 +1,443 @@
1
+ // @ts-check
2
+
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+
6
+ import { stableStringify } from "../../format.js";
7
+ import { checkGeneratorPack } from "../../generator/check.js";
8
+ import {
9
+ GENERATOR_MANIFESTS,
10
+ getGeneratorManifest,
11
+ loadPackageGeneratorManifest,
12
+ packageGeneratorInstallCommand
13
+ } from "../../generator/registry.js";
14
+ import { GENERATOR_POLICY_FILE } from "../../generator-policy.js";
15
+
16
+ /**
17
+ * @returns {void}
18
+ */
19
+ export function printGeneratorHelp() {
20
+ console.log("Usage: topogram generator list [--json]");
21
+ console.log(" or: topogram generator show <id-or-package> [--json]");
22
+ console.log(" or: topogram generator check <path-or-package> [--json]");
23
+ console.log(" or: topogram generator policy init [path] [--json]");
24
+ console.log(" or: topogram generator policy status [path] [--json]");
25
+ console.log(" or: topogram generator policy check [path] [--json]");
26
+ console.log(" or: topogram generator policy explain [path] [--json]");
27
+ console.log(" or: topogram generator policy pin [package@version] [path] [--json]");
28
+ console.log("");
29
+ console.log("Inspects generator manifests and checks generator pack conformance.");
30
+ console.log("");
31
+ console.log("Notes:");
32
+ console.log(" - list shows bundled generators plus installed package-backed generators declared in package.json; it reads manifests only.");
33
+ console.log(" - show accepts an installed package name or a bundled fallback generator id; it does not load adapter code.");
34
+ console.log(" - check validates a local generator package path or an already installed package by loading the adapter and running smoke generation.");
35
+ console.log(" - Topogram does not install generator packages during show or check.");
36
+ console.log(` - package-backed project generators are governed by ${GENERATOR_POLICY_FILE}; bundled topogram/* generators are allowed.`);
37
+ console.log("");
38
+ console.log("Examples:");
39
+ console.log(" topogram generator list");
40
+ console.log(" topogram generator list --json");
41
+ console.log(" topogram generator show @topogram/generator-react-web");
42
+ console.log(" topogram generator show @scope/topogram-generator-web --json");
43
+ console.log(" topogram generator check ./generator-package");
44
+ console.log(" topogram generator check @scope/topogram-generator-web --json");
45
+ console.log(" topogram generator policy init");
46
+ console.log(" topogram generator policy status --json");
47
+ console.log(" topogram generator policy check --json");
48
+ console.log(" topogram generator policy pin @topogram/generator-react-web@1");
49
+ }
50
+
51
+ /**
52
+ * @param {ReturnType<typeof checkGeneratorPack>} payload
53
+ * @returns {void}
54
+ */
55
+ export function printGeneratorCheck(payload) {
56
+ console.log(payload.ok ? "Generator check passed." : "Generator check found issues.");
57
+ console.log(`Source: ${payload.sourceSpec}`);
58
+ console.log(`Type: ${payload.source}`);
59
+ if (payload.packageName) {
60
+ console.log(`Package: ${payload.packageName}`);
61
+ }
62
+ if (payload.manifestPath) {
63
+ console.log(`Manifest: ${payload.manifestPath}`);
64
+ }
65
+ if (payload.manifest) {
66
+ console.log(`Generator: ${payload.manifest.id}@${payload.manifest.version}`);
67
+ console.log(`Surface: ${payload.manifest.surface}`);
68
+ console.log(`Projection types: ${payload.manifest.projectionTypes.join(", ")}`);
69
+ console.log(`Source mode: ${payload.manifest.source}`);
70
+ }
71
+ console.log("Executes package code: yes (loads adapter and runs smoke generate)");
72
+ console.log("");
73
+ console.log("Checks:");
74
+ for (const check of payload.checks || []) {
75
+ console.log(`- ${check.ok ? "PASS" : "FAIL"} ${check.name}: ${check.message}`);
76
+ }
77
+ if (payload.smoke) {
78
+ console.log("");
79
+ console.log(`Smoke output: ${payload.smoke.files} file(s), ${payload.smoke.artifacts} artifact(s), ${payload.smoke.diagnostics} diagnostic(s)`);
80
+ }
81
+ if ((payload.errors || []).length > 0) {
82
+ console.log("");
83
+ console.log("Errors:");
84
+ for (const error of payload.errors) {
85
+ console.log(`- ${error}`);
86
+ }
87
+ }
88
+ }
89
+
90
+ /**
91
+ * @param {import("../../generator/registry.js").GeneratorManifest} manifest
92
+ * @param {{ source?: string|null, manifestPath?: string|null, packageRoot?: string|null, installed?: boolean, errors?: string[] }} [metadata]
93
+ * @returns {Record<string, any>}
94
+ */
95
+ function generatorManifestSummary(manifest, metadata = {}) {
96
+ const installCommand = manifest.package ? packageGeneratorInstallCommand(manifest.package) : null;
97
+ return {
98
+ id: manifest.id,
99
+ version: manifest.version,
100
+ surface: manifest.surface,
101
+ projectionTypes: manifest.projectionTypes || [],
102
+ inputs: manifest.inputs || [],
103
+ outputs: manifest.outputs || [],
104
+ stack: manifest.stack || {},
105
+ capabilities: manifest.capabilities || {},
106
+ source: manifest.source,
107
+ loadsAdapter: false,
108
+ executesPackageCode: false,
109
+ ...(manifest.profile ? { profile: manifest.profile } : {}),
110
+ ...(manifest.package ? { package: manifest.package } : {}),
111
+ ...(installCommand ? { installCommand } : {}),
112
+ ...(manifest.planned ? { planned: true } : {}),
113
+ installed: metadata.installed !== false,
114
+ manifestPath: metadata.manifestPath || null,
115
+ packageRoot: metadata.packageRoot || null,
116
+ errors: metadata.errors || []
117
+ };
118
+ }
119
+
120
+ /**
121
+ * @param {string} surface
122
+ * @param {string[]} [projectionTypes]
123
+ * @returns {string}
124
+ */
125
+ function exampleProjectionId(surface, projectionTypes = []) {
126
+ const projectionType = projectionTypes[0] || "";
127
+ if (surface === "api") return "proj_api";
128
+ if (surface === "database") return projectionType === "db_contract" ? "proj_db" : "proj_db";
129
+ if (surface === "native") return projectionType === "android_surface" ? "proj_android_surface" : "proj_ios_surface";
130
+ return "proj_web_surface";
131
+ }
132
+
133
+ /**
134
+ * @param {import("../../generator/registry.js").GeneratorManifest} manifest
135
+ * @returns {Record<string, any>}
136
+ */
137
+ function exampleTopologyBinding(manifest) {
138
+ const runtimeId = manifest.surface === "api"
139
+ ? "app_api"
140
+ : manifest.surface === "database"
141
+ ? "app_db"
142
+ : manifest.surface === "native"
143
+ ? "app_ios"
144
+ : "app_web";
145
+ return {
146
+ id: runtimeId,
147
+ kind: manifest.runtimeKinds?.[0] || manifest.surface,
148
+ projection: exampleProjectionId(manifest.surface, manifest.projectionTypes),
149
+ generator: {
150
+ id: manifest.id,
151
+ version: manifest.version,
152
+ ...(manifest.package ? { package: manifest.package } : {})
153
+ }
154
+ };
155
+ }
156
+
157
+ /**
158
+ * @param {string} cwd
159
+ * @returns {string[]}
160
+ */
161
+ function declaredGeneratorPackages(cwd) {
162
+ const packagePath = path.join(cwd, "package.json");
163
+ if (!fs.existsSync(packagePath)) {
164
+ return [];
165
+ }
166
+ const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8"));
167
+ const dependencyBuckets = [
168
+ packageJson.dependencies,
169
+ packageJson.devDependencies,
170
+ packageJson.optionalDependencies,
171
+ packageJson.peerDependencies
172
+ ];
173
+ const packages = new Set();
174
+ for (const dependencies of dependencyBuckets) {
175
+ if (!dependencies || typeof dependencies !== "object" || Array.isArray(dependencies)) {
176
+ continue;
177
+ }
178
+ for (const name of Object.keys(dependencies)) {
179
+ if (name.includes("topogram-generator") || name.startsWith("@topogram/generator-")) {
180
+ packages.add(name);
181
+ }
182
+ }
183
+ }
184
+ return [...packages].sort();
185
+ }
186
+
187
+ /**
188
+ * @param {string} cwd
189
+ * @returns {{ ok: boolean, cwd: string, generators: Record<string, any>[], summary: Record<string, number> }}
190
+ */
191
+ export function buildGeneratorListPayload(cwd) {
192
+ const generators = GENERATOR_MANIFESTS
193
+ .map((manifest) => generatorManifestSummary(manifest))
194
+ .sort((left, right) => left.id.localeCompare(right.id));
195
+ for (const packageName of declaredGeneratorPackages(cwd)) {
196
+ const loaded = loadPackageGeneratorManifest(packageName, cwd);
197
+ if (loaded.manifest) {
198
+ generators.push(generatorManifestSummary(loaded.manifest, {
199
+ installed: true,
200
+ manifestPath: loaded.manifestPath,
201
+ packageRoot: loaded.packageRoot,
202
+ errors: loaded.errors
203
+ }));
204
+ } else {
205
+ const installCommand = packageGeneratorInstallCommand(packageName);
206
+ generators.push({
207
+ id: null,
208
+ version: null,
209
+ surface: null,
210
+ projectionTypes: [],
211
+ inputs: [],
212
+ outputs: [],
213
+ stack: {},
214
+ capabilities: {},
215
+ source: "package",
216
+ package: packageName,
217
+ ...(installCommand ? { installCommand } : {}),
218
+ installed: false,
219
+ manifestPath: loaded.manifestPath,
220
+ packageRoot: loaded.packageRoot,
221
+ errors: loaded.errors
222
+ });
223
+ }
224
+ }
225
+ generators.sort((left, right) => String(left.id || left.package || "").localeCompare(String(right.id || right.package || "")));
226
+ return {
227
+ ok: generators.every((generator) => generator.errors.length === 0),
228
+ cwd,
229
+ generators,
230
+ summary: {
231
+ total: generators.length,
232
+ bundled: generators.filter((generator) => generator.source === "bundled").length,
233
+ package: generators.filter((generator) => generator.source === "package").length,
234
+ installed: generators.filter((generator) => generator.installed).length,
235
+ planned: generators.filter((generator) => generator.planned).length
236
+ }
237
+ };
238
+ }
239
+
240
+ /**
241
+ * @param {string} spec
242
+ * @returns {string}
243
+ */
244
+ function packageNameFromPackageSpec(spec) {
245
+ if (spec.startsWith("@")) {
246
+ const segments = spec.split("/");
247
+ if (segments.length < 2) {
248
+ throw new Error(`Invalid scoped package spec '${spec}'.`);
249
+ }
250
+ const scope = segments[0];
251
+ const nameAndVersion = segments.slice(1).join("/");
252
+ const versionIndex = nameAndVersion.indexOf("@");
253
+ return `${scope}/${versionIndex >= 0 ? nameAndVersion.slice(0, versionIndex) : nameAndVersion}`;
254
+ }
255
+ const versionIndex = spec.indexOf("@");
256
+ return versionIndex >= 0 ? spec.slice(0, versionIndex) : spec;
257
+ }
258
+
259
+ /**
260
+ * @param {string} spec
261
+ * @param {string} cwd
262
+ * @returns {{ ok: boolean, sourceSpec: string, generator: Record<string, any>|null, exampleTopologyBinding: Record<string, any>|null, errors: string[] }}
263
+ */
264
+ export function buildGeneratorShowPayload(spec, cwd) {
265
+ const errors = [];
266
+ if (!spec || spec.startsWith("-")) {
267
+ return {
268
+ ok: false,
269
+ sourceSpec: spec || "",
270
+ generator: null,
271
+ exampleTopologyBinding: null,
272
+ errors: ["Usage: topogram generator show <id-or-package>"]
273
+ };
274
+ }
275
+ const bundled = getGeneratorManifest(spec);
276
+ if (bundled) {
277
+ return {
278
+ ok: true,
279
+ sourceSpec: spec,
280
+ generator: generatorManifestSummary(bundled),
281
+ exampleTopologyBinding: exampleTopologyBinding(bundled),
282
+ errors: []
283
+ };
284
+ }
285
+ let packageName = spec;
286
+ try {
287
+ packageName = packageNameFromPackageSpec(spec);
288
+ } catch (error) {
289
+ errors.push(error instanceof Error ? error.message : String(error));
290
+ }
291
+ if (errors.length === 0) {
292
+ const loaded = loadPackageGeneratorManifest(packageName, cwd);
293
+ if (loaded.manifest) {
294
+ return {
295
+ ok: true,
296
+ sourceSpec: spec,
297
+ generator: generatorManifestSummary(loaded.manifest, {
298
+ installed: true,
299
+ manifestPath: loaded.manifestPath,
300
+ packageRoot: loaded.packageRoot,
301
+ errors: loaded.errors
302
+ }),
303
+ exampleTopologyBinding: exampleTopologyBinding(loaded.manifest),
304
+ errors: []
305
+ };
306
+ }
307
+ errors.push(...loaded.errors);
308
+ }
309
+ return {
310
+ ok: false,
311
+ sourceSpec: spec,
312
+ generator: null,
313
+ exampleTopologyBinding: null,
314
+ errors
315
+ };
316
+ }
317
+
318
+ /**
319
+ * @param {ReturnType<typeof buildGeneratorListPayload>} payload
320
+ * @returns {void}
321
+ */
322
+ export function printGeneratorList(payload) {
323
+ console.log("Topogram generators");
324
+ console.log(`Bundled: ${payload.summary.bundled}; package-backed: ${payload.summary.package}; installed: ${payload.summary.installed}; planned: ${payload.summary.planned}`);
325
+ console.log("");
326
+ for (const generator of payload.generators) {
327
+ const id = generator.id || generator.package || "unknown";
328
+ const status = generator.errors.length > 0
329
+ ? "invalid"
330
+ : generator.planned
331
+ ? "planned"
332
+ : generator.source === "package"
333
+ ? (generator.installed ? "package installed" : "package missing")
334
+ : "bundled";
335
+ const platforms = generator.projectionTypes.join(", ") || "none";
336
+ const stack = Object.values(generator.stack || {}).join(" + ") || "not declared";
337
+ console.log(`- ${id}${generator.version ? `@${generator.version}` : ""} (${generator.surface || "unknown"}, ${status})`);
338
+ console.log(` Source: ${generator.source}`);
339
+ console.log(" Adapter loaded: no");
340
+ console.log(" Executes package code: no");
341
+ if (generator.source === "package") {
342
+ console.log(` Installed: ${generator.installed ? "yes" : "no"}`);
343
+ }
344
+ console.log(` Platforms: ${platforms}`);
345
+ console.log(` Stack: ${stack}`);
346
+ if (generator.package) {
347
+ console.log(` Package: ${generator.package}`);
348
+ }
349
+ if (generator.installCommand) {
350
+ console.log(` Install: ${generator.installCommand}`);
351
+ }
352
+ for (const error of generator.errors || []) {
353
+ console.log(` Error: ${error}`);
354
+ }
355
+ }
356
+ }
357
+
358
+ /**
359
+ * @param {ReturnType<typeof buildGeneratorShowPayload>} payload
360
+ * @returns {void}
361
+ */
362
+ export function printGeneratorShow(payload) {
363
+ if (!payload.ok || !payload.generator) {
364
+ console.log("Generator not found.");
365
+ for (const error of payload.errors || []) {
366
+ console.log(`- ${error}`);
367
+ }
368
+ return;
369
+ }
370
+ const generator = payload.generator;
371
+ console.log(`Generator: ${generator.id}@${generator.version}`);
372
+ console.log(`Surface: ${generator.surface}`);
373
+ console.log(`Source: ${generator.source}${generator.planned ? " (planned)" : ""}`);
374
+ console.log("Adapter loaded: no");
375
+ console.log("Executes package code: no");
376
+ if (generator.source === "package") {
377
+ console.log(`Installed: ${generator.installed ? "yes" : "no"}`);
378
+ }
379
+ if (generator.package) {
380
+ console.log(`Package: ${generator.package}`);
381
+ }
382
+ if (generator.installCommand) {
383
+ console.log(`Install: ${generator.installCommand}`);
384
+ }
385
+ if (generator.manifestPath) {
386
+ console.log(`Manifest: ${generator.manifestPath}`);
387
+ }
388
+ console.log(`Projection types: ${generator.projectionTypes.join(", ") || "none"}`);
389
+ console.log(`Inputs: ${generator.inputs.join(", ") || "none"}`);
390
+ console.log(`Outputs: ${generator.outputs.join(", ") || "none"}`);
391
+ console.log(`Stack: ${Object.entries(generator.stack || {}).map(([key, value]) => `${key}=${value}`).join(", ") || "not declared"}`);
392
+ console.log(`Capabilities: ${Object.entries(generator.capabilities || {}).map(([key, value]) => `${key}=${value}`).join(", ") || "not declared"}`);
393
+ console.log("");
394
+ console.log("Example topology binding:");
395
+ console.log(stableStringify(payload.exampleTopologyBinding));
396
+ }
397
+
398
+
399
+ /**
400
+ * @param {{
401
+ * commandArgs: Record<string, any>,
402
+ * inputPath: string|null|undefined,
403
+ * json: boolean,
404
+ * cwd: string
405
+ * }} context
406
+ * @returns {number}
407
+ */
408
+ export function runGeneratorCommand(context) {
409
+ const { commandArgs, inputPath, json, cwd } = context;
410
+ if (commandArgs.generatorCommand === "check") {
411
+ const payload = checkGeneratorPack(inputPath || "", { cwd });
412
+ if (json) {
413
+ console.log(stableStringify(payload));
414
+ } else {
415
+ printGeneratorCheck(payload);
416
+ }
417
+ return payload.ok ? 0 : 1;
418
+ }
419
+
420
+ if (commandArgs.generatorCommand === "list") {
421
+ const payload = buildGeneratorListPayload(cwd);
422
+ if (json) {
423
+ console.log(stableStringify(payload));
424
+ } else {
425
+ printGeneratorList(payload);
426
+ }
427
+ return payload.ok ? 0 : 1;
428
+ }
429
+
430
+ if (commandArgs.generatorCommand === "show") {
431
+ const payload = buildGeneratorShowPayload(inputPath || "", cwd);
432
+ if (json) {
433
+ console.log(stableStringify(payload));
434
+ } else {
435
+ printGeneratorShow(payload);
436
+ }
437
+ return payload.ok ? 0 : 1;
438
+ }
439
+
440
+ throw new Error(`Unknown generator command '${commandArgs.generatorCommand}'`);
441
+ }
442
+
443
+ export { checkGeneratorPack };
@@ -0,0 +1,170 @@
1
+ // @ts-check
2
+
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+
6
+ import { buildTopogramImportStatus } from "../../../import/provenance.js";
7
+ import { runWorkflow } from "../../../workflows.js";
8
+ import { CLI_PACKAGE_NAME, readInstalledCliPackageVersion } from "../package.js";
9
+ import {
10
+ appendImportAdoptionReceipt,
11
+ importAdoptCommand,
12
+ importProjectCommandPath,
13
+ projectFileHash
14
+ } from "./paths.js";
15
+ import { readImportAdoptionArtifacts } from "./plan.js";
16
+ import { writeRelativeFiles } from "./workspace.js";
17
+
18
+ /**
19
+ * @typedef {Record<string, any>} AnyRecord
20
+ */
21
+
22
+ /**
23
+ * @param {string} outputRoot
24
+ * @param {string[]} writtenFiles
25
+ * @returns {AnyRecord[]}
26
+ */
27
+ export function writtenFileHashesForReceipt(outputRoot, writtenFiles) {
28
+ return (writtenFiles || []).map((relativePath) => {
29
+ const filePath = path.join(outputRoot, relativePath);
30
+ const hash = fs.existsSync(filePath) ? projectFileHash(filePath) : null;
31
+ return {
32
+ path: relativePath,
33
+ sha256: hash?.sha256 || null,
34
+ size: hash?.size || null
35
+ };
36
+ });
37
+ }
38
+
39
+ /**
40
+ * @param {{ artifacts: AnyRecord, selector: string, options: AnyRecord, importStatus: AnyRecord, summary: AnyRecord, writtenFiles: string[], outputRoot: string }} input
41
+ * @returns {AnyRecord}
42
+ */
43
+ export function buildImportAdoptionReceipt({ artifacts, selector, options, importStatus, summary, writtenFiles, outputRoot }) {
44
+ return {
45
+ type: "topogram_import_adoption_receipt",
46
+ version: "0.1",
47
+ timestamp: new Date().toISOString(),
48
+ cli: {
49
+ packageName: CLI_PACKAGE_NAME,
50
+ version: readInstalledCliPackageVersion()
51
+ },
52
+ projectRoot: artifacts.projectRoot,
53
+ topogramRoot: artifacts.topogramRoot,
54
+ selector,
55
+ mode: "write",
56
+ dryRun: false,
57
+ forced: Boolean(options.force),
58
+ reason: options.reason || null,
59
+ sourceProvenance: {
60
+ ok: importStatus.ok,
61
+ status: importStatus.status,
62
+ path: importStatus.path || null,
63
+ changed: importStatus.content?.changed || [],
64
+ added: importStatus.content?.added || [],
65
+ removed: importStatus.content?.removed || []
66
+ },
67
+ promotedCanonicalItems: (summary.promoted_canonical_items || []).map((/** @type {AnyRecord} */ item) => ({
68
+ bundle: item.bundle || null,
69
+ kind: item.kind || null,
70
+ item: item.item || null,
71
+ canonicalRelPath: item.canonical_rel_path || null,
72
+ sourcePath: item.source_path || null,
73
+ changeType: item.change_type || null
74
+ })),
75
+ writtenFiles,
76
+ writtenFileHashes: writtenFileHashesForReceipt(outputRoot, writtenFiles),
77
+ outputRoot
78
+ };
79
+ }
80
+
81
+ /**
82
+ * @param {string} selector
83
+ * @param {string} inputPath
84
+ * @param {{ write?: boolean, dryRun?: boolean, force?: boolean, reason?: string|null, refreshAdopted?: boolean }} [options]
85
+ * @returns {AnyRecord}
86
+ */
87
+ export function buildBrownfieldImportAdoptPayload(selector, inputPath, options = {}) {
88
+ if (!selector) {
89
+ throw new Error("Missing required <selector>. Example: topogram import adopt bundle:task --dry-run");
90
+ }
91
+ if (options.write && options.dryRun) {
92
+ throw new Error("Use either --dry-run or --write, not both.");
93
+ }
94
+ if (options.write && options.force && !options.reason) {
95
+ throw new Error("Forced import adoption writes require --reason <text>.");
96
+ }
97
+ const artifacts = readImportAdoptionArtifacts(inputPath);
98
+ const importStatus = buildTopogramImportStatus(artifacts.projectRoot);
99
+ if (options.write && !options.force && !importStatus.ok) {
100
+ throw new Error(`Refusing to write import adoption because brownfield source provenance is ${importStatus.status}. Run 'topogram import check ${importProjectCommandPath(artifacts.projectRoot)}', review the changed source evidence, rerun import, or pass --force --reason <text> after review.`);
101
+ }
102
+ const result = runWorkflow("reconcile", artifacts.projectRoot, {
103
+ adopt: selector,
104
+ write: Boolean(options.write),
105
+ refreshAdopted: Boolean(options.refreshAdopted)
106
+ });
107
+ const outputRoot = path.resolve(result.defaultOutDir || artifacts.topogramRoot);
108
+ const writtenFiles = options.write ? writeRelativeFiles(outputRoot, result.files || {}) : [];
109
+ const summary = result.summary || {};
110
+ const receipt = options.write
111
+ ? buildImportAdoptionReceipt({ artifacts, selector, options, importStatus, summary, writtenFiles, outputRoot })
112
+ : null;
113
+ const receiptPath = receipt ? appendImportAdoptionReceipt(artifacts.projectRoot, receipt) : null;
114
+ return {
115
+ ok: true,
116
+ projectRoot: artifacts.projectRoot,
117
+ topogramRoot: artifacts.topogramRoot,
118
+ selector,
119
+ dryRun: !options.write,
120
+ write: Boolean(options.write),
121
+ forced: Boolean(options.force),
122
+ reason: options.reason || null,
123
+ outputRoot,
124
+ promotedCanonicalItemCount: (summary.promoted_canonical_items || []).length,
125
+ promotedCanonicalItems: summary.promoted_canonical_items || [],
126
+ writtenFiles,
127
+ receipt,
128
+ receiptPath,
129
+ adoption: summary,
130
+ import: importStatus,
131
+ warnings: options.write && options.force && !importStatus.ok
132
+ ? [`Brownfield source provenance is ${importStatus.status}; adoption write was forced with reason: ${options.reason}.`]
133
+ : [],
134
+ nextCommands: options.write
135
+ ? [
136
+ `topogram import history ${importProjectCommandPath(artifacts.projectRoot)}`,
137
+ `topogram import status ${importProjectCommandPath(artifacts.projectRoot)}`,
138
+ `topogram check ${importProjectCommandPath(artifacts.projectRoot)}`
139
+ ]
140
+ : [
141
+ importAdoptCommand(artifacts.projectRoot, selector, true),
142
+ `topogram import status ${importProjectCommandPath(artifacts.projectRoot)}`
143
+ ]
144
+ };
145
+ }
146
+
147
+ /**
148
+ * @param {AnyRecord} payload
149
+ * @returns {void}
150
+ */
151
+ export function printBrownfieldImportAdopt(payload) {
152
+ console.log(`${payload.dryRun ? "Previewed" : "Applied"} import adoption for ${payload.selector}.`);
153
+ console.log(`Project: ${payload.projectRoot}`);
154
+ console.log(`Promoted canonical items: ${payload.promotedCanonicalItemCount}`);
155
+ console.log(`Written files: ${payload.writtenFiles.length}`);
156
+ if (payload.receiptPath) {
157
+ console.log(`Receipt: ${payload.receiptPath}`);
158
+ }
159
+ if (payload.dryRun) {
160
+ console.log("No files were written. Re-run with --write to promote these candidates.");
161
+ }
162
+ for (const warning of payload.warnings || []) {
163
+ console.log(`Warning: ${warning}`);
164
+ }
165
+ console.log("");
166
+ console.log("Next steps:");
167
+ for (const command of payload.nextCommands) {
168
+ console.log(` ${command}`);
169
+ }
170
+ }