pi-apexlang 0.2.2 → 0.4.0

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 (239) hide show
  1. package/README.md +22 -5
  2. package/THIRD_PARTY_NOTICES.md +2 -2
  3. package/UPSTREAM.json +2 -2
  4. package/docs/assets/overview.en.png +0 -0
  5. package/docs/assets/overview.en.svg +89 -0
  6. package/docs/assets/overview.uk.png +0 -0
  7. package/docs/assets/overview.uk.svg +89 -0
  8. package/docs/en/README.md +41 -0
  9. package/docs/en/architecture.md +73 -0
  10. package/docs/en/getting-started.md +77 -0
  11. package/docs/en/maintenance.md +83 -0
  12. package/docs/en/tool-reference.md +85 -0
  13. package/docs/uk/README.md +41 -0
  14. package/docs/uk/architecture.md +73 -0
  15. package/docs/uk/getting-started.md +77 -0
  16. package/docs/uk/maintenance.md +83 -0
  17. package/docs/uk/tool-reference.md +85 -0
  18. package/extensions/apexlang/index.ts +19 -10
  19. package/extensions/lib/apexlang-cli.d.mts +1 -2
  20. package/extensions/lib/apexlang-cli.mjs +18 -13
  21. package/extensions/lib/apexlang-local-validate.mjs +83 -0
  22. package/extensions/lib/apexlang-local-validator.py +116 -0
  23. package/extensions/lib/apexlang-runtime-validate.mjs +76 -0
  24. package/package.json +2 -1
  25. package/skills/apexlang/APEXlang Skills and Workflows.md +325 -0
  26. package/skills/apexlang/README.md +6 -6
  27. package/skills/apexlang/RELEASE-NOTES.md +2 -2
  28. package/skills/apexlang/SKILL.md +24 -19
  29. package/skills/apexlang/agents/openai.yaml +4 -3
  30. package/skills/apexlang/assets/apex-generation/components.registry.json +1001 -16
  31. package/skills/apexlang/assets/apexlang/domains-catalog.json +6 -1
  32. package/skills/apexlang/assets/component-attributes.json +1924 -180
  33. package/skills/apexlang/assets/component-policies.json +19 -10
  34. package/skills/apexlang/assets/contracts/grammar-semantic-rules.json +134 -0
  35. package/skills/apexlang/assets/contracts/package-layers.json +56 -0
  36. package/skills/apexlang/assets/contracts/page-construction-packs.json +154 -0
  37. package/skills/apexlang/assets/contracts/page-patterns.json +119 -0
  38. package/skills/apexlang/assets/grammar/apexlang.ebnf +11743 -0
  39. package/skills/apexlang/assets/indexes/font-apex-icon-index.json +1699 -0
  40. package/skills/apexlang/assets/routing-catalog-main.json +11 -10
  41. package/skills/apexlang/assets/routing-load-policy.json +35 -9
  42. package/skills/apexlang/assets/rules-mapping.json +110 -2
  43. package/skills/apexlang/assets/rules.catalog.json +1298 -0
  44. package/skills/apexlang/assets/validator-fix-recipes.json +372 -17
  45. package/skills/apexlang/assets/workspace-intelligence.json +7 -10
  46. package/skills/apexlang/manifest.json +268 -12
  47. package/skills/apexlang/references/domains/README.md +1 -1
  48. package/skills/apexlang/references/domains/page-components/buttons.md +2 -2
  49. package/skills/apexlang/references/domains/page-components/page-items.md +3 -3
  50. package/skills/apexlang/references/domains/page-components/regions/region-display-selector/workflow-region-display-selector.md +69 -0
  51. package/skills/apexlang/references/domains/page-components/regions.md +1 -0
  52. package/skills/apexlang/references/domains/template-components/comments.md +61 -0
  53. package/skills/apexlang/references/domains/template-components/registry.md +2 -0
  54. package/skills/apexlang/references/domains/template-components/templates.md +47 -0
  55. package/skills/apexlang/references/domains/template-components/timeline.md +51 -0
  56. package/skills/apexlang/references/ops/one-message-router-contract.md +2 -2
  57. package/skills/apexlang/references/ops/runtime-gates/01-direct-sqlcl-import.md +1 -1
  58. package/skills/apexlang/references/ops/runtime-gates/02-direct-sqlcl-validate-gate.md +1 -1
  59. package/skills/apexlang/references/ops/runtime-gates.md +17 -16
  60. package/skills/apexlang/references/ops/sqlcl-agents/00-connection-gate.md +7 -7
  61. package/skills/apexlang/references/ops/sqlcl.md +7 -8
  62. package/skills/apexlang/references/policies/compiler-prop-map.md +6 -4
  63. package/skills/apexlang/references/policies/governance/00-governance.md +2 -2
  64. package/skills/apexlang/references/policies/memory-bank/00-guard/ai.guard.md +126 -922
  65. package/skills/apexlang/references/policies/memory-bank/20-data/apex.logic.md +3 -3
  66. package/skills/apexlang/references/policies/memory-bank/20-data/db.connection.md +9 -11
  67. package/skills/apexlang/references/policies/memory-bank/30-pages/apex.cards-page.md +95 -0
  68. package/skills/apexlang/references/policies/memory-bank/30-pages/apex.page.md +2 -2
  69. package/skills/apexlang/references/policies/memory-bank/30-pages/apex.smart-filter-search.md +145 -74
  70. package/skills/apexlang/references/policies/memory-bank/40-components/apex.region-interactions.md +9 -2
  71. package/skills/apexlang/references/policies/memory-bank/40-components/apex.region-media.md +6 -5
  72. package/skills/apexlang/references/policies/memory-bank/systemPatterns.md +9 -1
  73. package/skills/apexlang/references/workflows/apex-generation/agents/20-agent-draft.md +51 -232
  74. package/skills/apexlang/references/workflows/apex-generation/agents/30-agent-critique.md +49 -449
  75. package/skills/apexlang/references/workflows/apex-generation/agents/40-agent-revision.md +38 -238
  76. package/skills/apexlang/references/workflows/apex-generation/nlu/nlu-routing-test-matrix.md +8 -2
  77. package/skills/apexlang/references/workflows/apex-generation/nlu/nlu-routing-validation-notes.md +19 -3
  78. package/skills/apexlang/references/workflows/apex-generation/registry.md +15 -1
  79. package/skills/apexlang/references/workflows/apex-generation/templates.md +1 -1
  80. package/skills/apexlang/references/workflows/apex-generation.md +1 -1
  81. package/skills/apexlang/references/workflows/apexlang/apexlang-execution-model.md +5 -5
  82. package/skills/apexlang/references/workflows/apexlang/prompt-contracts.md +81 -10
  83. package/skills/apexlang/references/workflows/apexlang/workflow-create-app-from-fr-and-model.md +18 -7
  84. package/skills/apexlang/release-notes.json +156 -0
  85. package/skills/apexlang/runtime/grammar_contract.mjs +1166 -0
  86. package/skills/apexlang/runtime/internal/python/format_apexlang.py +210 -0
  87. package/skills/apexlang/runtime/internal/python/validate_apexlang.py +14142 -5843
  88. package/skills/apexlang/runtime/internal/python/validator_common.py +2 -0
  89. package/skills/apexlang/runtime/lib/catalogs.mjs +1026 -0
  90. package/skills/apexlang/runtime/lib/common.mjs +35 -0
  91. package/skills/apexlang/runtime/runtime.bundle.mjs +457 -57
  92. package/skills/apexlang/templates/items/combobox/combobox.explicit-defaults.md +1 -1
  93. package/skills/apexlang/templates/items/date-picker/date-picker._common.md +1 -1
  94. package/skills/apexlang/templates/items/date-picker/date-picker.explicit-defaults.md +1 -1
  95. package/skills/apexlang/templates/items/file-upload/file-upload._common.md +30 -24
  96. package/skills/apexlang/templates/items/file-upload/file-upload.compact-template.md +6 -0
  97. package/skills/apexlang/templates/items/file-upload/file-upload.explicit-defaults.md +23 -8
  98. package/skills/apexlang/templates/items/file-upload/file-upload.minimal.md +6 -0
  99. package/skills/apexlang/templates/items/hidden-item/hidden-item._common.md +1 -1
  100. package/skills/apexlang/templates/items/hidden-item/hidden-item.explicit-defaults.md +1 -1
  101. package/skills/apexlang/templates/items/items._common.md +3 -2
  102. package/skills/apexlang/templates/items/list-manager/list-manager.explicit-defaults.md +1 -1
  103. package/skills/apexlang/templates/items/markdown-editor/markdown-editor._common.md +1 -1
  104. package/skills/apexlang/templates/items/markdown-editor/markdown-editor.explicit-defaults.md +1 -1
  105. package/skills/apexlang/templates/items/number-field/number-field._common.md +8 -6
  106. package/skills/apexlang/templates/items/number-field/number-field.explicit-defaults.md +12 -2
  107. package/skills/apexlang/templates/items/popup-lov/popup-lov.explicit-defaults.md +1 -1
  108. package/skills/apexlang/templates/items/rich-text-editor/rich-text-editor._common.md +1 -1
  109. package/skills/apexlang/templates/items/rich-text-editor/rich-text-editor.explicit-defaults.md +1 -1
  110. package/skills/apexlang/templates/items/select-many/standard.md +1 -1
  111. package/skills/apexlang/templates/items/shuttle/shuttle.explicit-defaults.md +1 -1
  112. package/skills/apexlang/templates/items/switch/switch._common.md +8 -8
  113. package/skills/apexlang/templates/items/switch/switch.explicit-defaults.md +1 -1
  114. package/skills/apexlang/templates/items/text-area/text-area._common.md +2 -3
  115. package/skills/apexlang/templates/items/text-area/text-area.explicit-defaults.md +1 -1
  116. package/skills/apexlang/templates/items/text-area/text-area.required-length.md +1 -3
  117. package/skills/apexlang/templates/items/text-autocomplete/text-autocomplete.explicit-defaults.md +1 -1
  118. package/skills/apexlang/templates/items/text-autocomplete/text-autocomplete.required-length.md +1 -3
  119. package/skills/apexlang/templates/items/text-field/text-field._common.md +2 -3
  120. package/skills/apexlang/templates/items/text-field/text-field.explicit-defaults.md +1 -1
  121. package/skills/apexlang/templates/items/text-field/text-field.required-length.md +1 -3
  122. package/skills/apexlang/templates/page-examples/faceted-search/faceted-search.example.md +0 -5
  123. package/skills/apexlang/templates/page-examples/form-page/form-page.example.md +0 -9
  124. package/skills/apexlang/templates/page-examples/interactive-report-page/interactive-report-page.example.md +2 -2
  125. package/skills/apexlang/templates/page-examples/login-page/login-page.example.md +0 -8
  126. package/skills/apexlang/templates/page-examples/task-definition-initiated-tasks-page/task-definition-initiated-tasks-page.example.md +7 -17
  127. package/skills/apexlang/templates/page-examples/task-definition-my-tasks-page/task-definition-my-tasks-page.example.md +7 -65
  128. package/skills/apexlang/templates/page-examples/task-definition-task-details/task-definition-task-details.example.md +38 -201
  129. package/skills/apexlang/templates/region-components/calendar/calendar.custom-styling.md +3 -1
  130. package/skills/apexlang/templates/region-components/calendar/calendar.faceted-search.md +3 -2
  131. package/skills/apexlang/templates/region-components/cards/README.md +12 -4
  132. package/skills/apexlang/templates/region-components/cards/cards._common.md +176 -37
  133. package/skills/apexlang/templates/region-components/cards/cards._index.md +2 -1
  134. package/skills/apexlang/templates/region-components/cards/cards.refresh-after-dialog.md +46 -0
  135. package/skills/apexlang/templates/region-components/cards/cards.refresh-on-change.md +58 -0
  136. package/skills/apexlang/templates/region-components/cards/cards.rest-source.md +54 -18
  137. package/skills/apexlang/templates/region-components/cards/cards.standard.md +37 -21
  138. package/skills/apexlang/templates/region-components/chart/chart._series._common.md +1 -4
  139. package/skills/apexlang/templates/region-components/chart/chart.pie.md +6 -2
  140. package/skills/apexlang/templates/region-components/chart/chart.status-meter-gauge.md +1 -1
  141. package/skills/apexlang/templates/region-components/chart/chart.stock.md +2 -0
  142. package/skills/apexlang/templates/region-components/chart/features/chart.feature-chart-links.md +9 -7
  143. package/skills/apexlang/templates/region-components/faceted-search/faceted-search._common.md +1 -14
  144. package/skills/apexlang/templates/region-components/form/form._items._common.md +1 -5
  145. package/skills/apexlang/templates/region-components/interactive-report/interactive-report._columns._common.md +2 -6
  146. package/skills/apexlang/templates/region-components/interactive-report/interactive-report.page-header-actions.md +1 -7
  147. package/skills/apexlang/templates/region-components/list/README.md +1 -1
  148. package/skills/apexlang/templates/region-components/list/list._common.md +1 -1
  149. package/skills/apexlang/templates/region-components/map/map.backgrounds.md +12 -10
  150. package/skills/apexlang/templates/region-components/map/map.layer.extruded-polygons.md +16 -12
  151. package/skills/apexlang/templates/region-components/map/map.layer.heat-map.md +10 -7
  152. package/skills/apexlang/templates/region-components/map/map.layer.lines.md +10 -8
  153. package/skills/apexlang/templates/region-components/map/map.layer.polygons.md +21 -18
  154. package/skills/apexlang/templates/region-components/map/map.region.background-custom.md +25 -19
  155. package/skills/apexlang/templates/region-components/map/map.region.background-shared.md +19 -13
  156. package/skills/apexlang/templates/region-components/map/map.region.bbox-sql.md +13 -13
  157. package/skills/apexlang/templates/region-components/map/map.region.bbox-static.md +2 -2
  158. package/skills/apexlang/templates/region-components/map/map.region.browser-location.md +3 -7
  159. package/skills/apexlang/templates/region-components/map/map.region.init-position-sql.md +7 -7
  160. package/skills/apexlang/templates/region-components/region-display-selector/README.md +5 -2
  161. package/skills/apexlang/templates/region-components/region-display-selector/region-display-selector._common.md +60 -7
  162. package/skills/apexlang/templates/region-components/region-display-selector/region-display-selector._index.md +4 -1
  163. package/skills/apexlang/templates/region-components/region-display-selector/region-display-selector.permutations.md +55 -0
  164. package/skills/apexlang/templates/region-components/region-display-selector/region-display-selector.standard.md +91 -5
  165. package/skills/apexlang/templates/region-components/smart-filter-search/README.md +6 -2
  166. package/skills/apexlang/templates/region-components/smart-filter-search/smart-filter-search._common.md +107 -46
  167. package/skills/apexlang/templates/region-components/smart-filter-search/smart-filter-search._index.md +4 -3
  168. package/skills/apexlang/templates/region-components/smart-filter-search/smart-filter-search.standard.md +33 -17
  169. package/skills/apexlang/templates/shared-components/component-settings/component-settings._common.md +1 -0
  170. package/skills/apexlang/templates/shared-components/component-settings.example.md +1 -0
  171. package/skills/apexlang/templates/shared-components/email-templates.example.md +1 -1
  172. package/skills/apexlang/templates/shared-components/rest-data-sources/example_rest_data_source.example.md +40 -46
  173. package/skills/apexlang/templates/shared-components/task-definitions/action-task.example.md +2 -30
  174. package/skills/apexlang/templates/shared-components/task-definitions/approve-request.example.md +3 -31
  175. package/skills/apexlang/templates/template-components/README.md +27 -15
  176. package/skills/apexlang/templates/template-components/avatar/README.md +56 -0
  177. package/skills/apexlang/templates/template-components/avatar/avatar._common.md +149 -0
  178. package/skills/apexlang/templates/template-components/avatar/avatar._index.md +42 -0
  179. package/skills/apexlang/templates/template-components/{avatar._template_options.md → avatar/avatar._template_options.md} +1 -1
  180. package/skills/apexlang/templates/template-components/avatar/avatar.report-icon.md +48 -0
  181. package/skills/apexlang/templates/template-components/avatar/avatar.report-image-url-column.md +62 -0
  182. package/skills/apexlang/templates/template-components/avatar/avatar.report-initials.md +54 -0
  183. package/skills/apexlang/templates/template-components/badge/README.md +38 -0
  184. package/skills/apexlang/templates/template-components/badge/badge._common.md +183 -0
  185. package/skills/apexlang/templates/template-components/badge/badge._index.md +20 -0
  186. package/skills/apexlang/templates/template-components/badge/badge.report-link.md +66 -0
  187. package/skills/apexlang/templates/template-components/badge/badge.report-minimal.md +76 -0
  188. package/skills/apexlang/templates/template-components/comments/README.md +20 -0
  189. package/skills/apexlang/templates/template-components/comments/comments._common.md +43 -0
  190. package/skills/apexlang/templates/template-components/comments/comments._index.md +25 -0
  191. package/skills/apexlang/templates/template-components/{comments._template_options.md → comments/comments._template_options.md} +2 -1
  192. package/skills/apexlang/templates/template-components/comments/comments.apex-task-comments.md +77 -0
  193. package/skills/apexlang/templates/template-components/comments/comments.partial-column.md +120 -0
  194. package/skills/apexlang/templates/template-components/comments/comments.permutations.md +425 -0
  195. package/skills/apexlang/templates/template-components/content-row/README.md +1 -1
  196. package/skills/apexlang/templates/template-components/content-row/content-row._common.md +1 -1
  197. package/skills/apexlang/templates/template-components/content-row/content-row._index.md +1 -1
  198. package/skills/apexlang/templates/template-components/content-row/content-row._template_options.md +1 -1
  199. package/skills/apexlang/templates/template-components/flexbox-container/README.md +9 -0
  200. package/skills/apexlang/templates/template-components/flexbox-container/flexbox-container._index.md +13 -0
  201. package/skills/apexlang/templates/template-components/media-list/README.md +100 -0
  202. package/skills/apexlang/templates/template-components/media-list/media-list._common.md +174 -0
  203. package/skills/apexlang/templates/template-components/media-list/media-list._index.md +50 -0
  204. package/skills/apexlang/templates/template-components/{media-list._template_options.md → media-list/media-list._template_options.md} +8 -2
  205. package/skills/apexlang/templates/template-components/media-list/media-list.partial.md +50 -0
  206. package/skills/apexlang/templates/template-components/media-list/media-list.report-avatar-badge.md +76 -0
  207. package/skills/apexlang/templates/template-components/media-list/media-list.report-base.md +71 -0
  208. package/skills/apexlang/templates/template-components/media-list/media-list.report-grouped.md +40 -0
  209. package/skills/apexlang/templates/template-components/media-list/media-list.report-layouts.md +50 -0
  210. package/skills/apexlang/templates/template-components/media-list/media-list.report-link.md +53 -0
  211. package/skills/apexlang/templates/template-components/metric-card/README.md +19 -4
  212. package/skills/apexlang/templates/template-components/metric-card/metric-card._common.md +122 -29
  213. package/skills/apexlang/templates/template-components/metric-card/metric-card._index.md +6 -0
  214. package/skills/apexlang/templates/template-components/metric-card/metric-card._template_options.md +47 -2
  215. package/skills/apexlang/templates/template-components/metric-card/metric-card.partial-minimal.md +51 -0
  216. package/skills/apexlang/templates/template-components/metric-card/metric-card.permutations.md +56 -0
  217. package/skills/apexlang/templates/template-components/metric-card/metric-card.report-avatar-badge.md +98 -0
  218. package/skills/apexlang/templates/template-components/metric-card/metric-card.report-grouping-selection.md +131 -0
  219. package/skills/apexlang/templates/template-components/metric-card/metric-card.report-link.md +66 -0
  220. package/skills/apexlang/templates/template-components/metric-card/metric-card.report-minimal.md +97 -0
  221. package/skills/apexlang/templates/template-components/template-components.registry.json +90 -1
  222. package/skills/apexlang/templates/template-components/timeline/README.md +19 -0
  223. package/skills/apexlang/templates/template-components/timeline/timeline._common.md +43 -0
  224. package/skills/apexlang/templates/template-components/timeline/timeline._index.md +24 -0
  225. package/skills/apexlang/templates/template-components/{timeline._template_options.md → timeline/timeline._template_options.md} +2 -1
  226. package/skills/apexlang/templates/template-components/timeline/timeline.permutations.md +399 -0
  227. package/skills/apexlang/templates/template-components/timeline/timeline.report-sample-data.md +168 -0
  228. package/skills/apexlang/templates/workspace-components/credentials/credentials-for-open-ai.example.md +1 -1
  229. package/skills/apexlang/templates/workspace-components/generative-ai-services/open-ai.example.md +8 -6
  230. package/skills/apexlang/tools/apexctl.mjs +167 -4
  231. package/skills/apexlang/tools/compiler-truth-audit.mjs +95 -63
  232. package/skills/apexlang/tools/query-valid-props-context.mjs +30 -0
  233. package/skills/apexlang/tools/query-valid-props-normalize.mjs +1 -0
  234. package/skills/apexlang/tools/query-valid-props-runtime.mjs +13 -8
  235. package/skills/apexlang/tools/query-valid-props-semantics.mjs +391 -0
  236. package/skills/apexlang/tools/query-valid-props-template-components.mjs +15 -1
  237. package/skills/apexlang/tools/query-valid-props.mjs +198 -216
  238. /package/skills/apexlang/templates/template-components/{badge._template_options.md → badge/badge._template_options.md} +0 -0
  239. /package/skills/apexlang/templates/template-components/{flexbox-container._template_options.md → flexbox-container/flexbox-container._template_options.md} +0 -0
@@ -1,7 +1,15 @@
1
+ import fs from "node:fs";
1
2
  import path from "node:path";
2
3
  import { fileURLToPath } from "node:url";
3
- import { buildOracleNormalizedMap, ORACLE_NORMALIZER_VERSION, readOracleRuntimeMetadata } from "./query-valid-props-normalize.mjs";
4
- import { resolveOracleRuntime } from "./query-valid-props-runtime.mjs";
4
+ import { loadOracleCompilerContext } from "./query-valid-props-context.mjs";
5
+ import {
6
+ buildPropertyLookup as basePropertyLookup,
7
+ parseQueryAssumptions as parseAssumptions,
8
+ queryPropertyStatus as propertyStatus,
9
+ resolveDottedComponentAlias,
10
+ resolveLovValues,
11
+ selectQueryComponents as selectComponents
12
+ } from "./query-valid-props-semantics.mjs";
5
13
  import { loadTemplateComponentProfile } from "./query-valid-props-template-components.mjs";
6
14
 
7
15
  const SCRIPT_PATH = fileURLToPath(import.meta.url);
@@ -36,6 +44,7 @@ function parseArgs(argv) {
36
44
  parent: null,
37
45
  group: null,
38
46
  templateComponent: null,
47
+ auditOptionalProperties: false,
39
48
  assumes: [],
40
49
  list: false,
41
50
  dumpJson: false,
@@ -75,6 +84,9 @@ function parseArgs(argv) {
75
84
  args.templateComponent = readRequiredOptionValue(argv, index, arg);
76
85
  index += 1;
77
86
  break;
87
+ case "--audit-optional-properties":
88
+ args.auditOptionalProperties = true;
89
+ break;
78
90
  case "--when":
79
91
  args.assumes.push(readRequiredOptionValue(argv, index, arg));
80
92
  index += 1;
@@ -101,98 +113,187 @@ function parseArgs(argv) {
101
113
  return args;
102
114
  }
103
115
 
104
- const DOTTED_COMPONENT_ALIASES = new Map([
105
- ["map.region", { component: "region", assumes: ["94=NATIVE_MAP"] }],
106
- ["map.layer", { component: "layer" }],
107
- ["map.layer.source", { component: "layer", group: "source" }],
108
- ["map.layer.columnMapping", { component: "layer", group: "columnMapping" }],
109
- ["map.layer.tooltip", { component: "layer", group: "tooltip" }],
110
- ["map.layer.infoWindow", { component: "layer", group: "infoWindow" }],
111
- ["map.layer.link", { component: "layer", group: "link" }],
112
- ["chart.region", { component: "region", assumes: ["94=NATIVE_JET_CHART"] }],
113
- ["chart.series", { component: "series" }],
114
- ["chart.series.marker", { component: "series", group: "marker" }],
115
- ["chart.series.line", { component: "series", group: "line" }],
116
- ["chart.series.label", { component: "series", group: "label" }],
117
- ["chart.series.tooltip", { component: "series", group: "tooltip" }],
118
- ["chart.axis", { component: "axis" }],
119
- ["chart.axis.x", { component: "axis" }],
120
- ["chart.axis.y", { component: "axis" }],
121
- ["chart.axis.y2", { component: "axis" }],
122
- ["interactiveReport.region", { component: "region", assumes: ["94=NATIVE_IR"] }],
123
- ["interactiveGrid.region", { component: "region", assumes: ["94=NATIVE_IG"] }],
124
- ["classicReport.region", { component: "region", assumes: ["94=NATIVE_SQL_REPORT"] }],
125
- ["form.region", { component: "region", assumes: ["94=NATIVE_FORM"] }],
126
- ["report.column", { component: "column", parent: "region" }],
127
- ["report.column.heading", { component: "column", parent: "region", group: "heading" }],
128
- ["report.column.layout", { component: "column", parent: "region", group: "layout" }],
129
- ["report.column.source", { component: "column", parent: "region", group: "source" }],
130
- ["report.column.appearance", { component: "column", parent: "region", group: "appearance" }],
131
- ["report.column.link", { component: "column", parent: "region", group: "link" }],
132
- ["pageItem.layout", { component: "pageItem", group: "layout" }],
133
- ["pageItem.source", { component: "pageItem", group: "source" }],
134
- ["pageItem.validation", { component: "pageItem", group: "validation" }],
135
- ["displayOnly.source", { component: "pageItem", group: "source", assumes: ["381=DISPLAY_ONLY"] }]
136
- ]);
116
+ const APEXLANG_GRAMMAR_COMPONENT_RULE_PATTERN = /^"(?<keyword>[A-Za-z][A-Za-z0-9]*)"\s+\[\s*<required-ws>\s+<component-id>\s*\].*"\("[^\n]*/;
117
+ const APEXLANG_GRAMMAR_GROUP_RULE_PATTERN = /^<indent>\s+"(?<group>[A-Za-z][A-Za-z0-9]*)"\s+<ws>\s+"\{"/;
118
+ const APEXLANG_GRAMMAR_PROPERTY_PATTERN = /"([A-Za-z][A-Za-z0-9]*)"\s+":"[^(\n]*(?:\(\*\s*(?<comment>.*?)\s*\*\))?/g;
119
+ const APEXLANG_GRAMMAR_RULE_REF_PATTERN = /<([A-Za-z0-9-]+)>/g;
137
120
 
138
- /**
139
- * Expand friendly dotted aliases such as chart.series.tooltip into compiler metadata filters.
140
- */
141
- function resolveDottedComponentAlias(args) {
142
- if (!args.component || !args.component.includes(".")) {
143
- return;
121
+ function resolveGrammarPath() {
122
+ const repoGrammarPath = path.resolve("ai-context", "apexlang", "grammar", "apexlang.ebnf");
123
+ if (fs.existsSync(repoGrammarPath)) {
124
+ return repoGrammarPath;
144
125
  }
145
-
146
- const alias = DOTTED_COMPONENT_ALIASES.get(args.component);
147
- if (!alias) {
148
- throw new Error(`Unknown dotted component alias: ${args.component}`);
126
+ const packagedGrammarPath = path.resolve(path.dirname(SCRIPT_PATH), "..", "assets", "grammar", "apexlang.ebnf");
127
+ if (fs.existsSync(packagedGrammarPath)) {
128
+ return packagedGrammarPath;
149
129
  }
130
+ return null;
131
+ }
150
132
 
151
- args.component = alias.component;
152
- if (!args.group && alias.group) {
153
- args.group = alias.group;
133
+ function parseEbnfRules(grammarText) {
134
+ const rules = new Map();
135
+ let currentName = "";
136
+ let currentLines = [];
137
+
138
+ for (const line of grammarText.split(/\r?\n/)) {
139
+ const match = /^<([^>]+)>\s*::=\s*(.*)$/.exec(line);
140
+ if (match) {
141
+ if (currentName) {
142
+ rules.set(currentName, currentLines.join("\n").trim());
143
+ }
144
+ currentName = match[1];
145
+ currentLines = [match[2]];
146
+ continue;
147
+ }
148
+ if (currentName) {
149
+ currentLines.push(line);
150
+ }
154
151
  }
155
- if (alias.parent && !args.parent) {
156
- args.parent = alias.parent;
152
+ if (currentName) {
153
+ rules.set(currentName, currentLines.join("\n").trim());
157
154
  }
158
- if (alias.assumes?.length) {
159
- const existing = new Set(args.assumes);
160
- for (const assumption of alias.assumes) {
161
- if (!existing.has(assumption)) {
162
- args.assumes.push(assumption);
155
+ return rules;
156
+ }
157
+
158
+ function grammarRuleRefs(ruleBody) {
159
+ return [...String(ruleBody || "").matchAll(APEXLANG_GRAMMAR_RULE_REF_PATTERN)].map((match) => match[1]);
160
+ }
161
+
162
+ function grammarProperties(ruleBody) {
163
+ const properties = [];
164
+ for (const match of String(ruleBody || "").matchAll(APEXLANG_GRAMMAR_PROPERTY_PATTERN)) {
165
+ const comment = match.groups?.comment || "";
166
+ properties.push({
167
+ name: match[1],
168
+ required: /\brequired\b/.test(comment),
169
+ comment: comment || null
170
+ });
171
+ }
172
+ return properties;
173
+ }
174
+
175
+ function buildGrammarComponentContracts(grammarText) {
176
+ const rules = parseEbnfRules(grammarText);
177
+ const contracts = new Map();
178
+ for (const [ruleName, ruleBody] of rules.entries()) {
179
+ const componentMatch = APEXLANG_GRAMMAR_COMPONENT_RULE_PATTERN.exec(ruleBody);
180
+ if (!componentMatch) {
181
+ continue;
182
+ }
183
+ const keyword = componentMatch.groups.keyword;
184
+ const contract = {
185
+ keyword,
186
+ ruleName,
187
+ directProperties: grammarProperties(rules.get(`${ruleName}-direct-property`)),
188
+ groups: {}
189
+ };
190
+ for (const groupRuleName of grammarRuleRefs(rules.get(`${ruleName}-group-block`))) {
191
+ const groupMatch = APEXLANG_GRAMMAR_GROUP_RULE_PATTERN.exec(rules.get(groupRuleName) || "");
192
+ if (!groupMatch) {
193
+ continue;
163
194
  }
195
+ contract.groups[groupMatch.groups.group] = grammarProperties(rules.get(`${groupRuleName}-property`));
196
+ }
197
+ if (!contracts.has(keyword)) {
198
+ contracts.set(keyword, []);
164
199
  }
200
+ contracts.get(keyword).push(contract);
165
201
  }
202
+ return contracts;
166
203
  }
167
204
 
168
- /**
169
- * Convert --when entries into lookup maps used by dependency evaluation.
170
- */
171
- function parseAssumptions(entries) {
172
- const byRawKey = new Map();
173
- const byScopedName = new Map();
174
- const byPropertyName = new Map();
175
-
176
- for (const entry of entries) {
177
- const pivot = entry.indexOf("=");
178
- if (pivot === -1) {
179
- throw new Error(`Invalid --when expression: ${entry}. Expected group.property=value or property=value`);
205
+ function propertyConditionFeatures(prop) {
206
+ const features = new Set();
207
+ function walk(node) {
208
+ if (!node) {
209
+ return;
180
210
  }
181
- const key = entry.slice(0, pivot).trim();
182
- const value = entry.slice(pivot + 1).trim();
183
- if (!key || !value) {
184
- throw new Error(`Invalid --when expression: ${entry}. Expected non-empty key and value`);
211
+ if (node.conditions) {
212
+ for (const condition of node.conditions) {
213
+ walk(condition);
214
+ }
215
+ return;
185
216
  }
186
- byRawKey.set(key, value);
187
- byScopedName.set(key, value);
188
- const propertyName = key.split(".").at(-1);
189
- if (!byPropertyName.has(propertyName)) {
190
- byPropertyName.set(propertyName, []);
217
+ if (node.type === "FEATURES") {
218
+ for (const value of node.values || []) {
219
+ features.add(value);
220
+ }
191
221
  }
192
- byPropertyName.get(propertyName).push({ key, value });
193
222
  }
223
+ walk(prop.dependsOn);
224
+ return [...features].sort();
225
+ }
194
226
 
195
- return { byRawKey, byScopedName, byPropertyName };
227
+ function buildPageItemOptionalPropertiesAudit(map) {
228
+ const grammarPath = resolveGrammarPath();
229
+ if (!grammarPath) {
230
+ throw new Error("APEXlang grammar file not found for optional property audit");
231
+ }
232
+ const grammarText = fs.readFileSync(grammarPath, "utf8");
233
+ const grammarContracts = buildGrammarComponentContracts(grammarText).get("pageItem") || [];
234
+ const grammarContract = grammarContracts[0];
235
+ if (!grammarContract) {
236
+ throw new Error(`APEXlang grammar file does not expose a pageItem contract: ${grammarPath}`);
237
+ }
238
+
239
+ const pageItemRecord = map.componentTypes.find((record) => record.componentTypeId === "5120" || record.singular === "pageItem");
240
+ if (!pageItemRecord) {
241
+ throw new Error("Compiler metadata does not expose pageItem component type 5120");
242
+ }
243
+
244
+ const compilerLookup = basePropertyLookup(pageItemRecord);
245
+ const groups = {};
246
+ for (const [groupName, grammarProps] of Object.entries(grammarContract.groups)) {
247
+ groups[groupName] = grammarProps.map((grammarProp) => {
248
+ const compilerProps = compilerLookup.get(`${groupName}.${grammarProp.name}`) || [];
249
+ return {
250
+ propertyName: grammarProp.name,
251
+ grammarRequired: grammarProp.required,
252
+ grammarComment: grammarProp.comment,
253
+ compilerStatus: compilerProps.length ? "present" : "missing",
254
+ compilerPropertyIds: compilerProps.map((prop) => prop.propertyId),
255
+ compilerRequired: compilerProps.some((prop) => prop.required),
256
+ compilerConditionFeatures: [...new Set(compilerProps.flatMap(propertyConditionFeatures))].sort(),
257
+ compilerConditionText: compilerProps.map((prop) => conditionToText(prop.dependsOn)).filter(Boolean)
258
+ };
259
+ });
260
+ }
261
+
262
+ return {
263
+ status: "pass",
264
+ compilerTruth: map.compilerTruth,
265
+ grammar: {
266
+ path: grammarPath,
267
+ component: "pageItem",
268
+ ruleName: grammarContract.ruleName,
269
+ directProperties: grammarContract.directProperties,
270
+ groups
271
+ },
272
+ baseCompiler: {
273
+ componentTypeId: pageItemRecord.componentTypeId,
274
+ pluginPropertyId: pageItemRecord.pluginPropertyId,
275
+ pluginComponentTypeName: pageItemRecord.pluginComponentTypeName,
276
+ pluginApiExpression: pageItemRecord.pluginApiExpression,
277
+ groups: Object.fromEntries(
278
+ Object.entries(pageItemRecord.groups || {}).map(([groupName, props]) => [
279
+ groupName,
280
+ props.map((prop) => ({
281
+ propertyName: prop.propertyName,
282
+ propertyId: prop.propertyId,
283
+ required: prop.required,
284
+ conditionFeatures: propertyConditionFeatures(prop),
285
+ conditionText: conditionToText(prop.dependsOn) || null
286
+ }))
287
+ ])
288
+ )
289
+ },
290
+ pluginSettings: {
291
+ state: "plugin_attribute_metadata_not_exposed",
292
+ reason: "Live metadata exposes the pageItem plugin attribute sink but not a complete built-in native item plugin custom-attribute inventory; absence from generic grammar must not be treated as invalid settings syntax.",
293
+ attributeSink: pageItemRecord.pluginApiExpression || null,
294
+ pluginPropertyId: pageItemRecord.pluginPropertyId
295
+ }
296
+ };
196
297
  }
197
298
 
198
299
  /**
@@ -217,112 +318,6 @@ function conditionToText(node) {
217
318
  return `${left} ${node.type}`;
218
319
  }
219
320
 
220
- function resolveAssumptionValue(condition, assumptionIndex) {
221
- if (condition.propertyId && assumptionIndex.byRawKey.has(condition.propertyId)) {
222
- return { state: "known", value: assumptionIndex.byRawKey.get(condition.propertyId) };
223
- }
224
-
225
- const propertyName = condition.propertyName;
226
- if (!propertyName) {
227
- return { state: "unknown", reason: "condition has no property name" };
228
- }
229
-
230
- if (assumptionIndex.byScopedName.has(propertyName)) {
231
- return { state: "known", value: assumptionIndex.byScopedName.get(propertyName) };
232
- }
233
-
234
- const matches = assumptionIndex.byPropertyName.get(propertyName) || [];
235
- if (!matches.length) {
236
- return { state: "unknown", reason: `no assumption for ${propertyName}` };
237
- }
238
- if (matches.length > 1) {
239
- return {
240
- state: "unknown",
241
- reason: `ambiguous assumption for ${propertyName}: ${matches.map((match) => match.key).join(", ")}`
242
- };
243
- }
244
- return { state: "known", value: matches[0].value };
245
- }
246
-
247
- function evaluateLeaf(condition, assumptionIndex) {
248
- const resolved = resolveAssumptionValue(condition, assumptionIndex);
249
- if (resolved.state !== "known") {
250
- return { state: "unknown", reason: resolved.reason };
251
- }
252
-
253
- const actual = resolved.value;
254
- switch (condition.type) {
255
- case "EQUALS":
256
- return { state: actual === condition.value ? "true" : "false" };
257
- case "NOT_EQUALS":
258
- return { state: actual !== condition.value ? "true" : "false" };
259
- case "IN_LIST":
260
- return { state: condition.values?.includes(actual) ? "true" : "false" };
261
- case "NOT_IN_LIST":
262
- return { state: condition.values?.includes(actual) ? "false" : "true" };
263
- case "NOT_NULL":
264
- return { state: actual ? "true" : "false" };
265
- case "NULL":
266
- return { state: actual ? "false" : "true" };
267
- case "STARTS_WITH":
268
- return { state: actual.startsWith(condition.value || "") ? "true" : "false" };
269
- case "STARTS_WITH_ANY":
270
- return { state: (condition.values || []).some((value) => actual.startsWith(value)) ? "true" : "false" };
271
- default:
272
- return { state: "unknown", reason: `unsupported operator ${condition.type}` };
273
- }
274
- }
275
-
276
- function combineResults(operator, results) {
277
- const states = results.map((result) => result.state);
278
- if (operator === "AND") {
279
- if (states.includes("false")) return { state: "false" };
280
- if (states.every((state) => state === "true")) return { state: "true" };
281
- return { state: "unknown" };
282
- }
283
- if (operator === "OR") {
284
- if (states.includes("true")) return { state: "true" };
285
- if (states.every((state) => state === "false")) return { state: "false" };
286
- return { state: "unknown" };
287
- }
288
- return { state: "unknown" };
289
- }
290
-
291
- /**
292
- * Evaluate one metadata condition against caller-provided --when assumptions.
293
- */
294
- function evaluateCondition(node, assumptionIndex) {
295
- if (!node) {
296
- return { state: "true" };
297
- }
298
- if (node.conditions) {
299
- return combineResults(
300
- node.operator || "AND",
301
- node.conditions.map((condition) => evaluateCondition(condition, assumptionIndex))
302
- );
303
- }
304
- return evaluateLeaf(node, assumptionIndex);
305
- }
306
-
307
- /**
308
- * Return compiler components that match the requested component, parent, and type filters.
309
- */
310
- function selectComponents(map, args) {
311
- let matches = map.componentTypes;
312
-
313
- if (args.componentTypeId) {
314
- matches = matches.filter((record) => record.componentTypeId === args.componentTypeId);
315
- }
316
- if (args.component) {
317
- matches = matches.filter((record) => record.singular === args.component);
318
- }
319
- if (args.parent) {
320
- matches = matches.filter((record) => record.parentComponentType === args.parent);
321
- }
322
-
323
- return matches.sort((left, right) => left.componentTypeId.localeCompare(right.componentTypeId));
324
- }
325
-
326
321
  function listComponents(map, args) {
327
322
  const matches = selectComponents(map, args);
328
323
  if (!matches.length) {
@@ -332,24 +327,13 @@ function listComponents(map, args) {
332
327
  for (const match of matches) {
333
328
  console.log(`${match.componentTypeId}\t${match.singular}\tparent=${match.parentComponentType || "none"}\tprops=${match.propertyCount}`);
334
329
  if (match.parentDependsOn) {
335
- console.log(` when ${conditionToText(match.parentDependsOn)}`);
330
+ console.log(` valid when parent.${conditionToText(match.parentDependsOn)}`);
336
331
  }
337
332
  }
338
333
  }
339
334
 
340
- function propertyStatus(prop, assumptionIndex) {
341
- const result = evaluateCondition(prop.dependsOn, assumptionIndex);
342
- if (result.state === "true") return "active";
343
- if (result.state === "false") return "inactive";
344
- return prop.dependsOn ? "conditional" : "active";
345
- }
346
-
347
335
  function renderLovValues(prop) {
348
- if (!prop.lov?.values?.length) {
349
- return [];
350
- }
351
-
352
- return prop.lov.values.map((value) => {
336
+ return resolveLovValues(prop).map((value) => {
353
337
  const parts = [value.name];
354
338
  if (value.returnValue && value.returnValue !== value.name) {
355
339
  parts.push(`internal=${value.returnValue}`);
@@ -368,7 +352,7 @@ function renderComponent(record, args, assumptionIndex) {
368
352
  console.log(`${record.singular} [componentTypeId=${record.componentTypeId}]`);
369
353
  console.log(`parent: ${record.parentComponentType || "none"}`);
370
354
  if (record.parentDependsOn) {
371
- console.log(`parent condition: ${conditionToText(record.parentDependsOn)}`);
355
+ console.log(`valid when parent.${conditionToText(record.parentDependsOn)}`);
372
356
  }
373
357
  if (record.filePath) {
374
358
  console.log(`filePath: ${record.filePath}`);
@@ -439,7 +423,8 @@ Options:
439
423
  --component-type-id <id> Exact compiler component type id, for example 5110
440
424
  --parent <name> Filter by parent semantic name, for example page or region
441
425
  --group <name> Show only one group, for example source
442
- --template-component <name> Inspect Universal Theme template-component metadata and distilled settings
426
+ --template-component <name> Inspect Universal Theme export metadata (inventory only; not compiler-backed)
427
+ --audit-optional-properties Emit pageItem grammar/compiler optional-property audit JSON
443
428
  --when <expr> Assumption used to classify props, for example identification.type=NATIVE_IR or 94=NATIVE_IR
444
429
  --list List matching component types instead of property details
445
430
  --json Emit a machine-readable compiler-truth payload
@@ -452,6 +437,7 @@ Examples:
452
437
  ${command} --component map.layer.link
453
438
  ${command} --component chart.series.marker
454
439
  ${command} --template-component metricCard
440
+ ${command} --component pageItem --audit-optional-properties --json
455
441
  ${command} --json > /tmp/apexlang-runtime-map.json
456
442
  ${command} --compiler-oracle-home /path/to/oracle.sql-developer-26.1.2 --component-type-id 7320
457
443
  `);
@@ -459,6 +445,9 @@ Examples:
459
445
 
460
446
  function renderTemplateComponentProfile(profile) {
461
447
  console.log(`templateComponent ${profile.requestedName} [theme=${profile.theme}]`);
448
+ console.log(`authority: ${profile.authority}`);
449
+ console.log(`compilerBacked: ${profile.compilerBacked}`);
450
+ console.log(`warning: ${profile.limitations.join(" ")}`);
462
451
  console.log(`plugin: ${profile.plugin.identifier}`);
463
452
  console.log(`name: ${profile.plugin.name || "unknown"}`);
464
453
  console.log(`staticId: ${profile.plugin.staticId || "unknown"}`);
@@ -494,25 +483,11 @@ function renderTemplateComponentProfile(profile) {
494
483
  }
495
484
 
496
485
  function resolveOracleBackedMap(args) {
497
- const oracleRuntime = resolveOracleRuntime(args.compilerOracleHome);
498
- const { metadata, buildId, metadataHash } = readOracleRuntimeMetadata(oracleRuntime.compilerJarPath);
499
- const map = buildOracleNormalizedMap({
500
- metadata,
501
- compilerJarPath: oracleRuntime.compilerJarPath,
502
- oracleHome: oracleRuntime.oracleHome,
503
- source: oracleRuntime.source
504
- });
505
- map.compilerTruth = {
506
- buildID: buildId,
507
- metadataHash,
508
- normalizerVersion: ORACLE_NORMALIZER_VERSION,
509
- source: oracleRuntime.source,
510
- oracleHome: oracleRuntime.oracleHome,
511
- compilerJar: oracleRuntime.compilerJarPath
512
- };
486
+ const { map, provenance } = loadOracleCompilerContext(args.compilerOracleHome);
487
+ map.compilerTruth = provenance;
513
488
 
514
489
  console.error(
515
- `Using compiler metadata from SQLcl/Oracle runtime (build=${buildId}, normalizer=${ORACLE_NORMALIZER_VERSION}, metadataHash=${metadataHash}, source=${oracleRuntime.source})`
490
+ `Using compiler metadata from SQLcl/Oracle runtime (build=${provenance.buildID}, normalizer=${provenance.normalizerVersion}, metadataHash=${provenance.metadataHash}, source=${provenance.source})`
516
491
  );
517
492
  return map;
518
493
  }
@@ -537,6 +512,13 @@ function main() {
537
512
  }
538
513
 
539
514
  const map = resolveOracleBackedMap(args);
515
+ if (args.auditOptionalProperties) {
516
+ if (args.component && args.component !== "pageItem") {
517
+ throw new Error("--audit-optional-properties currently supports only --component pageItem");
518
+ }
519
+ console.log(JSON.stringify(buildPageItemOptionalPropertiesAudit(map), null, 2));
520
+ return;
521
+ }
540
522
  if (wantsFullMapJson) {
541
523
  console.log(JSON.stringify(map, null, 2));
542
524
  return;