@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,41 @@
1
+ export const STATEMENT_KINDS: Set<string>;
2
+ export const IDENTIFIER_PATTERN: RegExp;
3
+ export const DOMAIN_IDENTIFIER_PATTERN: RegExp;
4
+ export const DOMAIN_TAGGABLE_KINDS: Set<string>;
5
+ export const PITCH_IDENTIFIER_PATTERN: RegExp;
6
+ export const REQUIREMENT_IDENTIFIER_PATTERN: RegExp;
7
+ export const ACCEPTANCE_CRITERION_IDENTIFIER_PATTERN: RegExp;
8
+ export const TASK_IDENTIFIER_PATTERN: RegExp;
9
+ export const BUG_IDENTIFIER_PATTERN: RegExp;
10
+ export const DOCUMENT_IDENTIFIER_PATTERN: RegExp;
11
+ export const GLOBAL_STATUSES: Set<string>;
12
+ export const DECISION_STATUSES: Set<string>;
13
+ export const RULE_SEVERITIES: Set<string>;
14
+ export const VERIFICATION_METHODS: Set<string>;
15
+ export const STATUS_SETS_BY_KIND: Record<string, Set<string>>;
16
+ export const PITCH_STATUSES: Set<string>;
17
+ export const REQUIREMENT_STATUSES: Set<string>;
18
+ export const ACCEPTANCE_CRITERION_STATUSES: Set<string>;
19
+ export const TASK_STATUSES: Set<string>;
20
+ export const BUG_STATUSES: Set<string>;
21
+ export const PRIORITY_VALUES: Set<string>;
22
+ export const WORK_TYPES: Set<string>;
23
+ export const BUG_SEVERITIES: Set<string>;
24
+ export const DOC_TYPES: Set<string>;
25
+ export const AUDIENCES: Set<string>;
26
+ export const UI_SCREEN_KINDS: Set<string>;
27
+ export const UI_COLLECTION_PRESENTATIONS: Set<string>;
28
+ export const UI_NAVIGATION_PATTERNS: Set<string>;
29
+ export const UI_REGION_KINDS: Set<string>;
30
+ export const UI_PATTERN_KINDS: Set<string>;
31
+ export const UI_APP_SHELL_KINDS: Set<string>;
32
+ export const UI_WINDOWING_MODES: Set<string>;
33
+ export const UI_STATE_KINDS: Set<string>;
34
+ export const UI_DESIGN_DENSITIES: Set<string>;
35
+ export const UI_DESIGN_TONES: Set<string>;
36
+ export const UI_DESIGN_RADIUS_SCALES: Set<string>;
37
+ export const UI_DESIGN_COLOR_ROLES: Set<string>;
38
+ export const UI_DESIGN_TYPOGRAPHY_ROLES: Set<string>;
39
+ export const UI_DESIGN_ACTION_ROLES: Set<string>;
40
+ export const UI_DESIGN_ACCESSIBILITY_VALUES: Record<string, Set<string>>;
41
+ export const FIELD_SPECS: Record<string, { required: string[]; allowed: string[] }>;
@@ -1,3 +1,5 @@
1
+ // @ts-check
2
+
1
3
  export const STATEMENT_KINDS = new Set([
2
4
  "term",
3
5
  "actor",
@@ -0,0 +1,46 @@
1
+ // @ts-check
2
+
3
+ import {
4
+ blockEntries,
5
+ getFieldValue,
6
+ symbolValues
7
+ } from "./utils.js";
8
+
9
+ /**
10
+ * @param {TopogramStatement} statement
11
+ * @returns {string[]}
12
+ */
13
+ export function statementFieldNames(statement) {
14
+ return blockEntries(getFieldValue(statement, "fields"))
15
+ .map((entry) => entry.items[0])
16
+ .filter((item) => item?.type === "symbol")
17
+ .map((item) => item.value);
18
+ }
19
+
20
+ /**
21
+ * @param {TopogramStatement} statement
22
+ * @param {TopogramRegistry} registry
23
+ * @returns {string[]}
24
+ */
25
+ export function resolveShapeBaseFieldNames(statement, registry) {
26
+ const explicitFieldNames = statementFieldNames(statement);
27
+ if (explicitFieldNames.length > 0) {
28
+ return explicitFieldNames;
29
+ }
30
+
31
+ if (!statement.from) {
32
+ return [];
33
+ }
34
+
35
+ const source = registry.get(statement.from.value);
36
+ if (!source || source.kind !== "entity") {
37
+ return [];
38
+ }
39
+
40
+ const sourceFieldNames = statementFieldNames(source);
41
+ const includeNames = symbolValues(getFieldValue(statement, "include"));
42
+ const excludeNames = new Set(symbolValues(getFieldValue(statement, "exclude")));
43
+ const selectedNames = includeNames.length > 0 ? includeNames.filter((name) => sourceFieldNames.includes(name)) : sourceFieldNames;
44
+
45
+ return selectedNames.filter((fieldName) => !excludeNames.has(fieldName));
46
+ }
@@ -1,3 +1,4 @@
1
+ // @ts-check
1
2
  import {
2
3
  ACCEPTANCE_CRITERION_IDENTIFIER_PATTERN
3
4
  } from "../kinds.js";
@@ -7,6 +8,7 @@ import {
7
8
  symbolValues
8
9
  } from "../utils.js";
9
10
 
11
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement */
10
12
  function validateAcIdentifier(errors, statement) {
11
13
  if (!ACCEPTANCE_CRITERION_IDENTIFIER_PATTERN.test(statement.id)) {
12
14
  pushError(
@@ -17,6 +19,7 @@ function validateAcIdentifier(errors, statement) {
17
19
  }
18
20
  }
19
21
 
22
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
20
23
  function validateRequirementRef(errors, statement, fieldMap, registry) {
21
24
  // Generic reference validator skips `requirement` (it's overloaded with
22
25
  // rule.requirement which is a string condition); validate the kind=requirement
@@ -50,6 +53,7 @@ function validateRequirementRef(errors, statement, fieldMap, registry) {
50
53
  }
51
54
  }
52
55
 
56
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
53
57
  function validateSupersedes(errors, statement, fieldMap, registry) {
54
58
  const field = fieldMap.get("supersedes")?.[0];
55
59
  if (!field) return;
@@ -81,6 +85,7 @@ function validateSupersedes(errors, statement, fieldMap, registry) {
81
85
  }
82
86
  }
83
87
 
88
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
84
89
  export function validateAcceptanceCriterion(errors, statement, fieldMap, registry) {
85
90
  if (statement.kind !== "acceptance_criterion") {
86
91
  return;
@@ -1,3 +1,4 @@
1
+ // @ts-check
1
2
  import {
2
3
  BUG_IDENTIFIER_PATTERN,
3
4
  PRIORITY_VALUES,
@@ -9,6 +10,7 @@ import {
9
10
  symbolValues
10
11
  } from "../utils.js";
11
12
 
13
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement */
12
14
  function validateBugIdentifier(errors, statement) {
13
15
  if (!BUG_IDENTIFIER_PATTERN.test(statement.id)) {
14
16
  pushError(
@@ -19,6 +21,7 @@ function validateBugIdentifier(errors, statement) {
19
21
  }
20
22
  }
21
23
 
24
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
22
25
  function validatePriority(errors, statement, fieldMap) {
23
26
  const field = fieldMap.get("priority")?.[0];
24
27
  if (!field) return;
@@ -35,6 +38,7 @@ function validatePriority(errors, statement, fieldMap) {
35
38
  }
36
39
  }
37
40
 
41
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
38
42
  function validateSeverity(errors, statement, fieldMap) {
39
43
  const field = fieldMap.get("severity")?.[0];
40
44
  if (!field) return;
@@ -51,6 +55,7 @@ function validateSeverity(errors, statement, fieldMap) {
51
55
  }
52
56
  }
53
57
 
58
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
54
59
  function validateFixedInVerificationOnVerified(errors, statement, fieldMap) {
55
60
  // A bug in `verified` status must point at the verification that proved
56
61
  // the fix; this lets release-notes assemble a closed-loop record.
@@ -66,6 +71,7 @@ function validateFixedInVerificationOnVerified(errors, statement, fieldMap) {
66
71
  }
67
72
  }
68
73
 
74
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
69
75
  export function validateBug(errors, statement, fieldMap, registry) {
70
76
  if (statement.kind !== "bug") {
71
77
  return;
@@ -1,3 +1,4 @@
1
+ // @ts-check
1
2
  import {
2
3
  DOMAIN_IDENTIFIER_PATTERN,
3
4
  DOMAIN_TAGGABLE_KINDS
@@ -11,6 +12,7 @@ import {
11
12
  valueAsArray
12
13
  } from "../utils.js";
13
14
 
15
+ /** @param {TopogramToken} value @returns {boolean} */
14
16
  function isStringOrSymbolList(value) {
15
17
  for (const item of valueAsArray(value)) {
16
18
  if (item.type !== "string" && item.type !== "symbol") {
@@ -20,6 +22,7 @@ function isStringOrSymbolList(value) {
20
22
  return true;
21
23
  }
22
24
 
25
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement */
23
26
  function validateDomainIdentifier(errors, statement) {
24
27
  if (statement.kind !== "domain") {
25
28
  return;
@@ -33,6 +36,7 @@ function validateDomainIdentifier(errors, statement) {
33
36
  }
34
37
  }
35
38
 
39
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
36
40
  function validateScopeFields(errors, statement, fieldMap) {
37
41
  if (statement.kind !== "domain") {
38
42
  return;
@@ -50,6 +54,7 @@ function validateScopeFields(errors, statement, fieldMap) {
50
54
  }
51
55
  }
52
56
 
57
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
53
58
  function validateParentDomain(errors, statement, fieldMap, registry) {
54
59
  if (statement.kind !== "domain") {
55
60
  return;
@@ -94,6 +99,7 @@ function validateParentDomain(errors, statement, fieldMap, registry) {
94
99
  }
95
100
  }
96
101
 
102
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
97
103
  function validateOwners(errors, statement, fieldMap, registry) {
98
104
  if (statement.kind !== "domain") {
99
105
  return;
@@ -121,6 +127,7 @@ function validateOwners(errors, statement, fieldMap, registry) {
121
127
  }
122
128
  }
123
129
 
130
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
124
131
  function detectParentDomainCycle(errors, statement, fieldMap, registry) {
125
132
  if (statement.kind !== "domain") {
126
133
  return;
@@ -129,7 +136,9 @@ function detectParentDomainCycle(errors, statement, fieldMap, registry) {
129
136
  if (!field) return;
130
137
 
131
138
  const seen = new Set([statement.id]);
132
- let cursor = registry.get(symbolValue(field.value));
139
+ const parentId = symbolValue(field.value);
140
+ if (!parentId) return;
141
+ let cursor = registry.get(parentId);
133
142
  while (cursor && cursor.kind === "domain") {
134
143
  if (seen.has(cursor.id)) {
135
144
  pushError(
@@ -142,10 +151,13 @@ function detectParentDomainCycle(errors, statement, fieldMap, registry) {
142
151
  seen.add(cursor.id);
143
152
  const parentField = cursor.fields.find((f) => f.key === "parent_domain");
144
153
  if (!parentField) break;
145
- cursor = registry.get(symbolValue(parentField.value));
154
+ const nextParentId = symbolValue(parentField.value);
155
+ if (!nextParentId) break;
156
+ cursor = registry.get(nextParentId);
146
157
  }
147
158
  }
148
159
 
160
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
149
161
  export function validateDomain(errors, statement, fieldMap, registry) {
150
162
  if (statement.kind !== "domain") {
151
163
  return;
@@ -160,6 +172,7 @@ export function validateDomain(errors, statement, fieldMap, registry) {
160
172
  // Cross-kind validator: when *any* statement carries a `domain` field, verify
161
173
  // it resolves to kind=domain. Skipped on the `domain` kind itself (its own
162
174
  // `parent_domain` field handles that case).
175
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
163
176
  export function validateDomainTag(errors, statement, fieldMap, registry) {
164
177
  if (statement.kind === "domain") {
165
178
  return;
@@ -1,3 +1,4 @@
1
+ // @ts-check
1
2
  import {
2
3
  PITCH_IDENTIFIER_PATTERN,
3
4
  PRIORITY_VALUES
@@ -8,6 +9,7 @@ import {
8
9
  symbolValues
9
10
  } from "../utils.js";
10
11
 
12
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement */
11
13
  function validatePitchIdentifier(errors, statement) {
12
14
  if (!PITCH_IDENTIFIER_PATTERN.test(statement.id)) {
13
15
  pushError(
@@ -18,6 +20,7 @@ function validatePitchIdentifier(errors, statement) {
18
20
  }
19
21
  }
20
22
 
23
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
21
24
  function validatePriority(errors, statement, fieldMap) {
22
25
  const field = fieldMap.get("priority")?.[0];
23
26
  if (!field) return;
@@ -34,6 +37,7 @@ function validatePriority(errors, statement, fieldMap) {
34
37
  }
35
38
  }
36
39
 
40
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
37
41
  function validateAppetite(errors, statement, fieldMap) {
38
42
  const field = fieldMap.get("appetite")?.[0];
39
43
  if (!field) return;
@@ -46,6 +50,7 @@ function validateAppetite(errors, statement, fieldMap) {
46
50
  }
47
51
  }
48
52
 
53
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
49
54
  function validateShapingFields(errors, statement, fieldMap) {
50
55
  // When a pitch enters status `shaped`, the appetite, rabbit_holes, and
51
56
  // no_go_areas sections must be filled. This mirrors the Forge pitch
@@ -66,6 +71,7 @@ function validateShapingFields(errors, statement, fieldMap) {
66
71
  }
67
72
  }
68
73
 
74
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
69
75
  function validateDecisionRefs(errors, statement, fieldMap, registry) {
70
76
  const field = fieldMap.get("decisions")?.[0];
71
77
  if (!field) return;
@@ -89,6 +95,7 @@ function validateDecisionRefs(errors, statement, fieldMap, registry) {
89
95
  }
90
96
  }
91
97
 
98
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
92
99
  export function validatePitch(errors, statement, fieldMap, registry) {
93
100
  if (statement.kind !== "pitch") {
94
101
  return;
@@ -1,3 +1,4 @@
1
+ // @ts-check
1
2
  import {
2
3
  REQUIREMENT_IDENTIFIER_PATTERN,
3
4
  PRIORITY_VALUES
@@ -8,6 +9,7 @@ import {
8
9
  symbolValues
9
10
  } from "../utils.js";
10
11
 
12
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement */
11
13
  function validateRequirementIdentifier(errors, statement) {
12
14
  if (!REQUIREMENT_IDENTIFIER_PATTERN.test(statement.id)) {
13
15
  pushError(
@@ -18,6 +20,7 @@ function validateRequirementIdentifier(errors, statement) {
18
20
  }
19
21
  }
20
22
 
23
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
21
24
  function validatePriority(errors, statement, fieldMap) {
22
25
  const field = fieldMap.get("priority")?.[0];
23
26
  if (!field) return;
@@ -34,6 +37,7 @@ function validatePriority(errors, statement, fieldMap) {
34
37
  }
35
38
  }
36
39
 
40
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
37
41
  function validateSupersedes(errors, statement, fieldMap, registry) {
38
42
  const field = fieldMap.get("supersedes")?.[0];
39
43
  if (!field) return;
@@ -65,6 +69,7 @@ function validateSupersedes(errors, statement, fieldMap, registry) {
65
69
  }
66
70
  }
67
71
 
72
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
68
73
  export function validateRequirement(errors, statement, fieldMap, registry) {
69
74
  if (statement.kind !== "requirement") {
70
75
  return;
@@ -1,3 +1,4 @@
1
+ // @ts-check
1
2
  import {
2
3
  TASK_IDENTIFIER_PATTERN,
3
4
  PRIORITY_VALUES,
@@ -9,6 +10,7 @@ import {
9
10
  symbolValues
10
11
  } from "../utils.js";
11
12
 
13
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement */
12
14
  function validateTaskIdentifier(errors, statement) {
13
15
  if (!TASK_IDENTIFIER_PATTERN.test(statement.id)) {
14
16
  pushError(
@@ -19,6 +21,7 @@ function validateTaskIdentifier(errors, statement) {
19
21
  }
20
22
  }
21
23
 
24
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
22
25
  function validatePriority(errors, statement, fieldMap) {
23
26
  const field = fieldMap.get("priority")?.[0];
24
27
  if (!field) return;
@@ -35,6 +38,7 @@ function validatePriority(errors, statement, fieldMap) {
35
38
  }
36
39
  }
37
40
 
41
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
38
42
  function validateWorkType(errors, statement, fieldMap) {
39
43
  const field = fieldMap.get("work_type")?.[0];
40
44
  if (!field) return;
@@ -51,6 +55,7 @@ function validateWorkType(errors, statement, fieldMap) {
51
55
  }
52
56
  }
53
57
 
58
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
54
59
  function validateBlockingPair(errors, statement, fieldMap, registry) {
55
60
  // Self-block guard. Reciprocal `blocks` <-> `blocked_by` resolution is the
56
61
  // resolver's job; here we just guard against trivial cycles.
@@ -69,6 +74,7 @@ function validateBlockingPair(errors, statement, fieldMap, registry) {
69
74
  }
70
75
  }
71
76
 
77
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
72
78
  function validateClaimedByPresence(errors, statement, fieldMap) {
73
79
  // claimed/in-progress/done all require a claimed_by; unclaimed/blocked do not.
74
80
  const statusField = fieldMap.get("status")?.[0];
@@ -84,6 +90,7 @@ function validateClaimedByPresence(errors, statement, fieldMap) {
84
90
  }
85
91
  }
86
92
 
93
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
87
94
  export function validateTask(errors, statement, fieldMap, registry) {
88
95
  if (statement.kind !== "task") {
89
96
  return;
@@ -1,3 +1,4 @@
1
+ // @ts-check
1
2
  import {
2
3
  UI_PATTERN_KINDS,
3
4
  UI_REGION_KINDS
@@ -36,6 +37,7 @@ const WIDGET_BEHAVIOR_KINDS = new Set([
36
37
  "keyboard_navigation"
37
38
  ]);
38
39
 
40
+ /** @type {Record<string, Set<string>>} */
39
41
  const WIDGET_BEHAVIOR_DIRECTIVES = {
40
42
  selection: new Set(["mode", "state", "emits"]),
41
43
  sorting: new Set(["fields", "default"]),
@@ -51,10 +53,12 @@ const WIDGET_BEHAVIOR_DIRECTIVES = {
51
53
  keyboard_navigation: new Set(["scope", "shortcuts"])
52
54
  };
53
55
 
56
+ /** @param {TopogramToken | null | undefined} token @returns {any} */
54
57
  function tokenValue(token) {
55
58
  return token?.value ?? null;
56
59
  }
57
60
 
61
+ /** @param {TopogramToken | null | undefined} token @returns {any[]} */
58
62
  function tokenValues(token) {
59
63
  if (!token) {
60
64
  return [];
@@ -66,6 +70,7 @@ function tokenValues(token) {
66
70
  return value == null ? [] : [value];
67
71
  }
68
72
 
73
+ /** @param {TopogramStatement} statement @returns {Set<any>} */
69
74
  function widgetPropNames(statement) {
70
75
  return new Set(blockEntries(getFieldValue(statement, "props"))
71
76
  .map((entry) => entry.items[0])
@@ -73,6 +78,7 @@ function widgetPropNames(statement) {
73
78
  .map((item) => item.value));
74
79
  }
75
80
 
81
+ /** @param {TopogramStatement} statement @returns {Set<any>} */
76
82
  function widgetEventNames(statement) {
77
83
  return new Set(blockEntries(getFieldValue(statement, "events"))
78
84
  .map((entry) => entry.items[0])
@@ -80,6 +86,7 @@ function widgetEventNames(statement) {
80
86
  .map((item) => item.value));
81
87
  }
82
88
 
89
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
83
90
  function validateWidgetCategory(errors, statement, fieldMap) {
84
91
  const field = fieldMap.get("category")?.[0];
85
92
  if (!field) {
@@ -96,6 +103,7 @@ function validateWidgetCategory(errors, statement, fieldMap) {
96
103
  }
97
104
  }
98
105
 
106
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement */
99
107
  function validateWidgetProps(errors, statement) {
100
108
  for (const entry of blockEntries(getFieldValue(statement, "props"))) {
101
109
  const [name, type, requiredness, ...rest] = entry.items;
@@ -127,6 +135,7 @@ function validateWidgetProps(errors, statement) {
127
135
  }
128
136
  }
129
137
 
138
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramRegistry} registry */
130
139
  function validateWidgetEvents(errors, statement, registry) {
131
140
  for (const entry of blockEntries(getFieldValue(statement, "events"))) {
132
141
  const [eventName, shapeRef] = entry.items;
@@ -151,6 +160,7 @@ function validateWidgetEvents(errors, statement, registry) {
151
160
  }
152
161
  }
153
162
 
163
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement */
154
164
  function validateWidgetSlots(errors, statement) {
155
165
  for (const entry of blockEntries(getFieldValue(statement, "slots"))) {
156
166
  const [slotName, description] = entry.items;
@@ -165,6 +175,7 @@ function validateWidgetSlots(errors, statement) {
165
175
  }
166
176
  }
167
177
 
178
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {string} key @param {Set<string>} allowed @param {string} label */
168
179
  function validateSymbolList(errors, statement, fieldMap, key, allowed, label) {
169
180
  const field = fieldMap.get(key)?.[0];
170
181
  if (!field) {
@@ -178,6 +189,7 @@ function validateSymbolList(errors, statement, fieldMap, key, allowed, label) {
178
189
  }
179
190
  }
180
191
 
192
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramRegistry} registry @param {any} kind @param {any} directive @param {TopogramToken} valueToken @param {Set<any>} eventNames */
181
193
  function validateBehaviorActionReferences(errors, statement, registry, kind, directive, valueToken, eventNames) {
182
194
  for (const actionId of tokenValues(valueToken)) {
183
195
  if (eventNames.has(actionId)) {
@@ -195,6 +207,7 @@ function validateBehaviorActionReferences(errors, statement, registry, kind, dir
195
207
  }
196
208
  }
197
209
 
210
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
198
211
  function validateWidgetBehaviors(errors, statement, fieldMap, registry) {
199
212
  validateSymbolList(errors, statement, fieldMap, "behavior", WIDGET_BEHAVIOR_KINDS, "behavior");
200
213
 
@@ -259,6 +272,7 @@ function validateWidgetBehaviors(errors, statement, fieldMap, registry) {
259
272
  }
260
273
  }
261
274
 
275
+ /** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
262
276
  export function validateWidget(errors, statement, fieldMap, registry) {
263
277
  if (statement.kind !== "widget") {
264
278
  return;