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
@@ -40,6 +40,23 @@ function readOption(args, name, fallback = "") {
40
40
  return args[index + 1];
41
41
  }
42
42
 
43
+ function readPositiveIntegerOption(args, name, fallback) {
44
+ const index = args.indexOf(name);
45
+ const rawValue = index === -1 ? String(fallback) : args[index + 1];
46
+ if (typeof rawValue !== "string" || !/^[1-9]\d*$/.test(rawValue)) {
47
+ throw new Error(`${name} must be a positive integer`);
48
+ }
49
+ const value = Number(rawValue);
50
+ if (!Number.isSafeInteger(value)) {
51
+ throw new Error(`${name} must be a positive integer`);
52
+ }
53
+ return value;
54
+ }
55
+
56
+ function readOptions(args, name) {
57
+ return args.flatMap((value, index) => value === name && index + 1 < args.length ? [args[index + 1]] : []);
58
+ }
59
+
43
60
  function isPathInside(rootPath, targetPath) {
44
61
  const relative = path.relative(path.resolve(rootPath), path.resolve(targetPath));
45
62
  return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
@@ -150,9 +167,14 @@ function printUsage() {
150
167
  node tools/apexctl.mjs runtime verify-ui --app-path <path> [--runtime-base-url <url>] [--runtime-page-url <url>] [--runtime-provider <auto|chrome-devtools-mcp|http-fallback>] [--page <id>] [--artifact-dir <path>] [--report-path <path>]
151
168
  node tools/apexctl.mjs runtime validate --app-path <absolute_path> --db-connection-name <name> [--apex-root <path>] [--compiler-oracle-home <path>] [--execution-mode <auto|build-root|path>] [--workspaceid <id>] [--artifact-dir <path>] [--vscode-problems-path <path>] [--report-path <path>] [--transcript-path <path>]
152
169
  node tools/apexctl.mjs runtime roundtrip --app-path <path> --db-connection-name <name> [--import-intent <validate-only|validate-and-import>] [--execution-mode <auto|build-root|path>] [--target-resolution-mode <update-existing|create-new>] [--create-new-confirmed] [--workspaceid <id>] [--runtime-base-url <url>] [--runtime-page-url <url>] [--runtime-provider <auto|chrome-devtools-mcp|http-fallback>] [--page <id>] [--artifact-dir <path>] [--require-runtime-verification] [--skip-runtime-verification] [--supporting-objects] [--preflight-only] [--import-mode <auto|direct>] [--apex-root <path>] [--report-path <path>] [--transcript-path <path>]
153
- node tools/apexctl.mjs runtime predeploy --app-path <path> [--fix-vocab]
170
+ node tools/apexctl.mjs runtime predeploy --app-path <path> [--fix-vocab] [--generation-plan <path>] [--require-smart-filter-generation-plan]
171
+ node tools/apexctl.mjs apexlang format --app-path <path> [--strict-structure]
154
172
  node tools/apexctl.mjs apexlang validate --app-path <path> [--fix-vocab]
173
+ node tools/apexctl.mjs apexlang grammar contract --components <name[,name...]> [--children <parent.child[,parent.child...]>] [--instance <parent.child[id].[group.]property=value>]... [--groups <name[,name...]>] [--when <component[.group].property=value>]... [--compiler-oracle-home <path>] [--cache-dir <path>] [--no-cache]
174
+ node tools/apexctl.mjs apexlang grammar audit --artifact-path <path> --components <name[,name...]> [--children <parent.child[,parent.child...]>] [--instance <parent.child[id].[group.]property=value>]... [--groups <name[,name...]>] [--when <component[.group].property=value>]... [--compiler-oracle-home <path>] [--cache-dir <path>] [--no-cache]
155
175
  node tools/apexctl.mjs apexlang compiler-truth audit --app-path <path> [--report-path <path>] [--compiler-oracle-home <path>] [--verify-component-attributes]
176
+ node tools/apexctl.mjs context resolve --intent <text> [--phase <draft|critique|revision>] [--max-bytes <count>] [--cache-path <path>] [--no-cache] [--require-ready]
177
+ node tools/apexctl.mjs context repair [--problems <path>] [--rule-id <id[,id...]>] [--unit-id <id>] [--ir-pointer <pointer>] [--cache-path <path>] [--no-cache]
156
178
  node tools/apexctl.mjs diagnostics resolve-build-root --db-connection-name <name> [--apex-root <path>] [--report-path <path>]
157
179
  `);
158
180
  }
@@ -275,7 +297,12 @@ async function materializeNewApp(packageRoot, appPath, workspaceNameInput) {
275
297
  return 0;
276
298
  }
277
299
 
278
- async function runApexlangValidation(packageRoot, runtimeRoot, appPath, { fixVocab = false } = {}) {
300
+ async function runApexlangValidation(
301
+ packageRoot,
302
+ runtimeRoot,
303
+ appPath,
304
+ { fixVocab = false, generationPlan = "", requireSmartFilterGenerationPlan = false } = {}
305
+ ) {
279
306
  if (!appPath) {
280
307
  console.error("Missing required --app-path");
281
308
  return 1;
@@ -301,6 +328,8 @@ async function runApexlangValidation(packageRoot, runtimeRoot, appPath, { fixVoc
301
328
  path.join(runtimeRoot, "internal", "python", "validate_apexlang.py"),
302
329
  "--report-path",
303
330
  path.join(reportDir, "apexlang-dsl-report.json"),
331
+ ...(generationPlan ? ["--generation-plan", generationPlan] : []),
332
+ ...(requireSmartFilterGenerationPlan ? ["--require-smart-filter-generation-plan"] : []),
304
333
  appPath
305
334
  ]
306
335
  ],
@@ -340,6 +369,25 @@ async function runApexlangValidation(packageRoot, runtimeRoot, appPath, { fixVoc
340
369
  return 0;
341
370
  }
342
371
 
372
+ async function runApexlangFormat(runtimeRoot, appPath, strictStructure = false) {
373
+ if (!appPath) {
374
+ console.error("Missing required --app-path");
375
+ return 1;
376
+ }
377
+ const reportDir = path.join(process.env.APEXLANG_OUTPUT_ROOT, "logs");
378
+ await ensureDir(reportDir);
379
+ const result = spawnSync("python3", [
380
+ path.join(runtimeRoot, "internal", "python", "format_apexlang.py"),
381
+ appPath,
382
+ "--report-path",
383
+ path.join(reportDir, "apexlang-format-report.json"),
384
+ ...(strictStructure ? ["--strict-structure"] : [])
385
+ ], { cwd: process.cwd(), encoding: "utf8", env: process.env });
386
+ if (result.stdout) process.stdout.write(result.stdout);
387
+ if (result.stderr) process.stderr.write(result.stderr);
388
+ return typeof result.status === "number" ? result.status : 1;
389
+ }
390
+
343
391
  async function handleWorkspace(runtimeModule, args) {
344
392
  const intelligencePath = path.join(process.cwd(), "assets", "workspace-intelligence.json");
345
393
  const intelligence = (await readJsonIfPresent(intelligencePath)) ?? runtimeModule.DEFAULT_CONFIG;
@@ -457,8 +505,61 @@ async function handleDiagnostics(runtimeModule, args) {
457
505
  return result.code;
458
506
  }
459
507
 
508
+ async function writeContextCapsule(runRoot, result, args, kind) {
509
+ if (parseFlag(args, "--no-cache")) {
510
+ return "";
511
+ }
512
+ const requestedPath = readOption(args, "--cache-path", "");
513
+ const cachePath = requestedPath
514
+ ? path.resolve(requestedPath)
515
+ : path.join(runRoot, "context-capsules", kind + "-" + result.fingerprint + ".json");
516
+ await ensureDir(path.dirname(cachePath));
517
+ await writeJson(cachePath, result.payload);
518
+ return cachePath;
519
+ }
520
+
521
+ async function handleContext(runRoot, args) {
522
+ const action = args[0];
523
+ try {
524
+ const { resolveContextCapsule, resolveRepairCapsule } = await import("../runtime/lib/catalogs.mjs");
525
+ if (action === "resolve") {
526
+ const maxBytes = readPositiveIntegerOption(args, "--max-bytes", 12000);
527
+ const result = await resolveContextCapsule({
528
+ intent: readOption(args, "--intent", ""),
529
+ phase: readOption(args, "--phase", "draft"),
530
+ maxBytes
531
+ });
532
+ const cachePath = await writeContextCapsule(runRoot, result, args, "context");
533
+ console.log(JSON.stringify({ ...result.payload, capsule_bytes: result.bytes, cache_path: cachePath }, null, 2));
534
+ if (parseFlag(args, "--require-ready") && result.payload.generation_status !== "ready") {
535
+ console.error("APEXLANG_CONTEXT_BLOCKED " + result.payload.routing_decision.missingInputs.join(","));
536
+ return 2;
537
+ }
538
+ return 0;
539
+ }
540
+ if (action === "repair") {
541
+ const problemsPath = readOption(args, "--problems", "");
542
+ const problems = problemsPath ? await readJson(path.resolve(problemsPath)) : null;
543
+ const result = await resolveRepairCapsule({
544
+ ruleIds: args.flatMap((value, index) => value === "--rule-id" && args[index + 1] ? [args[index + 1]] : []),
545
+ problems,
546
+ unitId: readOption(args, "--unit-id", ""),
547
+ irPointer: readOption(args, "--ir-pointer", "")
548
+ });
549
+ const cachePath = await writeContextCapsule(runRoot, result, args, "repair");
550
+ console.log(JSON.stringify({ ...result.payload, capsule_bytes: result.bytes, cache_path: cachePath }, null, 2));
551
+ return 0;
552
+ }
553
+ } catch (error) {
554
+ console.error(error instanceof Error ? error.message : String(error));
555
+ return 1;
556
+ }
557
+ printUsage();
558
+ return 1;
559
+ }
560
+
460
561
  async function main() {
461
- const { packageRoot, runtimeRoot, runtimeModule } = await prepareRuntimeEnvironment();
562
+ const { packageRoot, runtimeRoot, runRoot, runtimeModule } = await prepareRuntimeEnvironment();
462
563
  const args = process.argv.slice(2);
463
564
  const namespace = args[0];
464
565
  const rest = args.slice(1);
@@ -473,11 +574,70 @@ async function main() {
473
574
  if (namespace === "new-app" && rest[0] === "materialize") {
474
575
  return materializeNewApp(packageRoot, readOption(rest, "--app-path", ""), readOption(rest, "--workspace-name", ""));
475
576
  }
577
+ if (namespace === "apexlang" && rest[0] === "format") {
578
+ return runApexlangFormat(runtimeRoot, readOption(rest, "--app-path", ""), parseFlag(rest, "--strict-structure"));
579
+ }
476
580
  if (namespace === "apexlang" && rest[0] === "validate") {
477
581
  return runApexlangValidation(packageRoot, runtimeRoot, readOption(rest, "--app-path", ""), {
478
- fixVocab: parseFlag(rest, "--fix-vocab")
582
+ fixVocab: parseFlag(rest, "--fix-vocab"),
583
+ generationPlan: readOption(rest, "--generation-plan", ""),
584
+ requireSmartFilterGenerationPlan: parseFlag(rest, "--require-smart-filter-generation-plan")
479
585
  });
480
586
  }
587
+ if (namespace === "apexlang" && rest[0] === "grammar" && rest[1] === "contract") {
588
+ const components = readOption(rest, "--components", "");
589
+ if (!components.trim()) {
590
+ console.error("Missing required --components");
591
+ return 1;
592
+ }
593
+ const { buildGrammarContract } = await import(pathToFileURL(path.join(runtimeRoot, "grammar_contract.mjs")).href);
594
+ try {
595
+ const result = await buildGrammarContract({
596
+ components: [components],
597
+ children: [readOption(rest, "--children", "")],
598
+ instances: readOptions(rest, "--instance"),
599
+ groups: [readOption(rest, "--groups", "")],
600
+ conditions: readOptions(rest, "--when"),
601
+ compilerOracleHome: readOption(rest, "--compiler-oracle-home", readOption(rest, "--oracle-home", "")),
602
+ cacheDir: readOption(rest, "--cache-dir", ""),
603
+ useCache: !parseFlag(rest, "--no-cache"),
604
+ compilerOracleHome: readOption(rest, "--compiler-oracle-home", readOption(rest, "--oracle-home", ""))
605
+ });
606
+ console.log(JSON.stringify({ ...result.contract, cache: { status: result.cacheStatus, path: result.cachePath } }, null, 2));
607
+ return 0;
608
+ } catch (error) {
609
+ console.error(`APEXLANG_GRAMMAR_CONTRACT_FAILED ${error.message}`);
610
+ return 1;
611
+ }
612
+ }
613
+ if (namespace === "apexlang" && rest[0] === "grammar" && rest[1] === "audit") {
614
+ const components = readOption(rest, "--components", "");
615
+ const artifactPath = readOption(rest, "--artifact-path", "");
616
+ if (!components.trim() || !artifactPath.trim()) {
617
+ console.error("Missing required --components or --artifact-path");
618
+ return 1;
619
+ }
620
+ const { auditGrammarContract, buildGrammarContract } = await import(pathToFileURL(path.join(runtimeRoot, "grammar_contract.mjs")).href);
621
+ try {
622
+ const { contract } = await buildGrammarContract({
623
+ components: [components],
624
+ children: [readOption(rest, "--children", "")],
625
+ instances: readOptions(rest, "--instance"),
626
+ groups: [readOption(rest, "--groups", "")],
627
+ conditions: readOptions(rest, "--when"),
628
+ compilerOracleHome: readOption(rest, "--compiler-oracle-home", readOption(rest, "--oracle-home", "")),
629
+ cacheDir: readOption(rest, "--cache-dir", ""),
630
+ useCache: !parseFlag(rest, "--no-cache"),
631
+ compilerOracleHome: readOption(rest, "--compiler-oracle-home", readOption(rest, "--oracle-home", ""))
632
+ });
633
+ const audit = await auditGrammarContract({ contract, artifactPath });
634
+ console.log(JSON.stringify(audit, null, 2));
635
+ return audit.status === "passed" ? 0 : 1;
636
+ } catch (error) {
637
+ console.error(`APEXLANG_GRAMMAR_AUDIT_FAILED ${error.message}`);
638
+ return 1;
639
+ }
640
+ }
481
641
  if (namespace === "apexlang" && rest[0] === "compiler-truth" && rest[1] === "audit") {
482
642
  const auditToolPath = path.join(packageRoot, "tools", "compiler-truth-audit.mjs");
483
643
  const result = spawnSync("node", [
@@ -504,6 +664,9 @@ async function main() {
504
664
  if (namespace === "runtime") {
505
665
  return handleRuntime(packageRoot, runtimeModule, rest);
506
666
  }
667
+ if (namespace === "context") {
668
+ return handleContext(runRoot, rest);
669
+ }
507
670
  if (namespace === "diagnostics") {
508
671
  return handleDiagnostics(runtimeModule, rest);
509
672
  }
@@ -3,8 +3,12 @@
3
3
  import { promises as fs } from "node:fs";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath, pathToFileURL } from "node:url";
6
- import { buildOracleNormalizedMap, ORACLE_NORMALIZER_VERSION, readOracleRuntimeMetadata } from "./query-valid-props-normalize.mjs";
7
- import { resolveOracleRuntime } from "./query-valid-props-runtime.mjs";
6
+ import { loadOracleCompilerContext } from "./query-valid-props-context.mjs";
7
+ import {
8
+ normalizeSemanticValue,
9
+ resolveAuditComponentRecord as resolveRecordFor,
10
+ resolveAuditProperty
11
+ } from "./query-valid-props-semantics.mjs";
8
12
 
9
13
  const SCRIPT_PATH = fileURLToPath(import.meta.url);
10
14
  const IS_PACKAGED_ROOT = path.basename(path.dirname(SCRIPT_PATH)) === "tools";
@@ -29,14 +33,11 @@ const SUPPORTED_COMPONENTS = new Set([
29
33
  "process",
30
34
  "computation",
31
35
  "validation",
36
+ "lov",
32
37
  "list",
33
38
  "entry",
34
39
  "breadcrumb",
35
40
  ]);
36
- const COMPILER_METADATA_PROPERTY_ALIASES = new Map([
37
- ["app.authentication.scheme", "authenticationScheme"]
38
- ]);
39
-
40
41
  function defaultCommand() {
41
42
  return IS_PACKAGED_ROOT
42
43
  ? "node tools/compiler-truth-audit.mjs"
@@ -153,38 +154,21 @@ async function collectApxFiles(targetPath) {
153
154
  return files.sort();
154
155
  }
155
156
 
156
- function buildCompilerContext(oracleHome) {
157
- const oracleRuntime = resolveOracleRuntime(oracleHome || undefined);
158
- const { metadata, buildId, metadataHash } = readOracleRuntimeMetadata(oracleRuntime.compilerJarPath);
159
- const map = buildOracleNormalizedMap({
160
- metadata,
161
- compilerJarPath: oracleRuntime.compilerJarPath,
162
- oracleHome: oracleRuntime.oracleHome,
163
- source: oracleRuntime.source
164
- });
165
- const provenance = {
166
- buildID: buildId,
167
- metadataHash,
168
- normalizerVersion: ORACLE_NORMALIZER_VERSION,
169
- source: oracleRuntime.source,
170
- oracleHome: oracleRuntime.oracleHome,
171
- compilerJar: oracleRuntime.compilerJarPath
172
- };
173
- return { map, provenance };
174
- }
175
-
176
- function firstRecordFor(map, singular, parentSingular = "") {
177
- const records = map.componentTypes.filter((record) => record.singular === singular);
178
- if (!records.length) {
179
- return null;
180
- }
181
- if (parentSingular) {
182
- const parentMatch = records.find((record) => record.parentComponentType === parentSingular);
183
- if (parentMatch) {
184
- return parentMatch;
185
- }
157
+ function normalizePropertySemanticValue(property, value) {
158
+ const normalized = normalizeSemanticValue(value);
159
+ if (
160
+ property?.propertyId === "94" &&
161
+ property?.lov?.type === "PLUGINS" &&
162
+ String(normalized).startsWith("themeTemplateComponent/")
163
+ ) {
164
+ const pluginName = String(normalized).slice("themeTemplateComponent/".length);
165
+ return `TMPL_${pluginName}`;
186
166
  }
187
- return records.length === 1 ? records[0] : records[0];
167
+ const token = String(normalized).replace(/[^A-Za-z0-9]/g, "").toLowerCase();
168
+ const match = (property?.lov?.values || []).find(({ name, returnValue }) =>
169
+ [name, returnValue].some((candidate) =>
170
+ String(candidate ?? "").replace(/[^A-Za-z0-9]/g, "").toLowerCase() === token));
171
+ return match?.returnValue || normalized;
188
172
  }
189
173
 
190
174
  function nearestComponent(stack) {
@@ -255,26 +239,18 @@ function addIssue(issues, filePath, lineNumber, code, message, details = {}) {
255
239
  });
256
240
  }
257
241
 
258
- function compilerMetadataPropertyNames(componentName, groupName, propertyName) {
259
- const names = [propertyName];
260
- const scopedKey = groupName
261
- ? `${componentName}.${groupName}.${propertyName}`
262
- : `${componentName}.${propertyName}`;
263
- const alias = COMPILER_METADATA_PROPERTY_ALIASES.get(scopedKey);
264
- if (alias && !names.includes(alias)) {
265
- names.push(alias);
266
- }
267
- return names;
268
- }
269
-
270
242
  function validateProperty({ issues, filePath, lineNumber, componentFrame, groupFrame, propertyName }) {
271
243
  if (!componentFrame?.record || !propertyName) {
272
- return;
244
+ return null;
273
245
  }
274
- const compilerPropertyNames = compilerMetadataPropertyNames(componentFrame.name, groupFrame?.name || "", propertyName);
246
+ const { property: match, conditionState } = resolveAuditProperty({
247
+ record: componentFrame.record,
248
+ componentName: componentFrame.name,
249
+ groupName: groupFrame?.name || "",
250
+ propertyName,
251
+ props: componentFrame.props || {}
252
+ });
275
253
  if (groupFrame) {
276
- const props = componentFrame.record.groups[groupFrame.name] || [];
277
- const match = props.find((prop) => compilerPropertyNames.includes(prop.propertyName));
278
254
  if (!match) {
279
255
  addIssue(
280
256
  issues,
@@ -289,12 +265,27 @@ function validateProperty({ issues, filePath, lineNumber, componentFrame, groupF
289
265
  property: propertyName
290
266
  }
291
267
  );
268
+ return null;
292
269
  }
293
- return;
270
+ if (conditionState === "false") {
271
+ addIssue(
272
+ issues,
273
+ filePath,
274
+ lineNumber,
275
+ "COMPILER_TRUTH_PROP_INACTIVE",
276
+ `${componentFrame.name}.${groupFrame.name}.${propertyName} exists in compiler metadata but is inactive under current component assumptions`,
277
+ {
278
+ component: componentFrame.name,
279
+ componentTypeId: componentFrame.record.componentTypeId,
280
+ group: groupFrame.name,
281
+ property: propertyName
282
+ }
283
+ );
284
+ }
285
+ return match;
294
286
  }
295
287
 
296
- const anyMatch = componentFrame.record.properties.some((prop) => compilerPropertyNames.includes(prop.propertyName));
297
- if (!anyMatch) {
288
+ if (!match) {
298
289
  addIssue(
299
290
  issues,
300
291
  filePath,
@@ -307,7 +298,23 @@ function validateProperty({ issues, filePath, lineNumber, componentFrame, groupF
307
298
  property: propertyName
308
299
  }
309
300
  );
301
+ return null;
302
+ }
303
+ if (conditionState === "false") {
304
+ addIssue(
305
+ issues,
306
+ filePath,
307
+ lineNumber,
308
+ "COMPILER_TRUTH_PROP_INACTIVE",
309
+ `${componentFrame.name}.${propertyName} exists in compiler metadata but is inactive under current component assumptions`,
310
+ {
311
+ component: componentFrame.name,
312
+ componentTypeId: componentFrame.record.componentTypeId,
313
+ property: propertyName
314
+ }
315
+ );
310
316
  }
317
+ return match;
311
318
  }
312
319
 
313
320
  export function auditApxText(filePath, text, map) {
@@ -326,9 +333,9 @@ export function auditApxText(filePath, text, map) {
326
333
  const currentComponent = nearestComponent(stack);
327
334
  const currentGroup = nearestGroup(stack);
328
335
  const opaqueScope = insideOpaque(stack);
329
- const propMatch = trimmed.match(/^([A-Za-z][A-Za-z0-9]*)\s*:/);
336
+ const propMatch = trimmed.match(/^([A-Za-z][A-Za-z0-9]*)\s*:\s*(.*)$/);
330
337
  if (propMatch && currentComponent && !opaqueScope) {
331
- validateProperty({
338
+ const compilerProperty = validateProperty({
332
339
  issues,
333
340
  filePath,
334
341
  lineNumber,
@@ -336,9 +343,17 @@ export function auditApxText(filePath, text, map) {
336
343
  groupFrame: currentGroup,
337
344
  propertyName: propMatch[1]
338
345
  });
346
+ currentComponent.props ||= {};
347
+ const semanticValue = normalizePropertySemanticValue(compilerProperty, propMatch[2]);
348
+ if (currentComponent.props[propMatch[1]] === undefined) {
349
+ currentComponent.props[propMatch[1]] = semanticValue;
350
+ }
351
+ if (compilerProperty?.propertyId) {
352
+ currentComponent.props[String(compilerProperty.propertyId)] = semanticValue;
353
+ }
339
354
  }
340
355
 
341
- const blockMatch = trimmed.match(/^([A-Za-z][A-Za-z0-9]*)\b(?:\s+[^({]+?)?\s*([({])/);
356
+ const blockMatch = trimmed.match(/^([A-Za-z][A-Za-z0-9]*(?:-[A-Za-z][A-Za-z0-9]*)*)\b(?:\s+[^({]+?)?\s*([({])/);
342
357
  if (blockMatch) {
343
358
  const [, token, delimiter] = blockMatch;
344
359
  const parentComponent = nearestComponent(stack);
@@ -346,8 +361,25 @@ export function auditApxText(filePath, text, map) {
346
361
  const { opens, closes } = lineOpenCloseBalance(line);
347
362
  const shouldPush = opens > closes;
348
363
  if (delimiter === "(" && SUPPORTED_COMPONENTS.has(token)) {
349
- const record = firstRecordFor(map, token, parentName);
350
- if (record) {
364
+ const { record, failure, candidates } = resolveRecordFor(map, token, parentComponent);
365
+ if (!record) {
366
+ addIssue(
367
+ issues,
368
+ filePath,
369
+ lineNumber,
370
+ failure === "ambiguous" ? "COMPILER_TRUTH_COMPONENT_AMBIGUOUS" : "COMPILER_TRUTH_COMPONENT_UNKNOWN",
371
+ failure === "ambiguous"
372
+ ? `${token} resolves to multiple compiler component records; add parent/type context (${(candidates || []).map((record) => record.componentTypeId).join(", ")})`
373
+ : `${token} is not valid under parent ${parentName || "none"} for current compiler metadata assumptions`,
374
+ {
375
+ component: token,
376
+ parent: parentName || ""
377
+ }
378
+ );
379
+ if (shouldPush) {
380
+ stack.push({ kind: "component", name: token, record: null, props: {} });
381
+ }
382
+ } else {
351
383
  observations.push({
352
384
  file: path.relative(process.cwd(), filePath) || path.basename(filePath),
353
385
  line: lineNumber,
@@ -356,7 +388,7 @@ export function auditApxText(filePath, text, map) {
356
388
  parent: record.parentComponentType || ""
357
389
  });
358
390
  if (shouldPush) {
359
- stack.push({ kind: "component", name: token, record });
391
+ stack.push({ kind: "component", name: token, record, props: {} });
360
392
  }
361
393
  }
362
394
  } else if (delimiter === "{" && !opaqueScope && parentComponent?.record?.groups?.[token]) {
@@ -443,7 +475,7 @@ async function writeReport(reportPath, payload) {
443
475
  }
444
476
 
445
477
  export async function runCompilerTruthAudit(options = {}) {
446
- const { map, provenance } = buildCompilerContext(options.compilerOracleHome || options.oracleHome || "");
478
+ const { map, provenance } = loadOracleCompilerContext(options.compilerOracleHome || options.oracleHome || undefined);
447
479
  const issues = [];
448
480
  const observations = [];
449
481
  const targets = [];
@@ -0,0 +1,30 @@
1
+ import { buildOracleNormalizedMap, ORACLE_NORMALIZER_VERSION, readOracleRuntimeMetadata } from "./query-valid-props-normalize.mjs";
2
+ import { resolveOracleRuntime } from "./query-valid-props-runtime.mjs";
3
+
4
+ /**
5
+ * Load one compiler-backed MMD context with normalized metadata and provenance.
6
+ */
7
+ export function loadOracleCompilerContext(compilerOracleHome, dependencies = {}) {
8
+ const resolveRuntime = dependencies.resolveOracleRuntime || resolveOracleRuntime;
9
+ const readRuntimeMetadata = dependencies.readOracleRuntimeMetadata || readOracleRuntimeMetadata;
10
+ const buildNormalizedMap = dependencies.buildOracleNormalizedMap || buildOracleNormalizedMap;
11
+
12
+ const oracleRuntime = resolveRuntime(compilerOracleHome);
13
+ const { metadata, buildId, metadataHash } = readRuntimeMetadata(oracleRuntime.compilerJarPath);
14
+ const map = buildNormalizedMap({
15
+ metadata,
16
+ compilerJarPath: oracleRuntime.compilerJarPath,
17
+ oracleHome: oracleRuntime.oracleHome,
18
+ source: oracleRuntime.source
19
+ });
20
+ const provenance = {
21
+ buildID: buildId,
22
+ metadataHash,
23
+ normalizerVersion: ORACLE_NORMALIZER_VERSION,
24
+ source: oracleRuntime.source,
25
+ oracleHome: oracleRuntime.oracleHome,
26
+ compilerJar: oracleRuntime.compilerJarPath
27
+ };
28
+
29
+ return { map, provenance };
30
+ }
@@ -110,6 +110,7 @@ function buildComponentRecord(componentTypeId, componentType, metadata) {
110
110
  parentDependsOn: summarizeCondition(componentType.parent?.dependingOn, metadata),
111
111
  pluginPropertyId: componentType.plugin?.propertyId || null,
112
112
  pluginComponentTypeName: componentType.plugin?.componentTypeName || null,
113
+ pluginApiExpression: componentType.plugin?.api?.expression || null,
113
114
  propertyCount: properties.length,
114
115
  groups,
115
116
  properties
@@ -53,9 +53,14 @@ export function findSqlOnPath({
53
53
  }
54
54
 
55
55
  /**
56
- * Build ordered Oracle runtime candidates from flags, environment variables, VS Code extensions, and PATH SQLcl.
56
+ * Build ordered Oracle runtime candidates from flags, environment variables, PATH SQLcl, and VS Code extensions.
57
57
  */
58
- export function collectOracleHomeCandidates(explicitOracleHome) {
58
+ export function collectOracleHomeCandidates(explicitOracleHome, {
59
+ pathValue = process.env.PATH || "",
60
+ platform = process.platform,
61
+ pathExtValue = process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM",
62
+ homeDir = os.homedir()
63
+ } = {}) {
59
64
  const candidates = [];
60
65
  const seen = new Set();
61
66
 
@@ -82,7 +87,12 @@ export function collectOracleHomeCandidates(explicitOracleHome) {
82
87
  }
83
88
  }
84
89
 
85
- const vscodeExtensionsDir = path.join(os.homedir(), ".vscode", "extensions");
90
+ const resolvedSqlPath = findSqlOnPath({ pathValue, platform, pathExtValue });
91
+ if (resolvedSqlPath) {
92
+ addCandidate(path.dirname(path.dirname(resolvedSqlPath)), "path_sqlcl");
93
+ }
94
+
95
+ const vscodeExtensionsDir = path.join(homeDir, ".vscode", "extensions");
86
96
  if (fs.existsSync(vscodeExtensionsDir)) {
87
97
  const extensionDirs = fs.readdirSync(vscodeExtensionsDir, { withFileTypes: true })
88
98
  .filter((entry) => entry.isDirectory() && entry.name.startsWith("oracle.sql-developer-"))
@@ -93,11 +103,6 @@ export function collectOracleHomeCandidates(explicitOracleHome) {
93
103
  }
94
104
  }
95
105
 
96
- const resolvedSqlPath = findSqlOnPath();
97
- if (resolvedSqlPath) {
98
- addCandidate(path.dirname(path.dirname(resolvedSqlPath)), "path_sqlcl");
99
- }
100
-
101
106
  return candidates;
102
107
  }
103
108