@shundoo-ai/dsh-cosmic 1.0.19 → 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/cordis.patch.yml +5 -5
  2. package/package.json +1 -1
  3. package/skills/cosmic-build/CHANGELOG.md +4 -0
  4. package/skills/cosmic-build/LOCAL-PATCHES.md +91 -40
  5. package/skills/cosmic-build/SKILL.md +46 -13
  6. package/skills/cosmic-build/assets/platform-report-filters/TypedReportFilterFields.java +169 -0
  7. package/skills/cosmic-build/assets/platform-report-filters/platform.patch +98 -0
  8. package/skills/cosmic-build/assets/report-algo-benchmark/ReportAlgoBenchmark.java +48 -0
  9. package/skills/cosmic-build/assets/report-algo-benchmark/ReportBenchmarkLogFactory.java +7 -0
  10. package/skills/cosmic-build/examples/java-rules/CosmicEntryQuery.java +26 -0
  11. package/skills/cosmic-build/examples/java-rules/CosmicReportAggregation.java +35 -0
  12. package/skills/cosmic-build/examples/java-rules/CosmicReportFilters.java +77 -0
  13. package/skills/cosmic-build/examples/java-rules/CosmicTimeAdapter.java +25 -0
  14. package/skills/cosmic-build/examples/java-rules/CosmicTimeAdapterCheck.java +26 -0
  15. package/skills/cosmic-build/knowledge/cosmic/platform/api/algo/GroupbyDataSet.md +47 -0
  16. package/skills/cosmic-build/knowledge/cosmic/platform/api/entity/report/FilterInfo.md +12 -12
  17. package/skills/cosmic-build/knowledge/cosmic/platform/api/entity/report/FilterItemInfo.md +2 -0
  18. package/skills/cosmic-build/knowledge/cosmic/platform/form-plugin.md +2 -4
  19. package/skills/cosmic-build/knowledge/cosmic/platform/java-type-contracts.md +11 -2
  20. package/skills/cosmic-build/knowledge/cosmic/platform/list-plugin.md +18 -14
  21. package/skills/cosmic-build/knowledge/cosmic/platform/operation-plugin.md +4 -4
  22. package/skills/cosmic-build/knowledge/cosmic/platform/reportlistdata-plugin.md +17 -9
  23. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/operation/cross-entity-aggregate-writeback.md +2 -0
  24. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/operation/pre-post-operation.md +15 -7
  25. package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-algo.md +24 -68
  26. package/skills/cosmic-build/knowledge/cosmic/platform/workflow-plugin.md +2 -7
  27. package/skills/cosmic-build/references/application-context.md +35 -1
  28. package/skills/cosmic-build/references/common-reference.md +1 -1
  29. package/skills/cosmic-build/references/compile-guide.md +55 -68
  30. package/skills/cosmic-build/references/delivery.md +59 -7
  31. package/skills/cosmic-build/references/execution-contract.md +38 -0
  32. package/skills/cosmic-build/references/form-discovery.md +7 -1
  33. package/skills/cosmic-build/references/java-plugin-delivery.md +32 -162
  34. package/skills/cosmic-build/references/operation-dispatch.md +17 -0
  35. package/skills/cosmic-build/references/plugin-handoff-input.md +131 -0
  36. package/skills/cosmic-build/references/plugin-runtime-routing.md +1 -1
  37. package/skills/cosmic-build/references/report-filter-contract.md +78 -0
  38. package/skills/cosmic-build/references/sdk-inspection.md +23 -0
  39. package/skills/cosmic-build/schemas/data-model-authoring.schema.json +2 -3
  40. package/skills/cosmic-build/scripts/_http_client.py +55 -55
  41. package/skills/cosmic-build/scripts/appconfig_load.py +2 -2
  42. package/skills/cosmic-build/scripts/apply_report_filter_extension.py +39 -0
  43. package/skills/cosmic-build/scripts/bootstrap_cosmic_context.py +37 -2
  44. package/skills/cosmic-build/scripts/compile_plugin_source.py +279 -156
  45. package/skills/cosmic-build/scripts/execution_binding.py +40 -0
  46. package/skills/cosmic-build/scripts/inspect_platform_sdk.py +169 -0
  47. package/skills/cosmic-build/scripts/kd_api.py +23 -22
  48. package/skills/cosmic-build/scripts/kd_auth.py +1 -1
  49. package/skills/cosmic-build/scripts/kd_env_loader.py +19 -10
  50. package/skills/cosmic-build/scripts/kd_token_cache.py +2 -2
  51. package/skills/cosmic-build/scripts/kingscript_sdk_sync.py +350 -0
  52. package/skills/cosmic-build/scripts/kingscript_source_gate.py +11 -8
  53. package/skills/cosmic-build/scripts/platform_api_contract.py +246 -11
  54. package/skills/cosmic-build/scripts/plugin_corpus/build_index.py +403 -0
  55. package/skills/cosmic-build/scripts/plugin_corpus/jvm_classfile.py +281 -0
  56. package/skills/cosmic-build/scripts/plugin_corpus/measure_api_usage.py +446 -0
  57. package/skills/cosmic-build/scripts/plugin_source_gate.py +48 -7
  58. package/skills/cosmic-build/scripts/plugin_target_sdk.py +45 -0
  59. package/skills/cosmic-build/scripts/prepare_plugin_handoff.py +493 -47
  60. package/skills/cosmic-build/scripts/preview_url.py +35 -6
  61. package/skills/cosmic-build/scripts/query_plugin_handoff.py +250 -0
  62. package/skills/cosmic-build/scripts/register_plugins.py +28 -2
  63. package/skills/cosmic-build/scripts/render_output_cards.py +42 -9
  64. package/skills/cosmic-build/scripts/report_algo_benchmark.py +46 -0
  65. package/skills/cosmic-build/scripts/run.py +2 -2
  66. package/skills/cosmic-build/scripts/sync_generated_locale_assets.py +43 -0
  67. package/skills/cosmic-build/scripts/test/fixtures/ReportSdkCheck.java +64 -0
  68. package/skills/cosmic-build/scripts/test/fixtures/java_context_booking_native.json +541 -0
  69. package/skills/cosmic-build/scripts/test/test_add_rule_business_contract.py +85 -14
  70. package/skills/cosmic-build/scripts/test/test_batch5_drift_governance.py +12 -3
  71. package/skills/cosmic-build/scripts/test/test_build_meta_order.py +0 -16
  72. package/skills/cosmic-build/scripts/test/test_cli_continuation.py +87 -0
  73. package/skills/cosmic-build/scripts/test/test_compile_plugin_source.py +224 -3
  74. package/skills/cosmic-build/scripts/test/test_control_authoring.py +123 -4
  75. package/skills/cosmic-build/scripts/test/test_cosmic_sdk_examples.py +141 -0
  76. package/skills/cosmic-build/scripts/test/test_data_model_contract.py +30 -5
  77. package/skills/cosmic-build/scripts/test/test_delivery_stage_boundary.py +2 -10
  78. package/skills/cosmic-build/scripts/test/test_dym_sync_background.py +11 -0
  79. package/skills/cosmic-build/scripts/test/test_dynamic_form_metadata_only_contract.py +59 -1
  80. package/skills/cosmic-build/scripts/test/test_guide_skeleton_contract.py +87 -43
  81. package/skills/cosmic-build/scripts/test/test_inspect_platform_sdk.py +71 -0
  82. package/skills/cosmic-build/scripts/test/test_kd_api.py +67 -19
  83. package/skills/cosmic-build/scripts/test/test_kingscript_sdk_sync.py +221 -0
  84. package/skills/cosmic-build/scripts/test/test_kingscript_source_gate.py +10 -0
  85. package/skills/cosmic-build/scripts/test/test_list_configuration_closure.py +18 -0
  86. package/skills/cosmic-build/scripts/test/test_long_session_regressions.py +116 -0
  87. package/skills/cosmic-build/scripts/test/test_mcp_cli.py +524 -0
  88. package/skills/cosmic-build/scripts/test/test_modeling_input_recovery.py +141 -0
  89. package/skills/cosmic-build/scripts/test/test_open_world_cli_catalog.py +36 -2
  90. package/skills/cosmic-build/scripts/test/test_platform_api_contract.py +161 -1
  91. package/skills/cosmic-build/scripts/test/test_plugin_business_contract.py +91 -0
  92. package/skills/cosmic-build/scripts/test/test_plugin_corpus.py +195 -0
  93. package/skills/cosmic-build/scripts/test/test_plugin_handoff.py +346 -1
  94. package/skills/cosmic-build/scripts/test/test_plugin_target_sdk.py +70 -0
  95. package/skills/cosmic-build/scripts/test/test_preview_url.py +44 -1
  96. package/skills/cosmic-build/scripts/test/test_property_batch.py +22 -0
  97. package/skills/cosmic-build/scripts/test/test_property_input_discovery.py +13 -11
  98. package/skills/cosmic-build/scripts/test/test_query_plugin_handoff.py +160 -0
  99. package/skills/cosmic-build/scripts/test/test_register_plugins.py +31 -1
  100. package/skills/cosmic-build/scripts/test/test_render_output_cards.py +50 -4
  101. package/skills/cosmic-build/scripts/test/test_report_business_contract.py +27 -0
  102. package/skills/cosmic-build/scripts/test/test_report_doc_contract_sync.py +5 -4
  103. package/skills/cosmic-build/scripts/test/test_report_sdk_optimization.py +36 -0
  104. package/skills/cosmic-build/scripts/test/test_rule_batch_evidence.py +1 -1
  105. package/skills/cosmic-build/scripts/test/test_rule_domain_contract.py +20 -0
  106. package/skills/cosmic-build/scripts/test/test_rule_function_formula.py +16 -6
  107. package/skills/cosmic-build/scripts/test/test_skill_entry_contract.py +1 -0
  108. package/skills/cosmic-build/scripts/test/test_test_environment.py +45 -0
  109. package/skills/cosmic-build/scripts/test/test_verify_plugin_loading.py +79 -0
  110. package/skills/cosmic-build/scripts/test_environment.py +49 -0
  111. package/skills/cosmic-build/scripts/verify_plugin_loading.py +71 -0
  112. package/skills/cosmic-build/skills/cosmic-coding-impl/SKILL.md +86 -162
  113. package/skills/cosmic-build/skills/cosmic-coding-script/ATTRIBUTION.md +1 -1
  114. package/skills/cosmic-build/skills/cosmic-coding-script/SKILL.md +45 -14
  115. package/skills/cosmic-build/skills/cosmic-coding-script/references/kwc-controller-authoring.md +6 -0
  116. package/skills/cosmic-build/skills/cosmic-coding-script/references/sdk/README.md +29 -19
  117. package/skills/cosmic-build/skills/cosmic-coding-script/references/sdk/docs//350/204/232/346/234/254SDK.md +3 -4
  118. package/skills/cosmic-build/skills/cosmic-coding-script/references/sdk/indexes/package-index.md +1 -1
  119. package/skills/cosmic-build/skills/cosmic-coding-script/references/sdk/strategy.md +27 -18
  120. package/skills/cosmic-build/skills/cosmic-meta-api/SKILL.md +11 -17
  121. package/skills/cosmic-build/skills/cosmic-meta-api/apis/ai_meta.md +1 -1
  122. package/skills/cosmic-build/skills/cosmic-meta-api/apis/app_menu.md +1 -1
  123. package/skills/cosmic-build/skills/cosmic-meta-api/apis/meta_log.md +1 -1
  124. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/control-authoring.json +45 -4
  125. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/form-control-traits.json +1 -1
  126. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/layout-ui.json +18 -0
  127. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/menu-publish.json +8 -2
  128. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/property-batch.json +7 -0
  129. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/property-input-index.json +3 -3
  130. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/report-write-contracts.json +1 -0
  131. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/rule-domain.json +37 -5
  132. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/rule-event-contract.json +24 -3
  133. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/run-build-meta.json +61 -12
  134. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/dropdown-menu.schema.json +69 -0
  135. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/report-write.schema.json +2 -1
  136. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/rule-set.schema.json +1 -0
  137. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/rule-write.schema.json +14 -7
  138. package/skills/cosmic-build/skills/cosmic-meta-api/docs/api-summary.md +2 -2
  139. package/skills/cosmic-build/skills/cosmic-meta-api/modules/app-action/SKILL.md +6 -3
  140. package/skills/cosmic-build/skills/cosmic-meta-api/modules/develop/SKILL.md +1 -2
  141. package/skills/cosmic-build/skills/cosmic-meta-api/modules/export/SKILL.md +5 -6
  142. package/skills/cosmic-build/skills/cosmic-meta-api/modules/init/SKILL.md +13 -36
  143. package/skills/cosmic-build/skills/cosmic-meta-api/modules/pdm/SKILL.md +8 -9
  144. package/skills/cosmic-build/skills/cosmic-meta-api/modules/pdm/scripts/config.json.example +5 -15
  145. package/skills/cosmic-build/skills/cosmic-meta-api/modules/reset/SKILL.md +6 -6
  146. package/skills/cosmic-build/skills/cosmic-meta-api/modules/usage/SKILL.md +20 -148
  147. package/skills/cosmic-build/skills/cosmic-meta-api/modules/verify/SKILL.md +1 -1
  148. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/build_receipts.py +171 -0
  149. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_apps.py +25 -6
  150. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_controls.py +55 -21
  151. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_fields.py +10 -3
  152. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_formactions.py +63 -6
  153. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_forms.py +59 -2
  154. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_listui.py +8 -0
  155. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_metaops.py +36 -1
  156. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_plugins.py +115 -90
  157. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_properties.py +666 -4
  158. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_rules.py +1415 -87
  159. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/commands.py +6 -1
  160. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/config.py +28 -15
  161. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/execution_errors.py +40 -0
  162. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/formatters.py +32 -5
  163. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/property_policy_contract.py +6 -0
  164. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/report_ops.py +113 -17
  165. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/reset.py +3 -3
  166. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/rule_contract.py +107 -26
  167. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/build_meta_order.py +50 -49
  168. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/cosmic_api.py +856 -150
  169. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/field_decorator.py +47 -14
  170. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_build_receipt_resume.py +374 -0
  171. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_cli_failure_contract.py +24 -0
  172. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_creation_identity_boundary.py +4 -2
  173. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_dropdown_menu_contract.py +382 -0
  174. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_existing_form_ui.py +0 -25
  175. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_field_decorator.py +50 -6
  176. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_functional_group_resolution.py +83 -16
  177. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_identity_template_resolution.py +103 -0
  178. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_plugin_contract.py +28 -2
  179. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_readback_derivation.py +22 -0
  180. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_typed_filters.py +65 -0
  181. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_rule_write_closure.py +1041 -15
  182. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_batch_post_build_recovery.py +65 -0
  183. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_batch_verification_evidence.py +17 -0
  184. package/skills/cosmic-build/skills/cosmic-meta-knowledge/generation/api-param-checklist.md +1 -1
  185. package/skills/cosmic-build/skills/cosmic-meta-knowledge/generation/rule-modeling-guide.md +7 -4
  186. package/skills/cosmic-build/skills/cosmic-meta-modeling/SKILL.md +61 -13
  187. package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/app-menu/SKILL.md +8 -0
  188. package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/formtemplate/SKILL.md +5 -0
  189. package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/formtemplate/dynamic-form-artifact-schema.md +5 -0
  190. package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/SKILL.md +21 -9
  191. package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-entity-graphs.md +1 -1
  192. package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-storage-constraints.md +5 -3
  193. package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-ui-composition.md +6 -3
  194. package/skills/cosmic-build/skills/cosmic-meta-modeling/references/creation-recovery.md +13 -0
  195. package/skills/cosmic-build/skills/cosmic-meta-modeling/references/parse-core.md +3 -0
  196. package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/data_model_contract.py +6 -1
  197. package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/data_model_emit.py +135 -87
  198. package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/field_type_registry.py +11 -1
  199. package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/isv_resolver.py +1 -3
  200. package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/report_validator.py +29 -0
  201. package/skills/cosmic-build/skills/cosmic-meta-modifier/SKILL.md +4 -2
  202. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/context/SKILL.md +2 -2
  203. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/execute/SKILL.md +1 -1
  204. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/operation/SKILL.md +5 -4
  205. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/operation/operation-write.md +6 -2
  206. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/operation/validation.md +2 -0
  207. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/property/SKILL.md +20 -5
  208. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/property/complex-apis.md +1 -1
  209. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/property/policy-grammar.md +4 -1
  210. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/report-op/SKILL.md +9 -0
  211. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/SKILL.md +61 -4
  212. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/raw-rule-authoring.md +3 -1
  213. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/rule-actions.md +2 -2
  214. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/rule-reference.md +6 -6
  215. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/state.md +1 -1
  216. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/unit/SKILL.md +6 -3
  217. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/verify/usage-guide.md +4 -4
  218. package/skills/cosmic-build/skills/cosmic-meta-modifier/references/list-filter-modification.md +4 -1
  219. package/skills/cosmic-build/skills/cosmic-meta-ui/SKILL.md +9 -1
  220. package/skills/cosmic-build/skills/cosmic-meta-ui/modules/button/SKILL.md +3 -0
  221. package/skills/cosmic-build/skills/mcp-server/SKILL.md +210 -0
  222. package/skills/cosmic-build/skills/mcp-server/scripts/mcp_cli.py +431 -0
  223. package/skills/cosmic-build/skills/openapi-gen/SKILL.md +3 -3
  224. package/skills/cosmic-build/skills/openapi-gen/scripts/api/gen_runner.py +2 -2
  225. package/skills/cosmic-dev-best-practices/references/bill-dev-convention.md +19 -9
  226. package/skills/cosmic-dev-best-practices/references/cosmic-meta-api.md +14 -11
  227. package/skills/cosmic-dev-best-practices/references/design-examples/basedata-design-example.md +1 -1
  228. package/skills/cosmic-dev-best-practices/references/design-examples/bill-design-example.md +1 -1
  229. package/skills/cosmic-dev-best-practices/references/elements/AssistantField.md +1 -1
  230. package/skills/cosmic-dev-best-practices/references/elements/BasedataField.md +2 -2
  231. package/skills/cosmic-dev-best-practices/references/elements/BasedataPropField.md +3 -3
  232. package/skills/cosmic-dev-best-practices/references/elements/CreaterField.md +2 -2
  233. package/skills/cosmic-dev-best-practices/references/elements/CurrencyField.md +2 -2
  234. package/skills/cosmic-dev-best-practices/references/elements/CustomerField.md +2 -2
  235. package/skills/cosmic-dev-best-practices/references/elements/FlexField.md +1 -1
  236. package/skills/cosmic-dev-best-practices/references/elements/MaterielField.md +2 -2
  237. package/skills/cosmic-dev-best-practices/references/elements/OrgField.md +2 -2
  238. package/skills/cosmic-dev-best-practices/references/elements/SupplierField.md +2 -2
  239. package/skills/cosmic-dev-best-practices/references/elements/UnitField.md +1 -1
  240. package/skills/cosmic-dev-best-practices/references/elements/UserField.md +3 -3
  241. package/skills/cosmic-dev-best-practices/references/elements/common-field-property-conventions.md +16 -11
  242. package/skills/cosmic-dev-best-practices/references/layout-control-convention.md +5 -4
  243. package/skills/erp-analysis/references/delivery-contract.md +4 -2
  244. package/skills/erp-analysis/templates/AGENTS.template.md +1 -1
  245. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/.dsh/cosmic/.kd/config.json +0 -21
@@ -120,10 +120,15 @@ _FRONT_MATTER_FIELD_RE = re.compile(r'^(?P<key>\w+):\s*"?(?P<value>[^"\n]*)"?\s*
120
120
  # One registered signature inside a ```java block. The return type may carry generics or array
121
121
  # markers; the generic body excludes parentheses so it can never swallow the parameter list. The
122
122
  # parameter list closes on the same line: every page signature is written that way, and requiring
123
- # the closing parenthesis keeps a prose fragment from parsing as a signature.
123
+ # the closing parenthesis keeps a prose fragment from parsing as a signature. A generic method
124
+ # declares its type parameters before the return type (`public <T extends Control> T
125
+ # getControl(String key)`); without that optional group IFormView.getControl and
126
+ # IDataModel.getContextVariable looked unregistered, and an ordinary call to either was reported
127
+ # as a remembered spelling of some other member.
124
128
  _SIGNATURE_RE = re.compile(
125
129
  r"^\s*(?:public|protected)\s+"
126
130
  r"(?:(?:static|final|abstract|synchronized|native|default|strictfp)\s+)*"
131
+ r"(?:(?P<tparams><[^;{}()]*>)\s+)?"
127
132
  r"(?P<ret>[\w.$]+(?:\s*<[^;{}()]*>)?(?:\s*\[\s*\])*)\s+"
128
133
  r"(?P<name>[A-Za-z_$][\w$]*)\s*\((?P<params>[^)]*)\)",
129
134
  re.MULTILINE,
@@ -153,6 +158,26 @@ _ALWAYS_ASSIGNABLE = {"Object", "var"}
153
158
  _GENERIC_RE = re.compile(r"<[^<>]*>")
154
159
 
155
160
 
161
+ def _type_variables(type_parameters: str) -> set[str]:
162
+ """`<T extends Control, K>` -> {"T", "K"}: only top-level names, not bounds."""
163
+ body = type_parameters.strip()[1:-1]
164
+ names, depth, current = set(), 0, ""
165
+ for char in body + ",":
166
+ if char == "<":
167
+ depth += 1
168
+ elif char == ">":
169
+ depth -= 1
170
+ elif char == "," and depth == 0:
171
+ match = re.match(r"\s*([A-Za-z_$][\w$]*)", current)
172
+ if match:
173
+ names.add(match.group(1))
174
+ current = ""
175
+ continue
176
+ if depth == 0:
177
+ current += char
178
+ return names
179
+
180
+
156
181
  def _normalized(type_text: str) -> str:
157
182
  """A type as a signature comparison sees it: no package, no generics, array markers kept."""
158
183
  bare = type_text.strip()
@@ -195,10 +220,16 @@ def _page(fqcn: str) -> dict | None:
195
220
  # a no-argument signature and stays registered, because "overrides nothing" is exactly the
196
221
  # finding for a no-arg method that declares a parameter.
197
222
  signatures: dict[str, set[tuple[str, ...]]] = {}
223
+ # Names with an overload whose return type is one of its own type variables: the caller's
224
+ # declared type is the type argument, so no declared type contradicts that overload.
225
+ generic_returns: set[str] = set()
198
226
  for match in _SIGNATURE_RE.finditer(text):
199
227
  returns.setdefault(match.group("name"), set()).add(_normalized(match.group("ret")))
200
228
  signatures.setdefault(match.group("name"), set()).add(
201
229
  tuple(_param_types(match.group("params"))))
230
+ if match.group("tparams") and _normalized(match.group("ret")).rstrip("[]") in _type_variables(
231
+ match.group("tparams")):
232
+ generic_returns.add(match.group("name"))
202
233
  supertypes: set[str] = set()
203
234
  for match in _SUPERTYPE_RE.finditer(text[: front.end() + 4000]):
204
235
  supertypes.update(_TYPE_TOKEN_RE.findall(match.group("names")))
@@ -207,9 +238,11 @@ def _page(fqcn: str) -> dict | None:
207
238
  "className": class_name,
208
239
  "fqcn": fqcn,
209
240
  "returns": returns,
241
+ "genericReturns": generic_returns,
210
242
  "signatures": signatures,
211
243
  "supertypes": supertypes,
212
244
  "path": path,
245
+ "text": text,
213
246
  }
214
247
 
215
248
 
@@ -236,6 +269,168 @@ def _page_by_simple_name(simple_name: str) -> dict | None:
236
269
  return _page(f"{PLATFORM_PACKAGE}{relative}.{simple_name}" if relative else f"{PLATFORM_PACKAGE}{simple_name}")
237
270
 
238
271
 
272
+ def describe_api(selector: str, members: list[str] | None = None) -> dict:
273
+ """Expose bounded API evidence for one receiver, including inherited declarations."""
274
+ page = _page(selector) if "." in selector else _page_by_simple_name(selector)
275
+ if page is None:
276
+ candidate = _page_by_simple_name(selector.rsplit(".", 1)[-1]) if "." in selector else None
277
+ return {"status": False, "errorCode": "API_CLASS_NOT_DOCUMENTED", "class": selector,
278
+ "message": "No unique registered API page; this does not prove the class is absent from the SDK.",
279
+ "sdkLookup": {"script": str(Path(__file__).with_name("inspect_platform_sdk.py")),
280
+ "arguments": ["--class", selector, "--sdk-dir", "<bound target SDK directory>",
281
+ *[arg for member in members or [] for arg in ("--member", member)]]},
282
+ **({"candidateClass": candidate["fqcn"], "candidateReference": str(candidate["path"])} if candidate else {})}
283
+ evidence = []
284
+ sources = {}
285
+ seen = set()
286
+ for owner in _lineage_pages(page["fqcn"]):
287
+ sections = re.split(r"(?m)^###\s+", owner["text"])
288
+ notes = {section.splitlines()[0].strip(): section.split("```", 1)[0].split("\n", 1)[-1].strip()
289
+ for section in sections[1:]}
290
+ for match in _SIGNATURE_RE.finditer(owner["text"]):
291
+ name = match.group("name")
292
+ identity = (name, tuple(_param_types(match.group("params"))))
293
+ if identity in seen or members and name not in members:
294
+ continue
295
+ seen.add(identity)
296
+ note = notes.get(name, "")
297
+ evidence.append({"name": name, "declaredBy": owner["fqcn"],
298
+ "signature": re.sub(r"\s+", " ", match.group(0)).strip(),
299
+ "deprecated": bool(re.search(r"deprecated|已弃用|废弃|过时", note, re.IGNORECASE)),
300
+ "notes": note[:600]})
301
+ sources[owner["fqcn"]] = str(owner["path"])
302
+ found = {item["name"] for item in evidence}
303
+ return {"status": True, "class": page["fqcn"], "import": "import " + page["fqcn"] + ";",
304
+ "reference": str(page["path"]), "members": evidence, "sources": sources,
305
+ "undocumentedMembers": [name for name in members or [] if name not in found],
306
+ **({"sdkLookup": {"script": str(Path(__file__).with_name("inspect_platform_sdk.py")),
307
+ "arguments": ["--class", page["fqcn"], "--sdk-dir", "<bound target SDK directory>",
308
+ *[arg for name in members or [] if name not in found for arg in ("--member", name)]]}}
309
+ if any(name not in found for name in members or []) else {}),
310
+ "evidenceScope": "Registered declarations and documented supertypes; undocumented members are not proof of SDK absence."}
311
+
312
+
313
+ def plugin_coding_evidence(plugin_type: str, scenes: list[str] | None = None) -> dict:
314
+ """Resolve coding references from the existing type and API registries."""
315
+ registry = json.loads(TYPE_REGISTRY_PAGE.read_text(encoding="utf-8-sig"))
316
+ definition = next((item for item in registry["types"] if item["type"] == plugin_type), None)
317
+ if definition is None:
318
+ return {}
319
+ root = TYPE_REGISTRY_PAGE.parent.parent
320
+ evidence = {
321
+ "codingEntry": str(root / "skills" / "cosmic-coding-impl" / "SKILL.md"),
322
+ "guide": str(root / definition["guide"]) if definition.get("guide") else None,
323
+ "typeKnowledge": str(TYPE_CONTRACTS_PAGE),
324
+ "standards": str(STANDARDS_PAGE),
325
+ "filterOperators": [{"literal": literal, "constant": "QCP." + constant, "preferred": preferred}
326
+ for literal, (constant, preferred) in _qcp_constants().items()],
327
+ "apiLookup": {"script": str(Path(__file__).resolve()),
328
+ "arguments": ["--describe-class", "<receiver class>", "--member", "<required member>"]},
329
+ "sdkLookup": {"script": str(Path(__file__).with_name("inspect_platform_sdk.py")),
330
+ "arguments": ["--class", "<receiver class>", "--sdk-dir", "<bound target SDK directory>",
331
+ "--member", "<required member>"]},
332
+ }
333
+ if plugin_type == "operation":
334
+ evidence["operationDispatch"] = {
335
+ "transactionEvent": {"class": "kd.bos.entity.plugin.args.OperationArgs", "accessor": "event.getOperationKey()",
336
+ "reference": describe_api("kd.bos.entity.plugin.args.OperationArgs")["reference"]},
337
+ "validator": {"class": "kd.bos.entity.validate.AbstractValidator", "accessor": "this.getOperateKey()",
338
+ "reference": describe_api("kd.bos.entity.validate.AbstractValidator")["reference"]},
339
+ "guide": str(root / "references" / "operation-dispatch.md"),
340
+ "evidenceScope": "8.0 SDK accessor signatures checked with javap; these do not verify any operateMeta Map key or actual event execution",
341
+ }
342
+ base = definition.get("baseImport")
343
+ if base:
344
+ evidence["baseContract"] = describe_api(base)
345
+ evidence["baseContract"]["members"] = [
346
+ {key: value for key, value in item.items() if key != "notes" or item["deprecated"]}
347
+ for item in evidence["baseContract"].get("members", [])
348
+ ]
349
+ guide_text = (root / definition["guide"]).read_text(encoding="utf-8-sig")
350
+ guide_signatures = list(_SIGNATURE_RE.finditer(guide_text))
351
+ evidence["guideSignatures"] = list(dict.fromkeys(
352
+ re.sub(r"\s+", " ", match.group(0)).strip() for match in guide_signatures
353
+ ))
354
+ parameters = {}
355
+ for match in guide_signatures:
356
+ for parameter in _param_types(match.group("params")):
357
+ page = _page_by_simple_name(parameter.removesuffix("[]"))
358
+ if page:
359
+ parameters[page["fqcn"]] = {"class": page["fqcn"], "reference": str(page["path"])}
360
+ for owner in _lineage_pages(base):
361
+ for signatures in owner["signatures"].values():
362
+ for signature in signatures:
363
+ for parameter in signature:
364
+ page = _page_by_simple_name(parameter.removesuffix("[]"))
365
+ if page:
366
+ parameters[page["fqcn"]] = {"class": page["fqcn"], "reference": str(page["path"])}
367
+ evidence["parameterTypes"] = sorted(parameters.values(), key=lambda item: item["class"])
368
+ scene_root = (root / "knowledge" / "cosmic" / "platform" / "scenes").resolve()
369
+ selected = []
370
+ apis: dict[str, set[str]] = {}
371
+ for selector in scenes or []:
372
+ target = (scene_root / (selector if selector.endswith(".md") else selector + ".md")).resolve()
373
+ if not target.is_relative_to(scene_root) or not target.is_file():
374
+ raise ValueError(f"unknown coding scene: {selector}")
375
+ selected.append(str(target))
376
+ text = target.read_text(encoding="utf-8-sig")
377
+ # Scene metadata and its explicit evidence links are existing knowledge authorities.
378
+ references = re.findall(r"`((?:data-access|operation)/[A-Za-z0-9_/.-]+\.md)`", text)
379
+ texts = [text] + [(scene_root / reference).read_text(encoding="utf-8-sig")
380
+ for reference in references if (scene_root / reference).is_file()]
381
+ for content in texts:
382
+ related = re.search(r"(?m)^related_apis:\s*\[([^]]*)\]", content)
383
+ tokens = [token.strip().strip("\"'") for token in
384
+ (related.group(1).split(",") if related else [])]
385
+ owners = [token for token in tokens if _page_by_simple_name(token)]
386
+ for owner in owners:
387
+ apis.setdefault(owner, set()).update(token for token in tokens
388
+ if re.fullmatch(r"[a-z][A-Za-z0-9_]*", token))
389
+ for token in tokens:
390
+ value = token
391
+ owner, separator, member = value.partition(".")
392
+ if not _page_by_simple_name(owner):
393
+ continue
394
+ apis.setdefault(owner, set())
395
+ if separator:
396
+ apis[owner].add(member)
397
+ for owner, member in re.findall(r"\b([A-Z][A-Za-z0-9_]*)\.([a-z][A-Za-z0-9_]*)\s*\(", content):
398
+ if _page_by_simple_name(owner):
399
+ apis.setdefault(owner, set()).add(member)
400
+ if selected:
401
+ evidence["scenes"] = selected
402
+ evidence["apiContracts"] = [describe_api(owner, sorted(members))
403
+ for owner, members in sorted(apis.items()) if members
404
+ and _page_by_simple_name(owner)["fqcn"] != base]
405
+ for contract in evidence["apiContracts"]:
406
+ contract["members"] = [{key: value for key, value in item.items()
407
+ if key != "notes" or item["deprecated"]}
408
+ for item in contract.get("members", [])]
409
+ # Parameter evidence alone misses types such as AbstractValidator.getDataEntities()'s
410
+ # ExtendedDataEntity[] return value. Resolve only names proven by a unique SDK page.
411
+ signature_types = {item["class"]: {**item, "import": "import " + item["class"] + ";"}
412
+ for item in evidence.get("parameterTypes", [])}
413
+ signatures = evidence.get("guideSignatures", []) + [
414
+ member["signature"] for contract in
415
+ [evidence.get("baseContract", {}), *evidence.get("apiContracts", [])]
416
+ for member in contract.get("members", [])
417
+ ]
418
+ for signature in signatures:
419
+ match = _SIGNATURE_RE.search(signature)
420
+ if not match:
421
+ continue
422
+ for name in re.findall(r"\b(?:kd\.bos\.[\w.$]+|[A-Z][\w$]*)\b",
423
+ match.group("ret") + " " + match.group("params")):
424
+ page = _page(name) if "." in name else _page_by_simple_name(name)
425
+ if page:
426
+ signature_types[page["fqcn"]] = {
427
+ "class": page["fqcn"], "import": "import " + page["fqcn"] + ";",
428
+ "reference": str(page["path"]),
429
+ }
430
+ evidence["signatureTypes"] = sorted(signature_types.values(), key=lambda item: item["class"])
431
+ return evidence
432
+
433
+
239
434
  def _imports(code: str) -> dict[str, str]:
240
435
  resolved: dict[str, str] = {}
241
436
  for match in _IMPORT_RE.finditer(code):
@@ -285,9 +480,10 @@ def return_type_issues(source_text: str) -> list[dict]:
285
480
  if not page:
286
481
  continue
287
482
  registered = page["returns"].get(match.group("method"))
288
- if not registered:
483
+ if not registered or match.group("method") in page["genericReturns"]:
289
484
  # The overload set may simply be unregistered — the javadoc export omits everything
290
- # that is not @SdkPublic. Unknown is not wrong.
485
+ # that is not @SdkPublic. Unknown is not wrong. A generic return (`<T> T`) takes its
486
+ # type from the declaration, so the declared type is never a contradiction.
291
487
  continue
292
488
  end = _call_end(code, code.index("(", match.end() - 1))
293
489
  if end is None or code[end:].lstrip()[:1] != ";":
@@ -409,6 +605,13 @@ def filter_operator_issues(source_text: str) -> list[dict]:
409
605
  continue
410
606
  operator = _OPERATOR_ARG_RE.match(arguments[1])
411
607
  if not operator:
608
+ # Confirmed javac failure from the recorded delivery; do not treat this typo as a
609
+ # valid constant or offer a string literal that would trigger the next guard.
610
+ if (arguments[1] == "kd.bos.orm.query.QCP.equal" or arguments[1] == "QCP.equal"
611
+ and _imports(code).get("QCP") == "kd.bos.orm.query.QCP") and "=" in constants:
612
+ issues.append({"line": code[:match.start()].count("\n") + 1,
613
+ "operator": arguments[1], "constant": "QCP." + constants["="][0],
614
+ "message": "QCP.equal is not the SDK equality constant; use QCP.equals. Keep the typed operator instead of replacing it with a string."})
412
615
  # Already a constant, or a variable / concatenation this scan must not judge.
413
616
  continue
414
617
  entry = constants.get(operator.group("operator").strip().lower())
@@ -564,7 +767,7 @@ _PROPERTY_WRITE_RE = re.compile(
564
767
  r"(?:\bgetModel\s*\(\s*\)\s*\.\s*setValue|\.\s*setValueFast)\s*\(")
565
768
  _PROPERTY_GUARD_RE = re.compile(r"getProperty\s*\(\s*\)|getChangeSet\s*\(\s*\)")
566
769
 
567
- _OPERATION_PLUGIN_RE = re.compile(r"\bextends\s+AbstractOperationServicePlugIn\b")
770
+ _OPERATION_PLUGIN_RE = re.compile(r"\bextends\s+(?:[\w$]+\.)*AbstractOperationServicePlugIn\b")
568
771
  # The plugin's own inherited accessor, not the one on an event argument. The lookbehind rejects any
569
772
  # qualified call so `e.getDataEntities()` — the correct form — is never matched, while `this.` is
570
773
  # matched explicitly.
@@ -618,17 +821,22 @@ def scene_misuse_issues(source_text: str) -> list[dict]:
618
821
  "write when the new value already equals the current one",
619
822
  )
620
823
 
621
- # `AbstractValidator` declares a `getDataEntities()` of its own that is correct to call, and a
622
- # validator is routinely written in the same file as the operation plugin that adds it. The two
623
- # are indistinguishable without class-level scoping, so the presence of a validator waives this
624
- # rule for the file: missing one null dereference costs a stack trace, while reporting the
625
- # validator's correct call would block a delivery that has nothing wrong with it.
626
- if _OPERATION_PLUGIN_RE.search(code) and "AbstractValidator" not in code:
824
+ # A validator's same-named method is valid; determine the actual enclosing receiver
825
+ # instead of waiving the operation-plugin check for the entire file.
826
+ classes = _class_bodies(code)
827
+ if _OPERATION_PLUGIN_RE.search(code):
627
828
  for match in _INHERITED_DATA_ENTITIES_RE.finditer(code):
628
829
  # Only a call inside a method body: the same text outside one is the class declaring
629
830
  # its own override, which is not this defect.
630
831
  if not any(body["start"] <= match.start() < body["end"] for body in bodies):
631
832
  continue
833
+ scopes = [scope for scope in classes if scope["start"] <= match.start() < scope["end"]]
834
+ qualifier = re.search(r"([A-Za-z_$][\w$]*)\s*\.\s*$", code[:match.start()])
835
+ if qualifier:
836
+ scopes = [scope for scope in scopes if scope["name"] == qualifier.group(1)]
837
+ owner = max(scopes, key=lambda scope: scope["start"]) if scopes else None
838
+ if not owner or owner["base"].rsplit(".", 1)[-1] != "AbstractOperationServicePlugIn":
839
+ continue
632
840
  add(
633
841
  match.start(),
634
842
  "AbstractOperationServicePlugIn.getDataEntities",
@@ -642,6 +850,26 @@ def scene_misuse_issues(source_text: str) -> list[dict]:
642
850
  return issues
643
851
 
644
852
 
853
+ def _class_bodies(code: str) -> list[dict]:
854
+ """Locate named and anonymous class scopes in comment/literal-free Java."""
855
+ pattern = re.compile(
856
+ r"\b(?:class\s+(?P<name>[\w$]+)(?:\s+extends\s+(?P<base>[\w$.]+))?[^;{}]*"
857
+ r"|new\s+(?P<anonymous>[\w$.]+)\s*\([^;{}]*\))\s*\{")
858
+ scopes = []
859
+ for match in pattern.finditer(code):
860
+ opening = match.end() - 1
861
+ depth = 1
862
+ end = opening + 1
863
+ while end < len(code) and depth:
864
+ depth += (code[end] == "{") - (code[end] == "}")
865
+ end += 1
866
+ if depth == 0:
867
+ scopes.append({"name": match.group("name"),
868
+ "base": match.group("base") or match.group("anonymous") or "",
869
+ "start": opening + 1, "end": end - 1})
870
+ return scopes
871
+
872
+
645
873
  # The outermost class declaration's `extends` clause. Generic bounds are skipped rather than
646
874
  # parsed: a plugin class never carries them, and a missed base is one finding fewer, never a
647
875
  # false one.
@@ -1177,8 +1405,15 @@ def unverified_member_issues(source_text: str) -> list[dict]:
1177
1405
  def main() -> int:
1178
1406
  parser = argparse.ArgumentParser(
1179
1407
  description="Check platform API contracts in one Java plugin source")
1180
- parser.add_argument("--source-path", required=True)
1408
+ mode = parser.add_mutually_exclusive_group(required=True)
1409
+ mode.add_argument("--source-path")
1410
+ mode.add_argument("--describe-class", action="append", help="Exact SDK class name or fully qualified name; repeat to batch lookups")
1411
+ parser.add_argument("--member", action="append", help="Limit API evidence to named members")
1181
1412
  args = parser.parse_args()
1413
+ if args.describe_class:
1414
+ results = [describe_api(selector, args.member) for selector in args.describe_class]
1415
+ print(json.dumps({"status": all(item["status"] for item in results), "classes": results}, ensure_ascii=False))
1416
+ return 0 if all(item["status"] for item in results) else 2
1182
1417
  source = Path(args.source_path)
1183
1418
  if not source.is_file():
1184
1419
  print(json.dumps({