@topogram/cli 0.3.64 → 0.3.66

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 (278) hide show
  1. package/package.json +1 -1
  2. package/src/adoption/plan/index.js +716 -0
  3. package/src/adoption/plan.js +12 -703
  4. package/src/adoption/reporting.js +1 -1
  5. package/src/agent-brief.js +7 -21
  6. package/src/agent-ops/query-builders/auth.js +375 -0
  7. package/src/agent-ops/query-builders/change-risk/change-plan.js +123 -0
  8. package/src/agent-ops/query-builders/change-risk/import-plan.js +49 -0
  9. package/src/agent-ops/query-builders/change-risk/maintained.js +286 -0
  10. package/src/agent-ops/query-builders/change-risk/review-packets.js +123 -0
  11. package/src/agent-ops/query-builders/change-risk/risk.js +189 -0
  12. package/src/agent-ops/query-builders/change-risk.js +25 -0
  13. package/src/agent-ops/query-builders/common.js +149 -0
  14. package/src/agent-ops/query-builders/maintained-risk.js +539 -0
  15. package/src/agent-ops/query-builders/maintained-shared.js +120 -0
  16. package/src/agent-ops/query-builders/multi-agent.js +547 -0
  17. package/src/agent-ops/query-builders/projection-impacts.js +514 -0
  18. package/src/agent-ops/query-builders/work-packets.js +417 -0
  19. package/src/agent-ops/query-builders/workflow-context-shared.js +300 -0
  20. package/src/agent-ops/query-builders/workflow-context.js +398 -0
  21. package/src/agent-ops/query-builders/workflow-presets-core.js +677 -0
  22. package/src/agent-ops/query-builders/workflow-presets.js +341 -0
  23. package/src/agent-ops/query-builders.d.ts +26 -26
  24. package/src/agent-ops/query-builders.js +42 -5021
  25. package/src/archive/jsonl.js +2 -2
  26. package/src/archive/resolver-bridge.js +1 -1
  27. package/src/archive/unarchive.js +2 -1
  28. package/src/catalog/constants.js +10 -0
  29. package/src/catalog/copy.js +65 -0
  30. package/src/catalog/diagnostics.js +15 -0
  31. package/src/catalog/entries.js +42 -0
  32. package/src/catalog/files.js +67 -0
  33. package/src/catalog/provenance.js +123 -0
  34. package/src/catalog/source.js +150 -0
  35. package/src/catalog/validation.js +252 -0
  36. package/src/catalog.d.ts +2 -0
  37. package/src/catalog.js +18 -746
  38. package/src/cli/command-parsers/project.js +3 -0
  39. package/src/cli/command-parsers/shared.js +1 -1
  40. package/src/cli/commands/agent.js +2 -2
  41. package/src/cli/commands/catalog/check.js +31 -0
  42. package/src/cli/commands/catalog/copy.js +59 -0
  43. package/src/cli/commands/catalog/doctor.js +248 -0
  44. package/src/cli/commands/catalog/help.js +21 -0
  45. package/src/cli/commands/catalog/list.js +52 -0
  46. package/src/cli/commands/catalog/runner.js +92 -0
  47. package/src/cli/commands/catalog/shared.js +17 -0
  48. package/src/cli/commands/catalog/show.js +134 -0
  49. package/src/cli/commands/catalog.js +30 -615
  50. package/src/cli/commands/check.js +3 -3
  51. package/src/cli/commands/doctor.js +2 -9
  52. package/src/cli/commands/generator-policy/package-info.js +162 -0
  53. package/src/cli/commands/generator-policy/payloads.js +372 -0
  54. package/src/cli/commands/generator-policy/printers.js +159 -0
  55. package/src/cli/commands/generator-policy/runner.js +81 -0
  56. package/src/cli/commands/generator-policy/shared.js +39 -0
  57. package/src/cli/commands/generator-policy.js +15 -783
  58. package/src/cli/commands/import/adopt.js +170 -0
  59. package/src/cli/commands/import/check.js +91 -0
  60. package/src/cli/commands/import/diff.js +84 -0
  61. package/src/cli/commands/import/help.js +47 -0
  62. package/src/cli/commands/import/paths.js +269 -0
  63. package/src/cli/commands/import/plan.js +292 -0
  64. package/src/cli/commands/import/refresh.js +471 -0
  65. package/src/cli/commands/import/status-history.js +196 -0
  66. package/src/cli/commands/import/workspace.js +233 -0
  67. package/src/cli/commands/import.js +33 -1732
  68. package/src/cli/commands/migrate.js +153 -0
  69. package/src/cli/commands/package/constants.js +17 -0
  70. package/src/cli/commands/package/doctor.js +240 -0
  71. package/src/cli/commands/package/help.js +27 -0
  72. package/src/cli/commands/package/lockfile.js +135 -0
  73. package/src/cli/commands/package/npm.js +97 -0
  74. package/src/cli/commands/package/reporting.js +35 -0
  75. package/src/cli/commands/package/runner.js +33 -0
  76. package/src/cli/commands/package/shared.js +9 -0
  77. package/src/cli/commands/package/update-cli.js +252 -0
  78. package/src/cli/commands/package/versions.js +35 -0
  79. package/src/cli/commands/package.js +29 -813
  80. package/src/cli/commands/query/change-plan.js +68 -0
  81. package/src/cli/commands/query/definitions.js +202 -0
  82. package/src/cli/commands/query/import-adopt.js +121 -0
  83. package/src/cli/commands/query/runner/artifacts.js +102 -0
  84. package/src/cli/commands/query/runner/boundaries.js +211 -0
  85. package/src/cli/commands/query/runner/change.js +182 -0
  86. package/src/cli/commands/query/runner/import-adopt.js +111 -0
  87. package/src/cli/commands/query/runner/index.js +31 -0
  88. package/src/cli/commands/query/runner/output.js +12 -0
  89. package/src/cli/commands/query/runner/workflow.js +241 -0
  90. package/src/cli/commands/query/runner.js +3 -0
  91. package/src/cli/commands/query/workflow-context.js +5 -0
  92. package/src/cli/commands/query/workspace.js +270 -0
  93. package/src/cli/commands/query.js +9 -1300
  94. package/src/cli/commands/source.js +3 -12
  95. package/src/cli/commands/template/baseline.js +100 -0
  96. package/src/cli/commands/template/check.js +467 -0
  97. package/src/cli/commands/template/constants.js +8 -0
  98. package/src/cli/commands/template/diagnostics.js +26 -0
  99. package/src/cli/commands/template/help.js +28 -0
  100. package/src/cli/commands/template/lifecycle.js +404 -0
  101. package/src/cli/commands/template/list-show.js +287 -0
  102. package/src/cli/commands/template/policy.js +422 -0
  103. package/src/cli/commands/template/shared.js +127 -0
  104. package/src/cli/commands/template/updates.js +352 -0
  105. package/src/cli/commands/template-runner.js +6 -6
  106. package/src/cli/commands/template.js +41 -2143
  107. package/src/cli/commands/trust.js +1 -1
  108. package/src/cli/commands/workflow.js +6 -1
  109. package/src/cli/dispatcher.js +6 -1
  110. package/src/cli/help.js +15 -14
  111. package/src/cli/migration-guidance.js +1 -1
  112. package/src/cli/output-safety.js +2 -1
  113. package/src/cli/path-normalization.js +3 -13
  114. package/src/generator/api/contracts.js +497 -0
  115. package/src/generator/api/metadata.js +221 -0
  116. package/src/generator/api/openapi.js +559 -0
  117. package/src/generator/api/schema.js +124 -0
  118. package/src/generator/api/types.d.ts +98 -0
  119. package/src/generator/api.js +3 -1195
  120. package/src/generator/context/domain-page.js +1 -1
  121. package/src/generator/context/shared/domain-sdlc.js +282 -0
  122. package/src/generator/context/shared/maintained-boundary.js +665 -0
  123. package/src/generator/context/shared/metrics.js +85 -0
  124. package/src/generator/context/shared/primitives.js +64 -0
  125. package/src/generator/context/shared/relationships.js +453 -0
  126. package/src/generator/context/shared/summaries.js +263 -0
  127. package/src/generator/context/shared/types.d.ts +207 -0
  128. package/src/generator/context/shared.d.ts +42 -0
  129. package/src/generator/context/shared.js +80 -1390
  130. package/src/generator/context/slice/core.js +397 -0
  131. package/src/generator/context/slice/sdlc.js +417 -0
  132. package/src/generator/context/slice/ui-packets.js +183 -0
  133. package/src/generator/context/slice.js +2 -859
  134. package/src/generator/context/task-mode.js +2 -2
  135. package/src/generator/registry/index.js +507 -0
  136. package/src/generator/registry.js +18 -504
  137. package/src/generator/runtime/environment/index.js +666 -0
  138. package/src/generator/runtime/environment.js +4 -666
  139. package/src/generator/runtime/runtime-check/index.js +554 -0
  140. package/src/generator/runtime/runtime-check.js +4 -554
  141. package/src/generator/runtime/shared/index.js +572 -0
  142. package/src/generator/runtime/shared.js +19 -570
  143. package/src/generator/sdlc/doc-page.js +1 -1
  144. package/src/generator/shared.d.ts +2 -0
  145. package/src/generator/surfaces/databases/lifecycle-shared.js +1 -1
  146. package/src/generator/surfaces/native/swiftui-templates/README.generated.md +1 -1
  147. package/src/generator/surfaces/shared.d.ts +3 -0
  148. package/src/generator/widget-conformance/behavior-report.js +258 -0
  149. package/src/generator/widget-conformance/checks.js +371 -0
  150. package/src/generator/widget-conformance/projection-context.js +200 -0
  151. package/src/generator/widget-conformance/report.js +166 -0
  152. package/src/generator/widget-conformance/types.d.ts +121 -0
  153. package/src/generator/widget-conformance.js +3 -824
  154. package/src/import/core/context.d.ts +3 -0
  155. package/src/import/core/context.js +5 -7
  156. package/src/import/core/contracts.d.ts +1 -0
  157. package/src/import/core/registry.d.ts +4 -0
  158. package/src/import/core/runner/candidates.js +337 -0
  159. package/src/import/core/runner/options.js +22 -0
  160. package/src/import/core/runner/reports.js +51 -0
  161. package/src/import/core/runner/run.js +79 -0
  162. package/src/import/core/runner/tracks.js +150 -0
  163. package/src/import/core/runner/ui-drafts.js +393 -0
  164. package/src/import/core/runner.js +3 -698
  165. package/src/import/core/shared/api-routes.js +221 -0
  166. package/src/import/core/shared/candidates.js +97 -0
  167. package/src/import/core/shared/files.js +177 -0
  168. package/src/import/core/shared/next-app.js +389 -0
  169. package/src/import/core/shared/types.d.ts +51 -0
  170. package/src/import/core/shared/ui-routes.js +230 -0
  171. package/src/import/core/shared.js +60 -861
  172. package/src/new-project/constants.js +128 -0
  173. package/src/new-project/create.js +90 -0
  174. package/src/new-project/json.js +28 -0
  175. package/src/new-project/metadata.js +96 -0
  176. package/src/new-project/package-spec.js +161 -0
  177. package/src/new-project/project-files.js +351 -0
  178. package/src/new-project/template-policy.js +269 -0
  179. package/src/new-project/template-resolution.js +370 -0
  180. package/src/new-project/template-snapshots.js +442 -0
  181. package/src/new-project/template-updates.js +512 -0
  182. package/src/new-project/types.d.ts +83 -0
  183. package/src/new-project.js +6 -2277
  184. package/src/parser.d.ts +87 -1
  185. package/src/parser.js +118 -0
  186. package/src/policy/review-boundaries.d.ts +15 -0
  187. package/src/project-config/index.js +591 -0
  188. package/src/project-config.js +19 -561
  189. package/src/resolver/enrich/acceptance-criterion.js +2 -0
  190. package/src/resolver/enrich/bug.js +2 -0
  191. package/src/resolver/enrich/pitch.js +2 -0
  192. package/src/resolver/enrich/requirement.js +2 -0
  193. package/src/resolver/enrich/task.js +2 -0
  194. package/src/resolver/index.js +19 -2089
  195. package/src/resolver/normalize.js +384 -1
  196. package/src/resolver/plans.js +168 -0
  197. package/src/resolver/projections-api.js +494 -0
  198. package/src/resolver/projections-db.js +133 -0
  199. package/src/resolver/projections-ui.js +317 -0
  200. package/src/resolver/shapes.js +251 -0
  201. package/src/resolver/shared.js +278 -0
  202. package/src/resolver/widgets.js +132 -0
  203. package/src/sdlc/adopt.js +6 -5
  204. package/src/sdlc/paths.js +3 -5
  205. package/src/sdlc/scaffold.js +2 -1
  206. package/src/template-trust/constants.js +62 -0
  207. package/src/template-trust/content.js +258 -0
  208. package/src/template-trust/diff.js +92 -0
  209. package/src/template-trust/policy.js +61 -0
  210. package/src/template-trust/record.js +90 -0
  211. package/src/template-trust/status.js +182 -0
  212. package/src/template-trust.js +24 -687
  213. package/src/text-helpers.d.ts +1 -0
  214. package/src/topogram-types.d.ts +69 -0
  215. package/src/validator/common.js +488 -0
  216. package/src/validator/data-model.js +237 -0
  217. package/src/validator/docs.js +167 -0
  218. package/src/validator/expressions.js +146 -1
  219. package/src/validator/index.d.ts +23 -0
  220. package/src/validator/index.js +32 -3585
  221. package/src/validator/kinds.d.ts +41 -0
  222. package/src/validator/kinds.js +2 -0
  223. package/src/validator/model-helpers.js +46 -0
  224. package/src/validator/per-kind/acceptance-criterion.js +5 -0
  225. package/src/validator/per-kind/bug.js +6 -0
  226. package/src/validator/per-kind/domain.js +15 -2
  227. package/src/validator/per-kind/pitch.js +7 -0
  228. package/src/validator/per-kind/requirement.js +5 -0
  229. package/src/validator/per-kind/task.js +7 -0
  230. package/src/validator/per-kind/widget.js +14 -0
  231. package/src/validator/projections/api-http-async.js +410 -0
  232. package/src/validator/projections/api-http-authz.js +88 -0
  233. package/src/validator/projections/api-http-core.js +205 -0
  234. package/src/validator/projections/api-http-policies.js +339 -0
  235. package/src/validator/projections/api-http-responses.js +233 -0
  236. package/src/validator/projections/api-http.js +44 -0
  237. package/src/validator/projections/db.js +353 -0
  238. package/src/validator/projections/generator-defaults.js +45 -0
  239. package/src/validator/projections/helpers.js +87 -0
  240. package/src/validator/projections/ui-helpers.js +214 -0
  241. package/src/validator/projections/ui-navigation.js +344 -0
  242. package/src/validator/projections/ui-structure.js +364 -0
  243. package/src/validator/projections/ui-widgets.js +493 -0
  244. package/src/validator/projections/ui.js +46 -0
  245. package/src/validator/registry.js +48 -1
  246. package/src/validator/utils.d.ts +20 -0
  247. package/src/validator/utils.js +115 -12
  248. package/src/widget-behavior.d.ts +1 -0
  249. package/src/workflows/import-app/api/collect.js +221 -0
  250. package/src/workflows/import-app/api/openapi.js +257 -0
  251. package/src/workflows/import-app/api/routes.js +327 -0
  252. package/src/workflows/import-app/api/sources.js +22 -0
  253. package/src/workflows/import-app/api.js +2 -797
  254. package/src/workflows/reconcile/adoption-plan/build.js +212 -0
  255. package/src/workflows/reconcile/adoption-plan/dependencies.js +75 -0
  256. package/src/workflows/reconcile/adoption-plan/outputs.js +153 -0
  257. package/src/workflows/reconcile/adoption-plan/paths.js +58 -0
  258. package/src/workflows/reconcile/adoption-plan/projection-patches.js +177 -0
  259. package/src/workflows/reconcile/adoption-plan/reasons.js +107 -0
  260. package/src/workflows/reconcile/adoption-plan.js +30 -740
  261. package/src/workflows/reconcile/auth/closures.js +115 -0
  262. package/src/workflows/reconcile/auth/formatters.js +142 -0
  263. package/src/workflows/reconcile/auth/inference.js +330 -0
  264. package/src/workflows/reconcile/auth/roles.js +122 -0
  265. package/src/workflows/reconcile/auth.js +35 -690
  266. package/src/workflows/reconcile/bundle-core/index.js +600 -0
  267. package/src/workflows/reconcile/bundle-core.js +12 -598
  268. package/src/workflows/reconcile/candidate-model.js +18 -2
  269. package/src/workflows/reconcile/canonical-surface.js +1 -1
  270. package/src/workflows/reconcile/impacts/adoption-plan.js +196 -0
  271. package/src/workflows/reconcile/impacts/indexes.js +105 -0
  272. package/src/workflows/reconcile/impacts/patches.js +252 -0
  273. package/src/workflows/reconcile/impacts/reports.js +80 -0
  274. package/src/workflows/reconcile/impacts.js +14 -623
  275. package/src/workflows/reconcile/renderers.js +41 -6
  276. package/src/workflows/shared.js +5 -11
  277. package/src/workspace-docs.d.ts +29 -0
  278. package/src/workspace-paths.js +328 -0
@@ -0,0 +1,85 @@
1
+ import { stableSortedStrings } from "./primitives.js";
2
+ import { verificationIdsForTarget } from "./relationships.js";
3
+
4
+ /**
5
+ * @param {unknown} value
6
+ * @returns {any}
7
+ */
8
+ export function jsonByteSize(value) {
9
+ return Buffer.byteLength(JSON.stringify(value));
10
+ }
11
+
12
+ /**
13
+ * @param {unknown} value
14
+ * @returns {any}
15
+ */
16
+ export function jsonLineCount(value) {
17
+ return JSON.stringify(value, null, 2).split("\n").length;
18
+ }
19
+
20
+ /**
21
+ * @param {number} part
22
+ * @param {number} whole
23
+ * @returns {any}
24
+ */
25
+ export function percentOf(part, whole) {
26
+ if (!whole) {
27
+ return 0;
28
+ }
29
+ return Number(((part / whole) * 100).toFixed(2));
30
+ }
31
+
32
+ /**
33
+ * @returns {any}
34
+ */
35
+ export function buildDefaultWriteScope() {
36
+ return {
37
+ safe_to_edit: ["topo/**", "candidates/**"],
38
+ generator_owned: ["artifacts/**", "apps/**"],
39
+ human_owned_review_required: ["examples/maintained/proof-app/**"],
40
+ out_of_bounds: [".git/**", "node_modules/**"]
41
+ };
42
+ }
43
+
44
+ /**
45
+ * @param {import("./types.d.ts").ContextGraph} graph
46
+ * @param {Iterable<string>} maintainedFiles
47
+ * @returns {any}
48
+ */
49
+ export function buildMaintainedWriteScope(graph, maintainedFiles = []) {
50
+ return {
51
+ safe_to_edit: stableSortedStrings(maintainedFiles),
52
+ generator_owned: ["artifacts/**", "apps/**"],
53
+ human_owned_review_required: stableSortedStrings([
54
+ ...maintainedFiles,
55
+ "examples/maintained/proof-app/**"
56
+ ]),
57
+ out_of_bounds: ["topo/**"]
58
+ };
59
+ }
60
+
61
+ /**
62
+ * @param {import("./types.d.ts").ContextGraph} graph
63
+ * @param {Iterable<string>} targetIds
64
+ * @param {import("./types.d.ts").VerificationTargetOptions} options
65
+ * @returns {any}
66
+ */
67
+ export function recommendedVerificationTargets(graph, targetIds = [], options = {}) {
68
+ const verificationIds = verificationIdsForTarget(graph, targetIds);
69
+ const base = /** @type {any} */ ({
70
+ verification_ids: verificationIds,
71
+ generated_checks: verificationIds.length > 0 ? ["compile-check", "runtime-check"] : ["compile-check"],
72
+ maintained_app_checks: [],
73
+ rationale: options.rationale || null
74
+ });
75
+
76
+ if (options.includeMaintainedApp) {
77
+ base.maintained_app_checks = [
78
+ "examples/maintained/proof-app/scripts/compile-check.mjs",
79
+ "examples/maintained/proof-app/scripts/smoke.mjs",
80
+ "examples/maintained/proof-app/scripts/runtime-check.mjs"
81
+ ];
82
+ }
83
+
84
+ return base;
85
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @param {Iterable<unknown>} values
3
+ * @returns {any}
4
+ */
5
+ export function stableSortedStrings(values) {
6
+ return [...new Set(Array.from(values || []).filter(Boolean))].sort();
7
+ }
8
+
9
+ /**
10
+ * @param {unknown} value
11
+ * @returns {any}
12
+ */
13
+ export function seamIdHint(value) {
14
+ return String(value || "")
15
+ .trim()
16
+ .toLowerCase()
17
+ .replace(/[^a-z0-9]+/g, "_")
18
+ .replace(/^_+|_+$/g, "") || "maintained_surface";
19
+ }
20
+
21
+ /**
22
+ * @param {unknown} value
23
+ * @returns {any}
24
+ */
25
+ export function titleCaseWords(value) {
26
+ return String(value || "")
27
+ .split(/[_\-\s]+/)
28
+ .filter(Boolean)
29
+ .map(/** @param {string} part */ (part) => part.charAt(0).toUpperCase() + part.slice(1))
30
+ .join(" ");
31
+ }
32
+
33
+ /**
34
+ * @param {any} items
35
+ * @returns {any}
36
+ */
37
+ export function refIds(items) {
38
+ return stableSortedStrings((items || []).map(/** @param {any} item */ (item) => item?.id || item?.target?.id));
39
+ }
40
+
41
+ /**
42
+ * @param {any} items
43
+ * @returns {any}
44
+ */
45
+ export function docIds(items) {
46
+ return stableSortedStrings((items || []).map(/** @param {any} item */ (item) => item?.id));
47
+ }
48
+
49
+ /**
50
+ * @param {any} items
51
+ * @param {any} keyFn
52
+ * @returns {any}
53
+ */
54
+ export function groupBy(items, keyFn) {
55
+ const grouped = /** @type {Record<string, any[]>} */ ({});
56
+ for (const item of items) {
57
+ const key = keyFn(item);
58
+ if (!Object.hasOwn(grouped, key)) {
59
+ grouped[key] = [];
60
+ }
61
+ grouped[key].push(item);
62
+ }
63
+ return grouped;
64
+ }
@@ -0,0 +1,453 @@
1
+ import { groupBy, refIds, stableSortedStrings } from "./primitives.js";
2
+ import { summarizeJourneyDoc, summarizeStatement } from "./summaries.js";
3
+
4
+ /**
5
+ * @param {import("./types.d.ts").ContextGraph} graph
6
+ * @returns {any}
7
+ */
8
+ export function buildIndexes(graph) {
9
+ const statementById = new Map((graph.statements || []).map(/** @param {import("./types.d.ts").ContextStatement} statement */ (statement) => [statement.id, statement]));
10
+ const docsById = new Map((graph.docs || []).map(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => [doc.id, doc]));
11
+ const docsByKind = groupBy(graph.docs || [], /** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.kind || "unknown");
12
+
13
+ return {
14
+ statementById,
15
+ docsById,
16
+ docsByKind
17
+ };
18
+ }
19
+
20
+ /**
21
+ * @param {import("./types.d.ts").ContextGraph} graph
22
+ * @param {(doc: import("./types.d.ts").ContextDoc) => boolean} predicate
23
+ * @returns {any}
24
+ */
25
+ export function relatedDocs(graph, predicate) {
26
+ return (graph.docs || []).filter(predicate);
27
+ }
28
+
29
+ /**
30
+ * @param {import("./types.d.ts").ContextGraph} graph
31
+ * @param {(id: string) => boolean} predicate
32
+ * @returns {any}
33
+ */
34
+ export function verificationsFor(graph, predicate) {
35
+ return stableSortedStrings(
36
+ (graph.byKind.verification || [])
37
+ .filter(/** @param {any} verification */ (verification) => (verification.validates || []).some(/** @param {any} target */ (target) => predicate(target.id)))
38
+ .map(/** @param {any} verification */ (verification) => verification.id)
39
+ );
40
+ }
41
+
42
+ /**
43
+ * @param {import("./types.d.ts").ContextGraph} graph
44
+ * @param {string} capabilityId
45
+ * @returns {any}
46
+ */
47
+ export function relatedJourneysForCapability(graph, capabilityId) {
48
+ return relatedDocs(
49
+ graph,
50
+ /** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.kind === "journey" && (doc.relatedCapabilities || []).includes(capabilityId)
51
+ );
52
+ }
53
+
54
+ /**
55
+ * @param {import("./types.d.ts").ContextGraph} graph
56
+ * @param {string} capabilityId
57
+ * @returns {any}
58
+ */
59
+ export function relatedWorkflowDocsForCapability(graph, capabilityId) {
60
+ return relatedDocs(
61
+ graph,
62
+ /** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.kind === "workflow" && (doc.relatedCapabilities || []).includes(capabilityId)
63
+ );
64
+ }
65
+
66
+ /**
67
+ * @param {import("./types.d.ts").ContextGraph} graph
68
+ * @param {string} targetId
69
+ * @returns {any}
70
+ */
71
+ export function relatedRulesForTarget(graph, targetId) {
72
+ return stableSortedStrings(
73
+ (graph.byKind.rule || [])
74
+ .filter(/** @param {any} rule */ (rule) => (rule.appliesTo || []).some(/** @param {any} target */ (target) => target.id === targetId))
75
+ .map(/** @param {any} rule */ (rule) => rule.id)
76
+ );
77
+ }
78
+
79
+ /**
80
+ * @param {import("./types.d.ts").ContextGraph} graph
81
+ * @param {string} capabilityId
82
+ * @returns {any}
83
+ */
84
+ export function relatedProjectionsForCapability(graph, capabilityId) {
85
+ return stableSortedStrings(
86
+ (graph.byKind.projection || [])
87
+ .filter(/** @param {import("./types.d.ts").ContextProjection} projection */ (projection) => (projection.realizes || []).some(/** @param {any} target */ (target) => target.id === capabilityId))
88
+ .map(/** @param {import("./types.d.ts").ContextProjection} projection */ (projection) => projection.id)
89
+ );
90
+ }
91
+
92
+ /**
93
+ * @param {import("./types.d.ts").ContextGraph} graph
94
+ * @param {string} entityId
95
+ * @returns {any}
96
+ */
97
+ export function relatedCapabilitiesForEntity(graph, entityId) {
98
+ return stableSortedStrings(
99
+ (graph.byKind.capability || [])
100
+ .filter(
101
+ /** @param {import("./types.d.ts").ContextCapability} capability */ (capability) =>
102
+ refIds(capability.reads).includes(entityId) ||
103
+ refIds(capability.creates).includes(entityId) ||
104
+ refIds(capability.updates).includes(entityId) ||
105
+ refIds(capability.deletes).includes(entityId)
106
+ )
107
+ .map(/** @param {import("./types.d.ts").ContextCapability} capability */ (capability) => capability.id)
108
+ );
109
+ }
110
+
111
+ /**
112
+ * @param {import("./types.d.ts").ContextGraph} graph
113
+ * @param {string} entityId
114
+ * @returns {any}
115
+ */
116
+ export function relatedShapesForEntity(graph, entityId) {
117
+ return stableSortedStrings(
118
+ (graph.byKind.shape || [])
119
+ .filter(/** @param {import("./types.d.ts").ContextShape} shape */ (shape) => refIds(shape.derivedFrom).includes(entityId))
120
+ .map(/** @param {import("./types.d.ts").ContextShape} shape */ (shape) => shape.id)
121
+ );
122
+ }
123
+
124
+ /**
125
+ * @param {import("./types.d.ts").ContextGraph} graph
126
+ * @param {string} entityId
127
+ * @returns {any}
128
+ */
129
+ export function relatedProjectionsForEntity(graph, entityId) {
130
+ return stableSortedStrings(
131
+ (graph.byKind.projection || [])
132
+ .filter(/** @param {import("./types.d.ts").ContextProjection} projection */ (projection) => {
133
+ const dbMatches = (projection.dbTables || []).some(/** @param {any} entry */ (entry) => entry.entity?.id === entityId);
134
+ const httpMatches = (projection.http || []).some(/** @param {any} entry */ (entry) => entry.entity?.id === entityId);
135
+ return dbMatches || httpMatches;
136
+ })
137
+ .map(/** @param {import("./types.d.ts").ContextProjection} projection */ (projection) => projection.id)
138
+ );
139
+ }
140
+
141
+ /**
142
+ * @param {import("./types.d.ts").ContextProjection} projection
143
+ * @returns {any}
144
+ */
145
+ export function relatedCapabilitiesForProjection(projection) {
146
+ const ids = [
147
+ ...(projection.realizes || []).map(/** @param {any} entry */ (entry) => entry.id),
148
+ ...(projection.http || []).map(/** @param {any} entry */ (entry) => entry.capability?.id),
149
+ ...(projection.uiActions || []).map(/** @param {any} entry */ (entry) => entry.capability?.id),
150
+ ...(projection.uiVisibility || []).map(/** @param {any} entry */ (entry) => entry.capability?.id),
151
+ ...(projection.uiLookups || []).map(/** @param {any} entry */ (entry) => entry.capability?.id)
152
+ ];
153
+ return stableSortedStrings(ids);
154
+ }
155
+
156
+ /**
157
+ * @param {import("./types.d.ts").ContextProjection} projection
158
+ * @returns {any}
159
+ */
160
+ export function relatedEntitiesForProjection(projection) {
161
+ const ids = [
162
+ ...(projection.dbTables || []).map(/** @param {any} entry */ (entry) => entry.entity?.id),
163
+ ...(projection.dbColumns || []).map(/** @param {any} entry */ (entry) => entry.entity?.id),
164
+ ...(projection.dbRelations || []).map(/** @param {any} entry */ (entry) => entry.source?.id),
165
+ ...(projection.dbRelations || []).map(/** @param {any} entry */ (entry) => entry.target?.id)
166
+ ];
167
+ return stableSortedStrings(ids);
168
+ }
169
+
170
+ /**
171
+ * @param {import("./types.d.ts").ContextProjection} projection
172
+ * @returns {any}
173
+ */
174
+ export function relatedShapesForProjection(projection) {
175
+ const ids = [
176
+ ...(projection.uiScreens || []).map(/** @param {any} entry */ (entry) => entry.viewShape?.id),
177
+ ...(projection.uiScreens || []).map(/** @param {any} entry */ (entry) => entry.editShape?.id),
178
+ ...(projection.uiCollections || []).map(/** @param {any} entry */ (entry) => entry.itemShape?.id),
179
+ ...(projection.httpResponses || []).map(/** @param {any} entry */ (entry) => entry.shape?.id),
180
+ ...(projection.http || []).map(/** @param {any} entry */ (entry) => entry.requestShape?.id)
181
+ ];
182
+ return stableSortedStrings(ids);
183
+ }
184
+
185
+ /**
186
+ * @param {import("./types.d.ts").ContextGraph} graph
187
+ * @param {string} shapeId
188
+ * @returns {any}
189
+ */
190
+ export function relatedProjectionsForShape(graph, shapeId) {
191
+ const directProjectionIds = stableSortedStrings((graph?.byKind?.projection || [])
192
+ .filter(/** @param {import("./types.d.ts").ContextProjection} projection */ (projection) => relatedShapesForProjection(projection).includes(shapeId))
193
+ .map(/** @param {import("./types.d.ts").ContextProjection} projection */ (projection) => projection.id));
194
+ const viaCapabilities = stableSortedStrings((graph?.byKind?.capability || [])
195
+ .filter(/** @param {import("./types.d.ts").ContextCapability} capability */ (capability) => [...(capability.input || []), ...(capability.output || [])].some(/** @param {any} item */ (item) => item.id === shapeId))
196
+ .flatMap(/** @param {import("./types.d.ts").ContextCapability} capability */ (capability) => relatedProjectionsForCapability(graph, capability.id)));
197
+
198
+ return stableSortedStrings([...directProjectionIds, ...viaCapabilities]);
199
+ }
200
+
201
+ /**
202
+ * @param {import("./types.d.ts").ContextGraph} graph
203
+ * @param {string} widgetId
204
+ * @returns {any}
205
+ */
206
+ export function widgetById(graph, widgetId) {
207
+ return (graph?.byKind?.widget || []).find(/** @param {import("./types.d.ts").ContextWidget} widget */ (widget) => widget.id === widgetId) || null;
208
+ }
209
+
210
+ /**
211
+ * @param {import("./types.d.ts").ContextGraph} graph
212
+ * @param {string} projectionId
213
+ * @returns {any}
214
+ */
215
+ export function projectionById(graph, projectionId) {
216
+ return (graph?.byKind?.projection || []).find(/** @param {import("./types.d.ts").ContextProjection} projection */ (projection) => projection.id === projectionId) || null;
217
+ }
218
+
219
+ /**
220
+ * @param {import("./types.d.ts").ContextProjection} projection
221
+ * @returns {any}
222
+ */
223
+ export function realizedProjectionIds(projection) {
224
+ return stableSortedStrings((projection?.realizes || [])
225
+ .filter(/** @param {any} target */ (target) => target.target?.kind === "projection" || String(target.id || "").startsWith("proj_"))
226
+ .map(/** @param {any} target */ (target) => target.id));
227
+ }
228
+
229
+ /**
230
+ * @param {import("./types.d.ts").ContextGraph} graph
231
+ * @param {Iterable<string>} projectionIds
232
+ * @returns {any}
233
+ */
234
+ export function downstreamProjectionIds(graph, projectionIds) {
235
+ const visited = new Set(projectionIds);
236
+ const queue = [...projectionIds];
237
+
238
+ while (queue.length > 0) {
239
+ const currentId = queue.shift();
240
+ for (const projection of graph?.byKind?.projection || []) {
241
+ if (visited.has(projection.id)) {
242
+ continue;
243
+ }
244
+ if (realizedProjectionIds(projection).includes(currentId)) {
245
+ visited.add(projection.id);
246
+ queue.push(projection.id);
247
+ }
248
+ }
249
+ }
250
+
251
+ return stableSortedStrings([...visited]);
252
+ }
253
+
254
+ /**
255
+ * @param {import("./types.d.ts").ContextGraph} graph
256
+ * @param {import("./types.d.ts").ContextProjection} projection
257
+ * @returns {any}
258
+ */
259
+ export function relatedWidgetsForProjection(graph, projection) {
260
+ const directIds = (projection?.widgetBindings || []).map(/** @param {any} entry */ (entry) => entry.widget?.id).filter(Boolean);
261
+ const inheritedIds = realizedProjectionIds(projection)
262
+ .map(/** @param {string} projectionId */ (projectionId) => projectionById(graph, projectionId))
263
+ .filter(Boolean)
264
+ .flatMap(/** @param {any} realizedProjection */ (realizedProjection) => relatedWidgetsForProjection(graph, realizedProjection));
265
+ return stableSortedStrings([...directIds, ...inheritedIds]);
266
+ }
267
+
268
+ /**
269
+ * @param {import("./types.d.ts").ContextWidget} widget
270
+ * @returns {any}
271
+ */
272
+ export function relatedShapesForWidget(widget) {
273
+ if (!widget) return [];
274
+ const ids = [
275
+ ...(widget.events || []).map(/** @param {any} event */ (event) => event.shape?.id),
276
+ ...(widget.lookups || [])
277
+ .filter(/** @param {any} lookup */ (lookup) => lookup?.target?.kind === "shape" || String(lookup?.id || "").startsWith("shape_"))
278
+ .map(/** @param {any} lookup */ (lookup) => lookup.id),
279
+ ...(widget.dependencies || [])
280
+ .filter(/** @param {any} dependency */ (dependency) => referenceKind(dependency) === "shape")
281
+ .map(/** @param {any} dependency */ (dependency) => dependency.id)
282
+ ];
283
+ return stableSortedStrings(ids);
284
+ }
285
+
286
+ /**
287
+ * @param {import("./types.d.ts").ContextGraph} graph
288
+ * @param {string} widgetId
289
+ * @returns {any}
290
+ */
291
+ export function relatedProjectionsForWidget(graph, widgetId) {
292
+ const widget = widgetById(graph, widgetId);
293
+ if (!widget) return [];
294
+ const explicitProjectionIds = stableSortedStrings((graph?.byKind?.projection || [])
295
+ .filter(/** @param {import("./types.d.ts").ContextProjection} projection */ (projection) => (projection.widgetBindings || []).some(/** @param {any} entry */ (entry) => entry.widget?.id === widgetId))
296
+ .map(/** @param {import("./types.d.ts").ContextProjection} projection */ (projection) => projection.id));
297
+ const dependencyProjectionIds = stableSortedStrings((widget.dependencies || []).flatMap(/** @param {any} dependency */ (dependency) => {
298
+ const kind = referenceKind(dependency);
299
+ if (kind === "projection") {
300
+ return [dependency.id];
301
+ }
302
+ if (kind === "capability") {
303
+ return relatedProjectionsForCapability(graph, dependency.id);
304
+ }
305
+ if (kind === "entity") {
306
+ return relatedProjectionsForEntity(graph, dependency.id);
307
+ }
308
+ if (kind === "shape") {
309
+ return relatedProjectionsForShape(graph, dependency.id);
310
+ }
311
+ return [];
312
+ }));
313
+ const widgetPatterns = new Set(widget.patterns || []);
314
+ const widgetRegions = new Set(widget.regions || []);
315
+ const viaUiRegions = stableSortedStrings((graph?.byKind?.projection || [])
316
+ .filter(/** @param {import("./types.d.ts").ContextProjection} projection */ (projection) => (projection.uiScreenRegions || []).some(/** @param {any} region */ (region) =>
317
+ (region.pattern && widgetPatterns.has(region.pattern)) ||
318
+ (region.region && widgetRegions.has(region.region))
319
+ ))
320
+ .map(/** @param {import("./types.d.ts").ContextProjection} projection */ (projection) => projection.id));
321
+
322
+ return downstreamProjectionIds(graph, stableSortedStrings([...explicitProjectionIds, ...dependencyProjectionIds, ...viaUiRegions]));
323
+ }
324
+
325
+ /**
326
+ * @param {import("./types.d.ts").ContextReference} reference
327
+ * @returns {any}
328
+ */
329
+ export function referenceKind(reference) {
330
+ if (reference?.target?.kind) {
331
+ return reference.target.kind;
332
+ }
333
+ const id = String(reference?.id || "");
334
+ const prefix = id.split("_")[0];
335
+ if (prefix === "proj") {
336
+ return "projection";
337
+ }
338
+ if (prefix === "cap") {
339
+ return "capability";
340
+ }
341
+ return prefix || null;
342
+ }
343
+
344
+ /**
345
+ * @param {import("./types.d.ts").ContextGraph} graph
346
+ * @param {Iterable<string>} targetIds
347
+ * @returns {any}
348
+ */
349
+ export function verificationIdsForTarget(graph, targetIds) {
350
+ const set = new Set(targetIds || []);
351
+ return verificationsFor(graph, /** @param {string} targetId */ (targetId) => set.has(targetId));
352
+ }
353
+
354
+ /**
355
+ * @param {import("./types.d.ts").ContextDoc} doc
356
+ * @returns {any}
357
+ */
358
+ export function summarizeDoc(doc) {
359
+ return summarizeJourneyDoc(doc);
360
+ }
361
+
362
+ /**
363
+ * @param {import("./types.d.ts").ContextGraph} graph
364
+ * @param {string} id
365
+ * @returns {any}
366
+ */
367
+ export function summarizeById(graph, id) {
368
+ const statement = (graph.statements || []).find(/** @param {any} item */ (item) => item.id === id);
369
+ if (statement) {
370
+ return summarizeStatement(statement);
371
+ }
372
+
373
+ const doc = (graph.docs || []).find(/** @param {any} item */ (item) => item.id === id);
374
+ return doc ? summarizeDoc(doc) : null;
375
+ }
376
+
377
+ /**
378
+ * @param {import("./types.d.ts").ContextGraph} graph
379
+ * @param {Iterable<string>} ids
380
+ * @returns {any}
381
+ */
382
+ export function summarizeStatementsByIds(graph, ids) {
383
+ return stableSortedStrings(ids).map(/** @param {string} id */ (id) => summarizeById(graph, id)).filter(Boolean);
384
+ }
385
+
386
+ /**
387
+ * @param {import("./types.d.ts").ContextGraph} graph
388
+ * @param {Iterable<string>} ids
389
+ * @returns {any}
390
+ */
391
+ export function summarizeDocsByIds(graph, ids) {
392
+ return stableSortedStrings(ids)
393
+ .map(/** @param {string} id */ (id) => (graph.docs || []).find(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.id === id))
394
+ .filter(Boolean)
395
+ .map(summarizeDoc);
396
+ }
397
+
398
+ /**
399
+ * @param {import("./types.d.ts").ContextGraph} graph
400
+ * @returns {any}
401
+ */
402
+ export function workspaceInventory(graph) {
403
+ return {
404
+ capabilities: stableSortedStrings((graph.byKind.capability || []).map(/** @param {any} item */ (item) => item.id)),
405
+ workflows: stableSortedStrings((graph.docs || []).filter(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.kind === "workflow").map(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.id)),
406
+ journeys: stableSortedStrings((graph.docs || []).filter(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.kind === "journey").map(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.id)),
407
+ entities: stableSortedStrings((graph.byKind.entity || []).map(/** @param {any} item */ (item) => item.id)),
408
+ projections: stableSortedStrings((graph.byKind.projection || []).map(/** @param {any} item */ (item) => item.id)),
409
+ widgets: stableSortedStrings((graph.byKind.widget || []).map(/** @param {any} item */ (item) => item.id)),
410
+ verifications: stableSortedStrings((graph.byKind.verification || []).map(/** @param {any} item */ (item) => item.id)),
411
+ domains: stableSortedStrings((graph.byKind.domain || []).map(/** @param {any} item */ (item) => item.id)),
412
+ pitches: stableSortedStrings((graph.byKind.pitch || []).map(/** @param {any} item */ (item) => item.id)),
413
+ requirements: stableSortedStrings((graph.byKind.requirement || []).map(/** @param {any} item */ (item) => item.id)),
414
+ acceptance_criteria: stableSortedStrings((graph.byKind.acceptance_criterion || []).map(/** @param {any} item */ (item) => item.id)),
415
+ tasks: stableSortedStrings((graph.byKind.task || []).map(/** @param {any} item */ (item) => item.id)),
416
+ bugs: stableSortedStrings((graph.byKind.bug || []).map(/** @param {any} item */ (item) => item.id)),
417
+ documents: stableSortedStrings((graph.docs || []).map(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.id))
418
+ };
419
+ }
420
+
421
+ /**
422
+ * @param {import("./types.d.ts").ContextSelectionOptions} options
423
+ * @returns {any}
424
+ */
425
+ export function ensureContextSelection(options = {}) {
426
+ const selectors = /** @type {any[]} */ ([
427
+ options.capabilityId ? ["capability", options.capabilityId] : null,
428
+ options.workflowId ? ["workflow", options.workflowId] : null,
429
+ options.projectionId ? ["projection", options.projectionId] : null,
430
+ (options.widgetId || options.componentId) ? ["widget", options.widgetId || options.componentId] : null,
431
+ options.entityId ? ["entity", options.entityId] : null,
432
+ options.journeyId ? ["journey", options.journeyId] : null,
433
+ options.surfaceId ? ["surface", options.surfaceId] : null,
434
+ options.domainId ? ["domain", options.domainId] : null,
435
+ options.pitchId ? ["pitch", options.pitchId] : null,
436
+ options.requirementId ? ["requirement", options.requirementId] : null,
437
+ options.acceptanceId ? ["acceptance_criterion", options.acceptanceId] : null,
438
+ options.taskId ? ["task", options.taskId] : null,
439
+ options.bugId ? ["bug", options.bugId] : null,
440
+ options.documentId ? ["document", options.documentId] : null
441
+ ].filter(Boolean));
442
+
443
+ if (selectors.length !== 1) {
444
+ throw new Error(
445
+ "Context selection requires exactly one of --capability, --workflow, --projection, --widget, --entity, --journey, --surface, --domain, --pitch, --requirement, --acceptance, --task, --bug, or --document"
446
+ );
447
+ }
448
+
449
+ return {
450
+ kind: selectors[0][0],
451
+ id: selectors[0][1]
452
+ };
453
+ }