@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,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: ["topogram/**", "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: ["topogram/**"]
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
+ }