@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,10 @@
1
+ export function attachBundleOperatorHints(...args: any[]): any;
2
+ export function annotateBundlePriorities(...args: any[]): any;
3
+ export function buildAdoptionStatusFiles(...args: any[]): any;
4
+ export function buildAdoptionStatusSummary(...args: any[]): any;
5
+ export function buildPromotedCanonicalItems(...args: any[]): any;
6
+ export function renderBundlePriorityActionsMarkdown(...args: any[]): string;
7
+ export function renderNextBestActionMarkdown(...args: any[]): string;
8
+ export function renderPreviewFollowupMarkdown(...args: any[]): string;
9
+ export function renderPreviewRiskMarkdown(...args: any[]): string;
10
+ export function renderPromotedCanonicalItemsMarkdown(...args: any[]): string;
@@ -0,0 +1,6 @@
1
+ export function buildBundleAdoptionPriorities(...args: any[]): any[];
2
+ export function buildBundleBlockerSummaries(...args: any[]): any[];
3
+ export function buildProjectionReviewGroups(...args: any[]): any[];
4
+ export function buildUiReviewGroups(...args: any[]): any[];
5
+ export function buildWorkflowReviewGroups(...args: any[]): any[];
6
+ export function selectNextBundle(...args: any[]): any;
@@ -0,0 +1,3 @@
1
+ export function buildAgentBrief(inputPath: string, ast: any): any;
2
+ export function formatAgentBrief(payload: any): string;
3
+ export function normalizeAgentTopogramPath(inputPath: string): string;
@@ -0,0 +1,495 @@
1
+ // @ts-check
2
+
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+
6
+ import {
7
+ GENERATOR_POLICY_FILE,
8
+ generatorPolicyDiagnosticsForBindings,
9
+ loadGeneratorPolicy,
10
+ packageBackedGeneratorBindings
11
+ } from "./generator-policy.js";
12
+ import { TOPOGRAM_IMPORT_FILE } from "./import/provenance.js";
13
+ import {
14
+ loadProjectConfig,
15
+ projectConfigOrDefault,
16
+ validateProjectConfig
17
+ } from "./project-config.js";
18
+ import { resolveWorkspace } from "./resolver.js";
19
+ import {
20
+ getTemplateTrustStatus,
21
+ TEMPLATE_TRUST_FILE
22
+ } from "./template-trust.js";
23
+
24
+ /**
25
+ * @typedef {{ path: string, reason: string, required: boolean, exists: boolean }} AgentBriefReadItem
26
+ * @typedef {{ command: string, reason: string, phase: string }} AgentBriefCommand
27
+ * @typedef {{ path: string, ownership: string, rule: string }} AgentBriefOutputBoundary
28
+ * @typedef {{ id: string, title: string, commands: string[], rule: string }} AgentBriefWorkflow
29
+ * @typedef {{ id: string, kind: string, projection: string|null, generator: string|null, uses_api: string|null, uses_database: string|null }} AgentBriefRuntime
30
+ * @typedef {{ path: string, source: string|null, tracks: string[], candidateCounts: Record<string, any>, ownership: string|null }} AgentBriefImport
31
+ * @typedef {{ ok: true, payload: Record<string, any> } | { ok: false, kind: "topogram", validation: any } | { ok: false, kind: "project", validation: any, configPath: string }} AgentBriefResult
32
+ */
33
+
34
+ /**
35
+ * @param {string} inputPath
36
+ * @returns {string}
37
+ */
38
+ export function normalizeAgentTopogramPath(inputPath) {
39
+ const resolved = path.resolve(inputPath || "./topogram");
40
+ if (path.basename(resolved) === "topogram") {
41
+ return resolved;
42
+ }
43
+ const nested = path.join(resolved, "topogram");
44
+ return fs.existsSync(nested) && fs.statSync(nested).isDirectory() ? nested : resolved;
45
+ }
46
+
47
+ /**
48
+ * @param {string} inputPath
49
+ * @returns {string}
50
+ */
51
+ function normalizeProjectRoot(inputPath) {
52
+ const resolved = path.resolve(inputPath || ".");
53
+ if (path.basename(resolved) === "topogram") {
54
+ return path.dirname(resolved);
55
+ }
56
+ if (fs.existsSync(path.join(resolved, "topogram.project.json"))) {
57
+ return resolved;
58
+ }
59
+ if (fs.existsSync(path.join(resolved, "topogram"))) {
60
+ return resolved;
61
+ }
62
+ return path.dirname(normalizeAgentTopogramPath(inputPath));
63
+ }
64
+
65
+ /**
66
+ * @param {string} projectRoot
67
+ * @param {string} targetPath
68
+ * @returns {string}
69
+ */
70
+ function relativeProjectPath(projectRoot, targetPath) {
71
+ const relative = path.relative(projectRoot, targetPath);
72
+ if (!relative || relative === "") {
73
+ return ".";
74
+ }
75
+ return relative.split(path.sep).join("/");
76
+ }
77
+
78
+ /**
79
+ * @param {string} projectRoot
80
+ * @param {string} relativePath
81
+ * @param {string} reason
82
+ * @param {boolean} required
83
+ * @returns {AgentBriefReadItem}
84
+ */
85
+ function readItem(projectRoot, relativePath, reason, required) {
86
+ return {
87
+ path: relativePath,
88
+ reason,
89
+ required,
90
+ exists: fs.existsSync(path.join(projectRoot, relativePath))
91
+ };
92
+ }
93
+
94
+ /**
95
+ * @param {string} command
96
+ * @param {string} reason
97
+ * @param {string} [phase]
98
+ * @returns {AgentBriefCommand}
99
+ */
100
+ function commandItem(command, reason, phase = "first-run") {
101
+ return { command, reason, phase };
102
+ }
103
+
104
+ /**
105
+ * @param {Record<string, any>} config
106
+ * @returns {AgentBriefRuntime[]}
107
+ */
108
+ function summarizeRuntimes(config) {
109
+ const runtimes = Array.isArray(config?.topology?.runtimes) ? config.topology.runtimes : [];
110
+ return runtimes.map((runtime) => ({
111
+ id: String(runtime.id || "unknown"),
112
+ kind: String(runtime.kind || "unknown"),
113
+ projection: typeof runtime.projection === "string" ? runtime.projection : null,
114
+ generator: typeof runtime.generator?.id === "string" ? runtime.generator.id : null,
115
+ uses_api: typeof runtime.uses_api === "string" ? runtime.uses_api : null,
116
+ uses_database: typeof runtime.uses_database === "string" ? runtime.uses_database : null
117
+ }));
118
+ }
119
+
120
+ /**
121
+ * @param {Record<string, any>} config
122
+ * @returns {AgentBriefOutputBoundary[]}
123
+ */
124
+ function summarizeOutputBoundaries(config) {
125
+ const outputs = config?.outputs && typeof config.outputs === "object" && !Array.isArray(config.outputs)
126
+ ? config.outputs
127
+ : {};
128
+ return Object.entries(outputs).map(([name, output]) => {
129
+ const ownership = String(output?.ownership || "unknown");
130
+ const outputPath = String(output?.path || name);
131
+ return {
132
+ path: outputPath,
133
+ ownership,
134
+ rule: ownership === "generated"
135
+ ? `Do not edit ${outputPath}/ directly unless changing output ownership to maintained. Regenerate it from the Topogram.`
136
+ : `Maintained output ${outputPath}/ is project-owned; agents may edit it directly after reading the relevant Topogram packets.`
137
+ };
138
+ });
139
+ }
140
+
141
+ /**
142
+ * @param {string} projectRoot
143
+ * @returns {AgentBriefImport|null}
144
+ */
145
+ function readImportSummary(projectRoot) {
146
+ const importPath = path.join(projectRoot, TOPOGRAM_IMPORT_FILE);
147
+ if (!fs.existsSync(importPath)) {
148
+ return null;
149
+ }
150
+ try {
151
+ const record = JSON.parse(fs.readFileSync(importPath, "utf8"));
152
+ return {
153
+ path: TOPOGRAM_IMPORT_FILE,
154
+ source: typeof record?.source?.path === "string" ? record.source.path : null,
155
+ tracks: Array.isArray(record?.import?.tracks) ? record.import.tracks.map(String) : [],
156
+ candidateCounts: record?.import?.candidateCounts && typeof record.import.candidateCounts === "object"
157
+ ? record.import.candidateCounts
158
+ : {},
159
+ ownership: typeof record?.ownership?.importedArtifacts === "string" ? record.ownership.importedArtifacts : null
160
+ };
161
+ } catch (error) {
162
+ return {
163
+ path: TOPOGRAM_IMPORT_FILE,
164
+ source: null,
165
+ tracks: [],
166
+ candidateCounts: {},
167
+ ownership: `invalid: ${error instanceof Error ? error.message : String(error)}`
168
+ };
169
+ }
170
+ }
171
+
172
+ /**
173
+ * @param {Record<string, any>} config
174
+ * @param {boolean} hasImportRecord
175
+ * @returns {AgentBriefWorkflow[]}
176
+ */
177
+ function buildWorkflows(config, hasImportRecord) {
178
+ const workflows = [
179
+ {
180
+ id: "greenfield-generated",
181
+ title: "Generated project loop",
182
+ commands: [
183
+ "npm run agent:brief",
184
+ "npm run check",
185
+ "npm run generate",
186
+ "npm run verify"
187
+ ],
188
+ rule: "Edit the Topogram first, then regenerate generated-owned outputs."
189
+ },
190
+ {
191
+ id: "widget-first-ui",
192
+ title: "Widget-first UI loop",
193
+ commands: [
194
+ "topogram query list --json",
195
+ "topogram query show widget-behavior",
196
+ "topogram widget check --json",
197
+ "topogram widget behavior --json",
198
+ "topogram emit ui-widget-contract --json"
199
+ ],
200
+ rule: "Use focused widget and surface packets before editing UI code."
201
+ },
202
+ {
203
+ id: "template-update",
204
+ title: "Template update loop",
205
+ commands: [
206
+ "npm run source:status",
207
+ "npm run template:explain",
208
+ "npm run template:update:recommend",
209
+ "npm run template:update:check"
210
+ ],
211
+ rule: "Local Topogram files are project-owned after edits; review update plans before applying template changes."
212
+ }
213
+ ];
214
+ if (config?.implementation) {
215
+ workflows.push({
216
+ id: "executable-template",
217
+ title: "Executable template review loop",
218
+ commands: [
219
+ "npm run trust:status",
220
+ "npm run trust:diff",
221
+ "npm run template:policy:explain",
222
+ "topogram trust template"
223
+ ],
224
+ rule: "Review implementation code before refreshing trust. The brief does not execute implementation providers."
225
+ });
226
+ }
227
+ if (hasImportRecord) {
228
+ workflows.push({
229
+ id: "brownfield-import",
230
+ title: "Brownfield import adoption loop",
231
+ commands: [
232
+ "topogram import check .",
233
+ "topogram import plan .",
234
+ "topogram import adopt --list .",
235
+ "topogram import status .",
236
+ "topogram import history . --verify"
237
+ ],
238
+ rule: "Imported Topogram files are editable after adoption; source hashes record trusted import evidence."
239
+ });
240
+ }
241
+ return workflows;
242
+ }
243
+
244
+ /**
245
+ * @param {string} projectRoot
246
+ * @param {Record<string, any>} config
247
+ * @param {Record<string, any>} trust
248
+ * @param {Record<string, any>|null} importSummary
249
+ * @param {Record<string, any>} generatorPolicy
250
+ * @returns {string[]}
251
+ */
252
+ function buildWarnings(projectRoot, config, trust, importSummary, generatorPolicy) {
253
+ /** @type {string[]} */
254
+ const warnings = [];
255
+ if (config?.implementation) {
256
+ warnings.push("implementation/ exists. Review executable implementation code before generation and before refreshing trust.");
257
+ }
258
+ if (trust?.requiresTrust && !trust?.ok) {
259
+ warnings.push(`${TEMPLATE_TRUST_FILE} does not currently match implementation/. Run trust status/diff and review code before trusting.`);
260
+ }
261
+ if (generatorPolicy?.diagnostics?.errors > 0) {
262
+ warnings.push(`${GENERATOR_POLICY_FILE} has generator policy errors. Fix policy before generating.`);
263
+ }
264
+ if (summarizeOutputBoundaries(config).some((output) => output.ownership === "generated")) {
265
+ warnings.push("Generated-owned outputs are replaceable by Topogram; do not make lasting edits under generated output paths.");
266
+ }
267
+ if (importSummary) {
268
+ warnings.push(`${TOPOGRAM_IMPORT_FILE} is present. Treat imported Topogram artifacts as project-owned after adoption; hashes are import evidence.`);
269
+ }
270
+ if (!fs.existsSync(path.join(projectRoot, "AGENTS.md"))) {
271
+ warnings.push("AGENTS.md is missing. Use this command as the current agent guidance source.");
272
+ }
273
+ return warnings;
274
+ }
275
+
276
+ /**
277
+ * @param {string} inputPath
278
+ * @param {Record<string, any>} workspaceAst
279
+ * @returns {AgentBriefResult}
280
+ */
281
+ export function buildAgentBrief(inputPath, workspaceAst) {
282
+ const topogramRoot = normalizeAgentTopogramPath(inputPath);
283
+ const projectRoot = normalizeProjectRoot(inputPath);
284
+ const resolved = resolveWorkspace(workspaceAst);
285
+ if (!resolved.ok) {
286
+ return { ok: false, kind: "topogram", validation: resolved.validation };
287
+ }
288
+
289
+ const explicitProjectConfig = loadProjectConfig(projectRoot) || loadProjectConfig(topogramRoot) || loadProjectConfig(inputPath);
290
+ const projectConfigInfo = explicitProjectConfig || projectConfigOrDefault(projectRoot, resolved.graph, null);
291
+ const projectConfigValidation = projectConfigInfo
292
+ ? validateProjectConfig(projectConfigInfo.config, resolved.graph, { configDir: projectConfigInfo.configDir })
293
+ : { ok: true, errors: [] };
294
+ if (!projectConfigValidation.ok) {
295
+ return {
296
+ ok: false,
297
+ kind: "project",
298
+ validation: projectConfigValidation,
299
+ configPath: projectConfigInfo?.configPath || "topogram.project.json"
300
+ };
301
+ }
302
+
303
+ const config = projectConfigInfo?.config || {};
304
+ const configDir = projectConfigInfo?.configDir || projectRoot;
305
+ const template = config.template || {};
306
+ const trust = config.implementation
307
+ ? getTemplateTrustStatus({
308
+ config: config.implementation,
309
+ configPath: projectConfigInfo?.configPath || path.join(configDir, "topogram.project.json"),
310
+ configDir
311
+ }, config)
312
+ : {
313
+ ok: true,
314
+ requiresTrust: false,
315
+ trustPath: path.join(configDir, TEMPLATE_TRUST_FILE),
316
+ trustRecord: null,
317
+ template: null,
318
+ implementation: null,
319
+ content: null,
320
+ issues: []
321
+ };
322
+
323
+ const generatorPolicyInfo = loadGeneratorPolicy(configDir);
324
+ const generatorBindings = packageBackedGeneratorBindings(config);
325
+ const generatorDiagnostics = generatorPolicyDiagnosticsForBindings(generatorPolicyInfo, generatorBindings, "agent-brief");
326
+ const importSummary = readImportSummary(configDir);
327
+
328
+ const topogramReadPath = path.resolve(topogramRoot) === path.resolve(projectRoot) ? "." : "topogram/";
329
+ const readOrder = [
330
+ readItem(projectRoot, "AGENTS.md", "Human-readable first-run guidance generated with this project.", false),
331
+ readItem(projectRoot, "README.md", "Project workflow and template provenance summary.", true),
332
+ readItem(projectRoot, "topogram.project.json", "Topology, outputs, template metadata, generator bindings, and implementation provider settings.", true),
333
+ readItem(projectRoot, "topogram.template-policy.json", "Template trust/update policy for attached templates.", false),
334
+ readItem(projectRoot, GENERATOR_POLICY_FILE, "Package-backed generator policy and allowed scopes.", false),
335
+ readItem(projectRoot, TEMPLATE_TRUST_FILE, "Executable implementation trust record, if the template copied implementation code.", Boolean(config.implementation)),
336
+ readItem(projectRoot, TOPOGRAM_IMPORT_FILE, "Brownfield import provenance and source evidence, if this came from import.", Boolean(importSummary)),
337
+ readItem(projectRoot, topogramReadPath, "Canonical Topogram graph source. Use focused query packets for implementation work.", true)
338
+ ];
339
+
340
+ const firstCommands = [
341
+ commandItem("npm run agent:brief", "Machine-readable current onboarding guidance."),
342
+ commandItem("npm run doctor", "Check local CLI, package, and catalog setup."),
343
+ commandItem("npm run source:status", "See whether template-derived files diverged locally."),
344
+ commandItem("npm run template:explain", "Understand whether the project is template-attached or detached."),
345
+ commandItem("npm run generator:policy:check", "Validate package-backed generator policy before generation."),
346
+ ...(config.implementation ? [
347
+ commandItem("npm run trust:status", "Check executable implementation trust before generation.", "trust")
348
+ ] : []),
349
+ commandItem("npm run check", "Validate Topogram, project config, topology, ownership, trust, and generator policy."),
350
+ commandItem("npm run query:list", "Discover focused agent packets."),
351
+ commandItem("npm run query:show -- widget-behavior", "Read a focused UI/widget packet before UI work.", "focused-context"),
352
+ commandItem("npm run generate", "Write generated-owned runtime/app outputs after validation.", "write"),
353
+ commandItem("npm run verify", "Run generated output verification.", "verify"),
354
+ ...(importSummary ? [
355
+ commandItem("topogram import check .", "Validate imported workspace provenance.", "import"),
356
+ commandItem("topogram import plan .", "Review import adoption plan.", "import"),
357
+ commandItem("topogram import adopt --list .", "List reviewable adoption selectors.", "import"),
358
+ commandItem("topogram import history . --verify", "Verify import history evidence.", "import")
359
+ ] : [])
360
+ ];
361
+
362
+ const generatorPolicy = {
363
+ exists: generatorPolicyInfo.exists,
364
+ path: relativeProjectPath(projectRoot, generatorPolicyInfo.path),
365
+ packageBackedGenerators: generatorBindings.length,
366
+ diagnostics: {
367
+ errors: generatorDiagnostics.filter((diagnostic) => diagnostic.severity === "error").length,
368
+ warnings: generatorDiagnostics.filter((diagnostic) => diagnostic.severity === "warning").length,
369
+ items: generatorDiagnostics
370
+ }
371
+ };
372
+
373
+ const templateSummary = {
374
+ id: template.id || null,
375
+ version: template.version || null,
376
+ source: template.source || null,
377
+ sourceSpec: template.sourceSpec || null,
378
+ requested: template.requested || null,
379
+ includesExecutableImplementation: typeof template.includesExecutableImplementation === "boolean"
380
+ ? template.includesExecutableImplementation
381
+ : Boolean(config.implementation)
382
+ };
383
+
384
+ const payload = {
385
+ type: "agent_brief",
386
+ version: "1",
387
+ project: {
388
+ root: projectRoot,
389
+ topogram: topogramRoot,
390
+ projectConfigPath: projectConfigInfo?.configPath || null,
391
+ packageJson: fs.existsSync(path.join(projectRoot, "package.json")) ? path.join(projectRoot, "package.json") : null
392
+ },
393
+ read_order: readOrder,
394
+ first_commands: firstCommands,
395
+ edit_boundaries: {
396
+ safe_paths: [
397
+ "topogram/**",
398
+ "topogram.project.json",
399
+ "topogram.template-policy.json",
400
+ GENERATOR_POLICY_FILE,
401
+ ...(config.implementation ? ["implementation/** after review and trust status"] : [])
402
+ ],
403
+ output_boundaries: summarizeOutputBoundaries(config),
404
+ rule: "Edit Topogram and policy files first. Avoid generated-owned output paths unless converting them to maintained ownership."
405
+ },
406
+ workflows: buildWorkflows(config, Boolean(importSummary)),
407
+ file_organization: {
408
+ small: ["topogram/actors", "topogram/entities", "topogram/shapes", "topogram/capabilities", "topogram/widgets", "topogram/projections", "topogram/verifications"],
409
+ large: ["topogram/domains/<domain>", "topogram/shared", "topogram/domains/<domain>/widgets", "topogram/domains/<domain>/projections"],
410
+ parserRule: "Folder layout is for humans and agents; Topogram flattens statements into one graph."
411
+ },
412
+ topology: {
413
+ runtimes: summarizeRuntimes(config),
414
+ outputs: summarizeOutputBoundaries(config)
415
+ },
416
+ template: templateSummary,
417
+ trust: {
418
+ ok: Boolean(trust.ok),
419
+ requiresTrust: Boolean(trust.requiresTrust),
420
+ path: trust.trustPath ? relativeProjectPath(projectRoot, trust.trustPath) : TEMPLATE_TRUST_FILE,
421
+ implementation: trust.implementation || null,
422
+ content: trust.content || null,
423
+ issues: trust.issues || []
424
+ },
425
+ generator_policy: generatorPolicy,
426
+ import: importSummary,
427
+ warnings: []
428
+ };
429
+ payload.warnings = buildWarnings(projectRoot, config, payload.trust, importSummary, generatorPolicy);
430
+ return { ok: true, payload };
431
+ }
432
+
433
+ /**
434
+ * @param {Record<string, any>} brief
435
+ * @returns {string}
436
+ */
437
+ export function formatAgentBrief(brief) {
438
+ const lines = [];
439
+ lines.push("Topogram agent brief");
440
+ lines.push(`Project: ${brief.project?.root || "unknown"}`);
441
+ lines.push(`Topogram: ${brief.project?.topogram || "unknown"}`);
442
+ lines.push(`Template: ${brief.template?.id || "none"}${brief.template?.version ? `@${brief.template.version}` : ""}`);
443
+ lines.push(`Implementation trust: ${brief.trust?.requiresTrust ? (brief.trust.ok ? "trusted" : "review required") : "not required"}`);
444
+ lines.push(`Package-backed generators: ${brief.generator_policy?.packageBackedGenerators || 0}`);
445
+ lines.push("");
446
+ lines.push("Read order:");
447
+ for (const item of brief.read_order || []) {
448
+ lines.push(` ${item.exists ? "-" : "- (missing)"} ${item.path} - ${item.reason}`);
449
+ }
450
+ lines.push("");
451
+ lines.push("First commands:");
452
+ for (const item of brief.first_commands || []) {
453
+ lines.push(` - ${item.command} - ${item.reason}`);
454
+ }
455
+ lines.push("");
456
+ lines.push("Edit boundaries:");
457
+ lines.push(` - ${brief.edit_boundaries?.rule || "Edit Topogram first."}`);
458
+ for (const output of brief.edit_boundaries?.output_boundaries || []) {
459
+ lines.push(` - ${output.path}/ (${output.ownership}) - ${output.rule}`);
460
+ }
461
+ lines.push("");
462
+ lines.push("Topology:");
463
+ for (const runtime of brief.topology?.runtimes || []) {
464
+ const edges = [
465
+ runtime.uses_api ? `uses_api=${runtime.uses_api}` : null,
466
+ runtime.uses_database ? `uses_database=${runtime.uses_database}` : null
467
+ ].filter(Boolean).join(", ");
468
+ lines.push(` - ${runtime.id}: ${runtime.kind}${runtime.projection ? ` -> ${runtime.projection}` : ""}${runtime.generator ? ` via ${runtime.generator}` : ""}${edges ? ` (${edges})` : ""}`);
469
+ }
470
+ if ((brief.topology?.runtimes || []).length === 0) {
471
+ lines.push(" - No topology runtimes configured.");
472
+ }
473
+ lines.push("");
474
+ lines.push("Workflows:");
475
+ for (const workflow of brief.workflows || []) {
476
+ lines.push(` - ${workflow.title}: ${workflow.rule}`);
477
+ }
478
+ lines.push("");
479
+ lines.push("Verification gates:");
480
+ lines.push(" - npm run check");
481
+ lines.push(" - topogram widget check --json when UI/widget contracts change");
482
+ lines.push(" - topogram widget behavior --json when widget behavior changes");
483
+ lines.push(" - npm run generate");
484
+ lines.push(" - npm run verify");
485
+ if ((brief.warnings || []).length > 0) {
486
+ lines.push("");
487
+ lines.push("Warnings:");
488
+ for (const warning of brief.warnings) {
489
+ lines.push(` - ${warning}`);
490
+ }
491
+ }
492
+ lines.push("");
493
+ lines.push("Machine-readable source: topogram agent brief --json");
494
+ return `${lines.join("\n")}\n`;
495
+ }