@topogram/cli 0.3.64 → 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 (245) hide show
  1. package/package.json +1 -1
  2. package/src/adoption/plan/index.js +703 -0
  3. package/src/adoption/plan.js +12 -703
  4. package/src/agent-ops/query-builders/auth.js +375 -0
  5. package/src/agent-ops/query-builders/change-risk/change-plan.js +123 -0
  6. package/src/agent-ops/query-builders/change-risk/import-plan.js +49 -0
  7. package/src/agent-ops/query-builders/change-risk/maintained.js +286 -0
  8. package/src/agent-ops/query-builders/change-risk/review-packets.js +123 -0
  9. package/src/agent-ops/query-builders/change-risk/risk.js +189 -0
  10. package/src/agent-ops/query-builders/change-risk.js +25 -0
  11. package/src/agent-ops/query-builders/common.js +149 -0
  12. package/src/agent-ops/query-builders/maintained-risk.js +539 -0
  13. package/src/agent-ops/query-builders/maintained-shared.js +120 -0
  14. package/src/agent-ops/query-builders/multi-agent.js +547 -0
  15. package/src/agent-ops/query-builders/projection-impacts.js +514 -0
  16. package/src/agent-ops/query-builders/work-packets.js +417 -0
  17. package/src/agent-ops/query-builders/workflow-context-shared.js +300 -0
  18. package/src/agent-ops/query-builders/workflow-context.js +398 -0
  19. package/src/agent-ops/query-builders/workflow-presets-core.js +676 -0
  20. package/src/agent-ops/query-builders/workflow-presets.js +341 -0
  21. package/src/agent-ops/query-builders.d.ts +26 -26
  22. package/src/agent-ops/query-builders.js +42 -5021
  23. package/src/catalog/constants.js +10 -0
  24. package/src/catalog/copy.js +60 -0
  25. package/src/catalog/diagnostics.js +15 -0
  26. package/src/catalog/entries.js +42 -0
  27. package/src/catalog/files.js +67 -0
  28. package/src/catalog/provenance.js +122 -0
  29. package/src/catalog/source.js +150 -0
  30. package/src/catalog/validation.js +252 -0
  31. package/src/catalog.d.ts +2 -0
  32. package/src/catalog.js +18 -746
  33. package/src/cli/commands/catalog/check.js +31 -0
  34. package/src/cli/commands/catalog/copy.js +59 -0
  35. package/src/cli/commands/catalog/doctor.js +248 -0
  36. package/src/cli/commands/catalog/help.js +21 -0
  37. package/src/cli/commands/catalog/list.js +52 -0
  38. package/src/cli/commands/catalog/runner.js +92 -0
  39. package/src/cli/commands/catalog/shared.js +17 -0
  40. package/src/cli/commands/catalog/show.js +134 -0
  41. package/src/cli/commands/catalog.js +30 -615
  42. package/src/cli/commands/generator-policy/package-info.js +162 -0
  43. package/src/cli/commands/generator-policy/payloads.js +372 -0
  44. package/src/cli/commands/generator-policy/printers.js +159 -0
  45. package/src/cli/commands/generator-policy/runner.js +81 -0
  46. package/src/cli/commands/generator-policy/shared.js +39 -0
  47. package/src/cli/commands/generator-policy.js +15 -783
  48. package/src/cli/commands/import/adopt.js +170 -0
  49. package/src/cli/commands/import/check.js +91 -0
  50. package/src/cli/commands/import/diff.js +84 -0
  51. package/src/cli/commands/import/help.js +47 -0
  52. package/src/cli/commands/import/paths.js +277 -0
  53. package/src/cli/commands/import/plan.js +284 -0
  54. package/src/cli/commands/import/refresh.js +470 -0
  55. package/src/cli/commands/import/status-history.js +196 -0
  56. package/src/cli/commands/import/workspace.js +230 -0
  57. package/src/cli/commands/import.js +33 -1732
  58. package/src/cli/commands/package/constants.js +17 -0
  59. package/src/cli/commands/package/doctor.js +240 -0
  60. package/src/cli/commands/package/help.js +27 -0
  61. package/src/cli/commands/package/lockfile.js +135 -0
  62. package/src/cli/commands/package/npm.js +97 -0
  63. package/src/cli/commands/package/reporting.js +35 -0
  64. package/src/cli/commands/package/runner.js +33 -0
  65. package/src/cli/commands/package/shared.js +9 -0
  66. package/src/cli/commands/package/update-cli.js +252 -0
  67. package/src/cli/commands/package/versions.js +35 -0
  68. package/src/cli/commands/package.js +29 -813
  69. package/src/cli/commands/query/change-plan.js +68 -0
  70. package/src/cli/commands/query/definitions.js +202 -0
  71. package/src/cli/commands/query/import-adopt.js +121 -0
  72. package/src/cli/commands/query/runner/artifacts.js +102 -0
  73. package/src/cli/commands/query/runner/boundaries.js +211 -0
  74. package/src/cli/commands/query/runner/change.js +182 -0
  75. package/src/cli/commands/query/runner/import-adopt.js +111 -0
  76. package/src/cli/commands/query/runner/index.js +31 -0
  77. package/src/cli/commands/query/runner/output.js +12 -0
  78. package/src/cli/commands/query/runner/workflow.js +241 -0
  79. package/src/cli/commands/query/runner.js +3 -0
  80. package/src/cli/commands/query/workflow-context.js +5 -0
  81. package/src/cli/commands/query/workspace.js +274 -0
  82. package/src/cli/commands/query.js +9 -1300
  83. package/src/cli/commands/template/baseline.js +100 -0
  84. package/src/cli/commands/template/check.js +466 -0
  85. package/src/cli/commands/template/constants.js +8 -0
  86. package/src/cli/commands/template/diagnostics.js +26 -0
  87. package/src/cli/commands/template/help.js +28 -0
  88. package/src/cli/commands/template/lifecycle.js +404 -0
  89. package/src/cli/commands/template/list-show.js +287 -0
  90. package/src/cli/commands/template/policy.js +422 -0
  91. package/src/cli/commands/template/shared.js +127 -0
  92. package/src/cli/commands/template/updates.js +352 -0
  93. package/src/cli/commands/template.js +41 -2143
  94. package/src/generator/api/contracts.js +497 -0
  95. package/src/generator/api/metadata.js +221 -0
  96. package/src/generator/api/openapi.js +559 -0
  97. package/src/generator/api/schema.js +124 -0
  98. package/src/generator/api/types.d.ts +98 -0
  99. package/src/generator/api.js +3 -1195
  100. package/src/generator/context/shared/domain-sdlc.js +282 -0
  101. package/src/generator/context/shared/maintained-boundary.js +665 -0
  102. package/src/generator/context/shared/metrics.js +85 -0
  103. package/src/generator/context/shared/primitives.js +64 -0
  104. package/src/generator/context/shared/relationships.js +453 -0
  105. package/src/generator/context/shared/summaries.js +263 -0
  106. package/src/generator/context/shared/types.d.ts +207 -0
  107. package/src/generator/context/shared.d.ts +42 -0
  108. package/src/generator/context/shared.js +80 -1390
  109. package/src/generator/context/slice/core.js +397 -0
  110. package/src/generator/context/slice/sdlc.js +417 -0
  111. package/src/generator/context/slice/ui-packets.js +183 -0
  112. package/src/generator/context/slice.js +2 -859
  113. package/src/generator/registry/index.js +507 -0
  114. package/src/generator/registry.js +18 -504
  115. package/src/generator/runtime/environment/index.js +666 -0
  116. package/src/generator/runtime/environment.js +4 -666
  117. package/src/generator/runtime/runtime-check/index.js +554 -0
  118. package/src/generator/runtime/runtime-check.js +4 -554
  119. package/src/generator/runtime/shared/index.js +572 -0
  120. package/src/generator/runtime/shared.js +19 -570
  121. package/src/generator/shared.d.ts +2 -0
  122. package/src/generator/surfaces/shared.d.ts +3 -0
  123. package/src/generator/widget-conformance/behavior-report.js +258 -0
  124. package/src/generator/widget-conformance/checks.js +371 -0
  125. package/src/generator/widget-conformance/projection-context.js +200 -0
  126. package/src/generator/widget-conformance/report.js +166 -0
  127. package/src/generator/widget-conformance/types.d.ts +121 -0
  128. package/src/generator/widget-conformance.js +3 -824
  129. package/src/import/core/context.d.ts +3 -0
  130. package/src/import/core/contracts.d.ts +1 -0
  131. package/src/import/core/registry.d.ts +4 -0
  132. package/src/import/core/runner/candidates.js +217 -0
  133. package/src/import/core/runner/options.js +22 -0
  134. package/src/import/core/runner/reports.js +50 -0
  135. package/src/import/core/runner/run.js +79 -0
  136. package/src/import/core/runner/tracks.js +150 -0
  137. package/src/import/core/runner/ui-drafts.js +337 -0
  138. package/src/import/core/runner.js +3 -698
  139. package/src/import/core/shared/api-routes.js +221 -0
  140. package/src/import/core/shared/candidates.js +97 -0
  141. package/src/import/core/shared/files.js +177 -0
  142. package/src/import/core/shared/next-app.js +389 -0
  143. package/src/import/core/shared/types.d.ts +51 -0
  144. package/src/import/core/shared/ui-routes.js +230 -0
  145. package/src/import/core/shared.js +60 -861
  146. package/src/new-project/constants.js +128 -0
  147. package/src/new-project/create.js +83 -0
  148. package/src/new-project/json.js +28 -0
  149. package/src/new-project/metadata.js +96 -0
  150. package/src/new-project/package-spec.js +161 -0
  151. package/src/new-project/project-files.js +348 -0
  152. package/src/new-project/template-policy.js +269 -0
  153. package/src/new-project/template-resolution.js +368 -0
  154. package/src/new-project/template-snapshots.js +430 -0
  155. package/src/new-project/template-updates.js +512 -0
  156. package/src/new-project/types.d.ts +83 -0
  157. package/src/new-project.js +6 -2277
  158. package/src/parser.d.ts +87 -1
  159. package/src/parser.js +118 -0
  160. package/src/policy/review-boundaries.d.ts +15 -0
  161. package/src/project-config/index.js +564 -0
  162. package/src/project-config.js +19 -561
  163. package/src/resolver/enrich/acceptance-criterion.js +2 -0
  164. package/src/resolver/enrich/bug.js +2 -0
  165. package/src/resolver/enrich/pitch.js +2 -0
  166. package/src/resolver/enrich/requirement.js +2 -0
  167. package/src/resolver/enrich/task.js +2 -0
  168. package/src/resolver/index.js +19 -2089
  169. package/src/resolver/normalize.js +384 -1
  170. package/src/resolver/plans.js +168 -0
  171. package/src/resolver/projections-api.js +494 -0
  172. package/src/resolver/projections-db.js +133 -0
  173. package/src/resolver/projections-ui.js +317 -0
  174. package/src/resolver/shapes.js +251 -0
  175. package/src/resolver/shared.js +278 -0
  176. package/src/resolver/widgets.js +132 -0
  177. package/src/template-trust/constants.js +62 -0
  178. package/src/template-trust/content.js +258 -0
  179. package/src/template-trust/diff.js +92 -0
  180. package/src/template-trust/policy.js +61 -0
  181. package/src/template-trust/record.js +90 -0
  182. package/src/template-trust/status.js +182 -0
  183. package/src/template-trust.js +24 -687
  184. package/src/text-helpers.d.ts +1 -0
  185. package/src/topogram-types.d.ts +69 -0
  186. package/src/validator/common.js +488 -0
  187. package/src/validator/data-model.js +237 -0
  188. package/src/validator/docs.js +167 -0
  189. package/src/validator/expressions.js +146 -1
  190. package/src/validator/index.d.ts +23 -0
  191. package/src/validator/index.js +32 -3585
  192. package/src/validator/kinds.d.ts +41 -0
  193. package/src/validator/kinds.js +2 -0
  194. package/src/validator/model-helpers.js +46 -0
  195. package/src/validator/per-kind/acceptance-criterion.js +5 -0
  196. package/src/validator/per-kind/bug.js +6 -0
  197. package/src/validator/per-kind/domain.js +15 -2
  198. package/src/validator/per-kind/pitch.js +7 -0
  199. package/src/validator/per-kind/requirement.js +5 -0
  200. package/src/validator/per-kind/task.js +7 -0
  201. package/src/validator/per-kind/widget.js +14 -0
  202. package/src/validator/projections/api-http-async.js +410 -0
  203. package/src/validator/projections/api-http-authz.js +88 -0
  204. package/src/validator/projections/api-http-core.js +205 -0
  205. package/src/validator/projections/api-http-policies.js +339 -0
  206. package/src/validator/projections/api-http-responses.js +233 -0
  207. package/src/validator/projections/api-http.js +44 -0
  208. package/src/validator/projections/db.js +353 -0
  209. package/src/validator/projections/generator-defaults.js +45 -0
  210. package/src/validator/projections/helpers.js +87 -0
  211. package/src/validator/projections/ui-helpers.js +214 -0
  212. package/src/validator/projections/ui-navigation.js +344 -0
  213. package/src/validator/projections/ui-structure.js +364 -0
  214. package/src/validator/projections/ui-widgets.js +493 -0
  215. package/src/validator/projections/ui.js +46 -0
  216. package/src/validator/registry.js +48 -1
  217. package/src/validator/utils.d.ts +20 -0
  218. package/src/validator/utils.js +115 -12
  219. package/src/widget-behavior.d.ts +1 -0
  220. package/src/workflows/import-app/api/collect.js +221 -0
  221. package/src/workflows/import-app/api/openapi.js +257 -0
  222. package/src/workflows/import-app/api/routes.js +327 -0
  223. package/src/workflows/import-app/api/sources.js +22 -0
  224. package/src/workflows/import-app/api.js +2 -797
  225. package/src/workflows/reconcile/adoption-plan/build.js +208 -0
  226. package/src/workflows/reconcile/adoption-plan/dependencies.js +75 -0
  227. package/src/workflows/reconcile/adoption-plan/outputs.js +143 -0
  228. package/src/workflows/reconcile/adoption-plan/paths.js +58 -0
  229. package/src/workflows/reconcile/adoption-plan/projection-patches.js +177 -0
  230. package/src/workflows/reconcile/adoption-plan/reasons.js +107 -0
  231. package/src/workflows/reconcile/adoption-plan.js +30 -740
  232. package/src/workflows/reconcile/auth/closures.js +115 -0
  233. package/src/workflows/reconcile/auth/formatters.js +142 -0
  234. package/src/workflows/reconcile/auth/inference.js +330 -0
  235. package/src/workflows/reconcile/auth/roles.js +122 -0
  236. package/src/workflows/reconcile/auth.js +35 -690
  237. package/src/workflows/reconcile/bundle-core/index.js +600 -0
  238. package/src/workflows/reconcile/bundle-core.js +12 -598
  239. package/src/workflows/reconcile/canonical-surface.js +1 -1
  240. package/src/workflows/reconcile/impacts/adoption-plan.js +192 -0
  241. package/src/workflows/reconcile/impacts/indexes.js +101 -0
  242. package/src/workflows/reconcile/impacts/patches.js +252 -0
  243. package/src/workflows/reconcile/impacts/reports.js +80 -0
  244. package/src/workflows/reconcile/impacts.js +14 -623
  245. package/src/workspace-docs.d.ts +29 -0
@@ -0,0 +1,230 @@
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 {
8
+ collectImportSourceFileRecords,
9
+ TOPOGRAM_IMPORT_FILE,
10
+ writeTopogramImportRecord
11
+ } from "../../../import/provenance.js";
12
+ import { runWorkflow } from "../../../workflows.js";
13
+ import { shellCommandArg } from "../catalog.js";
14
+
15
+ /**
16
+ * @typedef {Record<string, any>} AnyRecord
17
+ */
18
+
19
+ /**
20
+ * @param {string} targetPath
21
+ * @returns {void}
22
+ */
23
+ export function ensureEmptyImportTarget(targetPath) {
24
+ if (!fs.existsSync(targetPath)) {
25
+ fs.mkdirSync(targetPath, { recursive: true });
26
+ return;
27
+ }
28
+ if (!fs.statSync(targetPath).isDirectory()) {
29
+ throw new Error(`Cannot import into non-directory path '${targetPath}'.`);
30
+ }
31
+ const entries = fs.readdirSync(targetPath).filter((/** @type {string} */ entry) => entry !== ".DS_Store");
32
+ if (entries.length > 0) {
33
+ throw new Error(`Refusing to import into non-empty directory '${targetPath}'.`);
34
+ }
35
+ }
36
+
37
+ /**
38
+ * @param {string} outDir
39
+ * @param {Record<string, any>} files
40
+ * @returns {string[]}
41
+ */
42
+ export function writeRelativeFiles(outDir, files) {
43
+ const written = [];
44
+ for (const [relativePath, contents] of Object.entries(files || {})) {
45
+ const normalizedRelativePath = relativePath.replaceAll(path.sep, "/");
46
+ const destination = path.join(outDir, normalizedRelativePath);
47
+ fs.mkdirSync(path.dirname(destination), { recursive: true });
48
+ fs.writeFileSync(destination, typeof contents === "string" ? contents : `${stableStringify(contents)}\n`, "utf8");
49
+ written.push(normalizedRelativePath);
50
+ }
51
+ return written.sort((a, b) => a.localeCompare(b));
52
+ }
53
+
54
+ /**
55
+ * @returns {Record<string, any>}
56
+ */
57
+ function importedProjectConfig() {
58
+ return {
59
+ version: "0.1",
60
+ outputs: {
61
+ maintained_app: {
62
+ path: "./app",
63
+ ownership: "maintained"
64
+ }
65
+ },
66
+ topology: {
67
+ runtimes: []
68
+ }
69
+ };
70
+ }
71
+
72
+ /**
73
+ * @param {string} sourceRoot
74
+ * @param {string} targetRoot
75
+ * @param {ReturnType<typeof runWorkflow>["summary"]} importSummary
76
+ * @returns {string}
77
+ */
78
+ function importedWorkspaceReadme(sourceRoot, targetRoot, importSummary) {
79
+ return [
80
+ "# Imported Topogram Workspace",
81
+ "",
82
+ "This workspace was created from a brownfield app import.",
83
+ "",
84
+ `- Imported source: \`${sourceRoot}\``,
85
+ `- Target workspace: \`${targetRoot}\``,
86
+ `- Tracks: ${(importSummary.tracks || []).join(", ") || "none"}`,
87
+ `- Provenance: \`${TOPOGRAM_IMPORT_FILE}\``,
88
+ "",
89
+ "Imported Topogram artifacts are project-owned after creation. Edit them directly, promote candidates deliberately, and run `topogram check` before generation or maintained-app work.",
90
+ "",
91
+ "Useful commands:",
92
+ "",
93
+ "```sh",
94
+ "topogram import check",
95
+ "topogram check",
96
+ "topogram query import-plan ./topogram",
97
+ "```",
98
+ ""
99
+ ].join("\n");
100
+ }
101
+
102
+ /**
103
+ * @param {Record<string, any>} summary
104
+ * @returns {Record<string, number>}
105
+ */
106
+ export function importCandidateCounts(summary) {
107
+ const candidates = summary.candidates || {};
108
+ return {
109
+ dbEntities: candidates.db?.entities?.length || 0,
110
+ dbEnums: candidates.db?.enums?.length || 0,
111
+ apiCapabilities: candidates.api?.capabilities?.length || 0,
112
+ apiRoutes: candidates.api?.routes?.length || 0,
113
+ uiScreens: candidates.ui?.screens?.length || 0,
114
+ uiRoutes: candidates.ui?.routes?.length || 0,
115
+ uiWidgets: candidates.ui?.widgets?.length || candidates.ui?.components?.length || 0,
116
+ workflows: candidates.workflows?.workflows?.length || 0,
117
+ verifications: candidates.verification?.verifications?.length || 0
118
+ };
119
+ }
120
+
121
+ /**
122
+ * @param {string} rootPath
123
+ * @returns {number}
124
+ */
125
+ export function countFilesRecursive(rootPath) {
126
+ if (!fs.existsSync(rootPath)) {
127
+ return 0;
128
+ }
129
+ let count = 0;
130
+ for (const entry of fs.readdirSync(rootPath, { withFileTypes: true })) {
131
+ const childPath = path.join(rootPath, entry.name);
132
+ if (entry.isDirectory()) {
133
+ count += countFilesRecursive(childPath);
134
+ } else if (entry.isFile()) {
135
+ count += 1;
136
+ }
137
+ }
138
+ return count;
139
+ }
140
+
141
+ /**
142
+ * @param {string} sourcePath
143
+ * @param {string} targetPath
144
+ * @param {{ from?: string|null }} [options]
145
+ * @returns {{ ok: boolean, sourcePath: string, targetPath: string, topogramRoot: string, projectConfigPath: string, provenancePath: string, tracks: string[], sourceFiles: number, rawCandidateFiles: number, reconcileFiles: number, writtenFiles: string[], candidateCounts: Record<string, number>, nextCommands: string[] }}
146
+ */
147
+ export function buildBrownfieldImportWorkspacePayload(sourcePath, targetPath, options = {}) {
148
+ const sourceRoot = path.resolve(sourcePath);
149
+ const targetRoot = path.resolve(targetPath);
150
+ if (!fs.existsSync(sourceRoot) || !fs.statSync(sourceRoot).isDirectory()) {
151
+ throw new Error(`Cannot import missing app directory '${sourcePath}'.`);
152
+ }
153
+ if (sourceRoot === targetRoot) {
154
+ throw new Error("Refusing to import into the same directory as the brownfield app.");
155
+ }
156
+ ensureEmptyImportTarget(targetRoot);
157
+
158
+ const topogramRoot = path.join(targetRoot, "topogram");
159
+ fs.mkdirSync(topogramRoot, { recursive: true });
160
+ const sourceFiles = collectImportSourceFileRecords(sourceRoot, { excludeRoots: [targetRoot] });
161
+ const importResult = runWorkflow("import-app", sourceRoot, { from: options.from || null });
162
+ const rawCandidateFiles = writeRelativeFiles(topogramRoot, importResult.files || {});
163
+
164
+ const projectConfigPath = path.join(targetRoot, "topogram.project.json");
165
+ fs.writeFileSync(projectConfigPath, `${stableStringify(importedProjectConfig())}\n`, "utf8");
166
+ fs.writeFileSync(path.join(targetRoot, "README.md"), importedWorkspaceReadme(sourceRoot, targetRoot, importResult.summary), "utf8");
167
+
168
+ const reconcileResult = runWorkflow("reconcile", targetRoot, {});
169
+ const reconcileFiles = writeRelativeFiles(topogramRoot, reconcileResult.files || {});
170
+ const candidateCounts = importCandidateCounts(importResult.summary);
171
+ const provenance = writeTopogramImportRecord(targetRoot, {
172
+ sourceRoot,
173
+ ignoredRoots: [targetRoot],
174
+ tracks: importResult.summary.tracks || [],
175
+ findingsCount: importResult.summary.findings_count || 0,
176
+ candidateCounts,
177
+ files: sourceFiles
178
+ });
179
+ const writtenFiles = [
180
+ "README.md",
181
+ "topogram.project.json",
182
+ TOPOGRAM_IMPORT_FILE,
183
+ ...rawCandidateFiles.map((filePath) => `topogram/${filePath}`),
184
+ ...reconcileFiles.map((filePath) => `topogram/${filePath}`)
185
+ ].sort((a, b) => a.localeCompare(b));
186
+ return {
187
+ ok: true,
188
+ sourcePath: sourceRoot,
189
+ targetPath: targetRoot,
190
+ topogramRoot,
191
+ projectConfigPath,
192
+ provenancePath: provenance.path,
193
+ tracks: importResult.summary.tracks || [],
194
+ sourceFiles: sourceFiles.length,
195
+ rawCandidateFiles: rawCandidateFiles.length,
196
+ reconcileFiles: reconcileFiles.length,
197
+ writtenFiles,
198
+ candidateCounts,
199
+ nextCommands: [
200
+ "topogram import check",
201
+ "topogram import plan",
202
+ "topogram import adopt bundle:task --dry-run",
203
+ "topogram import status",
204
+ "topogram check",
205
+ "topogram query import-plan ./topogram"
206
+ ]
207
+ };
208
+ }
209
+
210
+ /**
211
+ * @param {ReturnType<typeof buildBrownfieldImportWorkspacePayload>} payload
212
+ * @returns {void}
213
+ */
214
+ export function printBrownfieldImportWorkspace(payload) {
215
+ console.log(`Imported brownfield app to ${payload.targetPath}.`);
216
+ console.log(`Source: ${payload.sourcePath}`);
217
+ console.log(`Topogram: ${payload.topogramRoot}`);
218
+ console.log(`Project config: ${payload.projectConfigPath}`);
219
+ console.log(`Import provenance: ${payload.provenancePath}`);
220
+ console.log(`Tracked source files: ${payload.sourceFiles}`);
221
+ console.log(`Raw candidate files: ${payload.rawCandidateFiles}`);
222
+ console.log(`Reconcile proposal files: ${payload.reconcileFiles}`);
223
+ console.log("Imported Topogram artifacts are project-owned after creation; source hashes record the app evidence trusted at import time.");
224
+ console.log("");
225
+ console.log("Next steps:");
226
+ console.log(` cd ${shellCommandArg(path.relative(process.cwd(), payload.targetPath) || ".")}`);
227
+ for (const command of payload.nextCommands) {
228
+ console.log(` ${command}`);
229
+ }
230
+ }