kcode-pi 0.1.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 (219) hide show
  1. package/README.md +358 -0
  2. package/dist/cli/kcode.d.ts +15 -0
  3. package/dist/cli/kcode.js +153 -0
  4. package/dist/cli/main.d.ts +2 -0
  5. package/dist/cli/main.js +7 -0
  6. package/docs/KCODE_DISTRIBUTION.md +91 -0
  7. package/extensions/kingdee-harness.ts +180 -0
  8. package/extensions/kingdee-header.ts +122 -0
  9. package/extensions/kingdee-tools.ts +379 -0
  10. package/knowledge/.backup/v1.0.0/version.json +10 -0
  11. package/knowledge/cangqiong/product-notes.md +15 -0
  12. package/knowledge/common/business-flows.md +115 -0
  13. package/knowledge/common/config-guides.md +110 -0
  14. package/knowledge/common/error-patterns.md +170 -0
  15. package/knowledge/common/implementation.md +144 -0
  16. package/knowledge/cosmic/hard-constraints.md +38 -0
  17. package/knowledge/cosmic/ksql-datafix.md +34 -0
  18. package/knowledge/cosmic/platform-baseline.md +32 -0
  19. package/knowledge/cosmic/plugin-decision-matrix.md +40 -0
  20. package/knowledge/cosmic/review-checklist.md +40 -0
  21. package/knowledge/cosmic/unittest.md +35 -0
  22. package/knowledge/enterprise/api-reference.md +186 -0
  23. package/knowledge/enterprise/code-patterns.md +217 -0
  24. package/knowledge/enterprise/plugin-lifecycle.md +188 -0
  25. package/knowledge/enterprise/tables.json +159 -0
  26. package/knowledge/flagship/api-reference.md +237 -0
  27. package/knowledge/flagship/code-patterns.md +246 -0
  28. package/knowledge/flagship/cosmic-platform-note.md +15 -0
  29. package/knowledge/flagship/plugin-lifecycle.md +248 -0
  30. package/knowledge/flagship/tables.json +159 -0
  31. package/knowledge/version.json +10 -0
  32. package/knowledge/xinghan/product-notes.md +15 -0
  33. package/package.json +71 -0
  34. package/prompts/kd-discuss.md +11 -0
  35. package/prompts/kd-execute.md +12 -0
  36. package/prompts/kd-plan.md +12 -0
  37. package/prompts/kd-ship.md +12 -0
  38. package/prompts/kd-spec.md +12 -0
  39. package/prompts/kd-verify.md +12 -0
  40. package/skills/kd-check/SKILL.md +26 -0
  41. package/skills/kd-cosmic-dev/SKILL.md +82 -0
  42. package/skills/kd-cosmic-review/SKILL.md +90 -0
  43. package/skills/kd-cosmic-unittest/SKILL.md +92 -0
  44. package/skills/kd-debug/SKILL.md +30 -0
  45. package/skills/kd-discuss/SKILL.md +24 -0
  46. package/skills/kd-execute/SKILL.md +22 -0
  47. package/skills/kd-gen/SKILL.md +34 -0
  48. package/skills/kd-ksql/SKILL.md +86 -0
  49. package/skills/kd-plan/SKILL.md +24 -0
  50. package/skills/kd-ship/SKILL.md +22 -0
  51. package/skills/kd-spec/SKILL.md +24 -0
  52. package/skills/kd-verify/SKILL.md +22 -0
  53. package/themes/kcode-dark.json +81 -0
  54. package/vendor/kingdee-skills/cosmic-unittest/SKILL.md +788 -0
  55. package/vendor/kingdee-skills/cosmic-unittest/author-cache.json +5 -0
  56. package/vendor/kingdee-skills/cosmic-unittest/cosmic-unittest-skill-overview.html +746 -0
  57. package/vendor/kingdee-skills/cosmic-unittest/examples/business-test.md +205 -0
  58. package/vendor/kingdee-skills/cosmic-unittest/examples/common-test.md +257 -0
  59. package/vendor/kingdee-skills/cosmic-unittest/examples/formplugin-test.md +560 -0
  60. package/vendor/kingdee-skills/cosmic-unittest/examples/op-plugin-test.md +231 -0
  61. package/vendor/kingdee-skills/cosmic-unittest/examples/validator-test.md +232 -0
  62. package/vendor/kingdee-skills/cosmic-unittest/patterns/business-helper.md +184 -0
  63. package/vendor/kingdee-skills/cosmic-unittest/patterns/common-module.md +355 -0
  64. package/vendor/kingdee-skills/cosmic-unittest/patterns/convert-plugin.md +130 -0
  65. package/vendor/kingdee-skills/cosmic-unittest/patterns/formplugin.md +235 -0
  66. package/vendor/kingdee-skills/cosmic-unittest/patterns/op-plugin.md +226 -0
  67. package/vendor/kingdee-skills/cosmic-unittest/patterns/validator.md +206 -0
  68. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/SKILL.md +674 -0
  69. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/advanced-scenario-checklist.md +307 -0
  70. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/algox-performance-checklist.md +129 -0
  71. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/coding-standard-checklist.md +491 -0
  72. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/cosmic-api-checklist.md +285 -0
  73. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/data-access-checklist.md +261 -0
  74. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/data-transaction-checklist.md +390 -0
  75. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/domain-logic-checklist.md +295 -0
  76. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/form-plugin-checklist.md +508 -0
  77. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/infra-checklist.md +254 -0
  78. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/ksql-checklist.md +305 -0
  79. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/lifecycle-checklist.md +298 -0
  80. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/operation-plugin-checklist.md +442 -0
  81. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/test-mock-checklist.md +120 -0
  82. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/ui-performance-checklist.md +320 -0
  83. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/scripts/pattern-matcher.py +336 -0
  84. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/scripts/review-score-calculator.py +121 -0
  85. package/vendor/kingdee-skills/ok-cosmic/CHANGELOG.md +295 -0
  86. package/vendor/kingdee-skills/ok-cosmic/README.md +460 -0
  87. package/vendor/kingdee-skills/ok-cosmic/SKILL.md +287 -0
  88. package/vendor/kingdee-skills/ok-cosmic/agents/openai.yaml +17 -0
  89. package/vendor/kingdee-skills/ok-cosmic/assets/BatchImportPluginTemplate.java +93 -0
  90. package/vendor/kingdee-skills/ok-cosmic/assets/BillPlugInTemplate.java +156 -0
  91. package/vendor/kingdee-skills/ok-cosmic/assets/ConvertPlugInTemplate.java +255 -0
  92. package/vendor/kingdee-skills/ok-cosmic/assets/FormPluginTemplate.java +597 -0
  93. package/vendor/kingdee-skills/ok-cosmic/assets/IWorkflowPluginTemplate.java +91 -0
  94. package/vendor/kingdee-skills/ok-cosmic/assets/ListPluginTemplate.java +194 -0
  95. package/vendor/kingdee-skills/ok-cosmic/assets/OpPluginTemplate.java +201 -0
  96. package/vendor/kingdee-skills/ok-cosmic/assets/OpenApiControllerTemplate.java +103 -0
  97. package/vendor/kingdee-skills/ok-cosmic/assets/PrintPluginTemplate.java +95 -0
  98. package/vendor/kingdee-skills/ok-cosmic/assets/ReportFormPluginTemplate.java +257 -0
  99. package/vendor/kingdee-skills/ok-cosmic/assets/ReportListDataPluginTemplate.java +70 -0
  100. package/vendor/kingdee-skills/ok-cosmic/assets/StandardTreeListPluginTemplate.java +130 -0
  101. package/vendor/kingdee-skills/ok-cosmic/assets/TaskTemplate.java +80 -0
  102. package/vendor/kingdee-skills/ok-cosmic/assets/TreeListPluginTemplate.java +152 -0
  103. package/vendor/kingdee-skills/ok-cosmic/assets/WriteBackPlugInTemplate.java +286 -0
  104. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/attachment/AttachmentUploadBindSample.java +93 -0
  105. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/botp/BotpTracePushSample.java +168 -0
  106. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/botp/SampleConvertPlugin.java +223 -0
  107. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/cache/SampleCacheUsage.java +218 -0
  108. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/concurrent/SampleThreadPoolBatch.java +156 -0
  109. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/data/DynamicObjectCrudSample.java +205 -0
  110. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/data/DynamicObjectOpsSample.java +100 -0
  111. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/BeforeOperationConfirmSample.java +217 -0
  112. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/ConfirmDialogSample.java +131 -0
  113. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/EntryRowCalculateSample.java +116 -0
  114. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/F7FilterSample.java +134 -0
  115. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/GetAndSetValueSample.java +176 -0
  116. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/HyperlinkJumpSample.java +124 -0
  117. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/OpenBillModalSample.java +253 -0
  118. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/ReturnParentDataSample.java +295 -0
  119. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/TreeControlSample.java +140 -0
  120. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/ViewControlOpsSample.java +132 -0
  121. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/list/ListPluginBasicSample.java +170 -0
  122. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/list/ListPreOpenFilterSample.java +68 -0
  123. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/message/MessageNotifySample.java +95 -0
  124. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/mq/SampleMQConsumer.java +198 -0
  125. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/mq/sample_mq.xml +15 -0
  126. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/operation/OpAddValidatorsSample.java +137 -0
  127. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/operation/OperationOptionBridgeSample.java +228 -0
  128. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/package-info.java +19 -0
  129. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/query/BaseDataQuerySample.java +194 -0
  130. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/query/BatchQuerySample.java +368 -0
  131. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/query/DataSetQueryStatSample.java +131 -0
  132. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/report/SampleReportFormPlugin.java +179 -0
  133. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/report/SampleReportListDataPlugin.java +616 -0
  134. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/snippets-guide.md +64 -0
  135. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/task/ScheduleTaskSample.java +160 -0
  136. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/workflow/SampleWorkflowPlugin.java +302 -0
  137. package/vendor/kingdee-skills/ok-cosmic/manifest.json +78 -0
  138. package/vendor/kingdee-skills/ok-cosmic/ok-cosmic-intro.html +903 -0
  139. package/vendor/kingdee-skills/ok-cosmic/references/adv/attachment-api.md +114 -0
  140. package/vendor/kingdee-skills/ok-cosmic/references/adv/botp-convert.md +98 -0
  141. package/vendor/kingdee-skills/ok-cosmic/references/adv/dynamic-object.md +113 -0
  142. package/vendor/kingdee-skills/ok-cosmic/references/adv/entity-metadata.md +123 -0
  143. package/vendor/kingdee-skills/ok-cosmic/references/adv/event-lifecycle.md +184 -0
  144. package/vendor/kingdee-skills/ok-cosmic/references/adv/flex-prop.md +114 -0
  145. package/vendor/kingdee-skills/ok-cosmic/references/adv/form-utils.md +133 -0
  146. package/vendor/kingdee-skills/ok-cosmic/references/adv/operate-chain.md +159 -0
  147. package/vendor/kingdee-skills/ok-cosmic/references/adv/plugin-base.md +218 -0
  148. package/vendor/kingdee-skills/ok-cosmic/references/adv/query-dataset.md +149 -0
  149. package/vendor/kingdee-skills/ok-cosmic/references/adv/request-context.md +88 -0
  150. package/vendor/kingdee-skills/ok-cosmic/references/adv/view-handler.md +157 -0
  151. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-bill.md +76 -0
  152. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-botp.md +70 -0
  153. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-form.md +165 -0
  154. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-import.md +69 -0
  155. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-list.md +227 -0
  156. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-openapi.md +112 -0
  157. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-operation.md +135 -0
  158. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-print.md +65 -0
  159. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-report-data.md +64 -0
  160. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-report-form.md +90 -0
  161. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-task.md +62 -0
  162. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-tree-list.md +71 -0
  163. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-workflow.md +82 -0
  164. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-writeback.md +71 -0
  165. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-algo.md +67 -0
  166. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-cache.md +63 -0
  167. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-dynamic-model-svc.md +82 -0
  168. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-dynamic-object.md +70 -0
  169. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-entity-model.md +61 -0
  170. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-exception.md +64 -0
  171. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-file.md +63 -0
  172. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-id.md +47 -0
  173. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-lock.md +61 -0
  174. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-log.md +63 -0
  175. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-network-control.md +70 -0
  176. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-orm-access.md +78 -0
  177. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-request-context.md +62 -0
  178. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-threadpool.md +63 -0
  179. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-tx.md +64 -0
  180. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-utils.md +67 -0
  181. package/vendor/kingdee-skills/ok-cosmic/requirements.txt +2 -0
  182. package/vendor/kingdee-skills/ok-cosmic/rules/a-layer-rules.json +24 -0
  183. package/vendor/kingdee-skills/ok-cosmic/rules/anti-patterns.md +48 -0
  184. package/vendor/kingdee-skills/ok-cosmic/rules/cheat-sheet.md +256 -0
  185. package/vendor/kingdee-skills/ok-cosmic/rules/coding-preferences.md +140 -0
  186. package/vendor/kingdee-skills/ok-cosmic/rules/constraints.md +61 -0
  187. package/vendor/kingdee-skills/ok-cosmic/rules/decision-matrix.md +222 -0
  188. package/vendor/kingdee-skills/ok-cosmic/rules/intent-routing.md +94 -0
  189. package/vendor/kingdee-skills/ok-cosmic/rules/platform-baseline.md +69 -0
  190. package/vendor/kingdee-skills/ok-cosmic/rules/post-check.md +109 -0
  191. package/vendor/kingdee-skills/ok-cosmic/scripts/config_loader.py +204 -0
  192. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-api-knowledge.py +910 -0
  193. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-basedata-query.py +359 -0
  194. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-config-check.py +181 -0
  195. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-extpoints-query.py +389 -0
  196. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-form-metadata.py +856 -0
  197. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-post-check.py +262 -0
  198. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-post-lint.py +293 -0
  199. package/vendor/kingdee-skills/ok-cosmic/scripts/lint/__init__.py +2 -0
  200. package/vendor/kingdee-skills/ok-cosmic/scripts/lint/base.py +393 -0
  201. package/vendor/kingdee-skills/ok-cosmic/scripts/lint/resource_check.py +176 -0
  202. package/vendor/kingdee-skills/ok-cosmic/scripts/lint/scene_check.py +375 -0
  203. package/vendor/kingdee-skills/ok-cosmic/scripts/lint/style_check.py +434 -0
  204. package/vendor/kingdee-skills/ok-cosmic/scripts/lint/verify_check.py +36 -0
  205. package/vendor/kingdee-skills/ok-cosmic/scripts/route_client.py +186 -0
  206. package/vendor/kingdee-skills/ok-cosmic/scripts/script_utils.py +40 -0
  207. package/vendor/kingdee-skills/ok-cosmic/scripts/sqlite_cache.py +142 -0
  208. package/vendor/kingdee-skills/ok-cosmic/setup/cuslib/kd-cd-cosmic-commons.jar +0 -0
  209. package/vendor/kingdee-skills/ok-cosmic/setup/cuslib/kd-cd-cosmic-features.jar +0 -0
  210. package/vendor/kingdee-skills/ok-cosmic/setup/ok-cosmic-docs.db +0 -0
  211. package/vendor/kingdee-skills/ok-cosmic/setup/ok-cosmic.json +13 -0
  212. package/vendor/kingdee-skills/ok-cosmic/setup/setup-mac.sh +18 -0
  213. package/vendor/kingdee-skills/ok-cosmic/setup/setup-windows.bat +53 -0
  214. package/vendor/kingdee-skills/ok-cosmic/setup/setup.jar +0 -0
  215. package/vendor/kingdee-skills/ok-ksql/SKILL.md +81 -0
  216. package/vendor/kingdee-skills/ok-ksql/agents/openai.yaml +7 -0
  217. package/vendor/kingdee-skills/ok-ksql/manifest.json +14 -0
  218. package/vendor/kingdee-skills/ok-ksql/references/ksql-datafix.md +452 -0
  219. package/vendor/kingdee-skills/ok-ksql/scripts/ksql_lint.py +363 -0
@@ -0,0 +1,389 @@
1
+ #!/usr/bin/env python3
2
+ # SPDX-License-Identifier: NOASSERTION
3
+ """
4
+ cosmic-extpoints-query.py — Cosmic business extension point query tool.
5
+
6
+ Usage:
7
+ python3 cosmic-extpoints-query.py --config ok-cosmic.json get --keyword 应付
8
+ python3 cosmic-extpoints-query.py --config ok-cosmic.json get 应付
9
+ python3 cosmic-extpoints-query.py --config ok-cosmic.json get --keyword 应付 --full # 需要生成代码/查看示例时使用
10
+
11
+ What it provides:
12
+ 1. Online business extension point lookup by keyword
13
+ 2. Unified route API resolution with environment-variable fallback
14
+ 3. Optional route.openApiSign support for OpenAPI signed URLs
15
+ 4. Human-readable summary output by default, with full JSON only for code sample inspection
16
+ 5. AI-friendly field: hasSample
17
+
18
+ What it does NOT do:
19
+ - It does not verify Java method signatures by itself; if the full result has no
20
+ clear Java sample code, use cosmic-api-knowledge.py detail to confirm methods
21
+ and parameters
22
+ - It does not generate plugin implementation code
23
+ - It does not infer whether an extension point is suitable for a concrete event
24
+
25
+ Prerequisites:
26
+ - A reachable runtime/route API, configured by ok-cosmic.json / route env / --api-url
27
+ """
28
+
29
+ import argparse
30
+ import json
31
+ import sys
32
+ from typing import Any, Dict, Iterable, List, Optional, Tuple
33
+
34
+ from config_loader import load_project_config
35
+ from route_client import RouteClient, unwrap_route_raw
36
+ from script_utils import FriendlyArgumentParser, run_cli
37
+
38
+
39
+ def _shorten(text: Any, max_len: int = 80) -> str:
40
+ value = "" if text is None else str(text)
41
+ value = value.replace("\r", " ").replace("\n", " ").strip()
42
+ if len(value) <= max_len:
43
+ return value
44
+ return value[: max_len - 1] + "…"
45
+
46
+
47
+ def _md_escape(text: Any) -> str:
48
+ return _shorten(text).replace("|", "\\|") or "-"
49
+
50
+
51
+ def _pick_value(item: Dict[str, Any], keys: Iterable[str]) -> Any:
52
+ lower_map = {str(k).lower(): v for k, v in item.items()}
53
+ for key in keys:
54
+ if key in item and item.get(key) not in (None, ""):
55
+ return item.get(key)
56
+ value = lower_map.get(key.lower())
57
+ if value not in (None, ""):
58
+ return value
59
+ return None
60
+
61
+
62
+ def _record_has_sample(item: Dict[str, Any]) -> bool:
63
+ sample = item.get("sample")
64
+ if isinstance(sample, str):
65
+ return bool(sample.strip())
66
+ return bool(sample)
67
+
68
+
69
+ def _first_list_from_mapping(data: Dict[str, Any]) -> Tuple[Optional[List[Any]], Optional[Any]]:
70
+ """
71
+ Try common list wrappers without assuming the exact remote payload shape.
72
+
73
+ Returns:
74
+ - records list, if found
75
+ - total count, if exposed by the wrapper
76
+ """
77
+ list_keys = (
78
+ "records",
79
+ "rows",
80
+ "items",
81
+ "list",
82
+ "result",
83
+ "values",
84
+ "extPoints",
85
+ "extpoints",
86
+ "data",
87
+ )
88
+ total = (
89
+ data.get("total")
90
+ or data.get("totalCount")
91
+ or data.get("count")
92
+ or data.get("size")
93
+ )
94
+ for key in list_keys:
95
+ value = data.get(key)
96
+ if isinstance(value, list):
97
+ return value, total
98
+ return None, total
99
+
100
+
101
+ def _looks_like_extpoints_payload(value: Any) -> bool:
102
+ if isinstance(value, list):
103
+ return True
104
+ if not isinstance(value, dict):
105
+ return False
106
+ records, _ = _first_list_from_mapping(value)
107
+ return records is not None
108
+
109
+
110
+ def _unwrap_route_raw(raw: Dict[str, Any]) -> Dict[str, Any]:
111
+ return unwrap_route_raw(raw, _looks_like_extpoints_payload)
112
+
113
+
114
+ class ExtPointsQuery:
115
+ def __init__(
116
+ self,
117
+ config: Dict[str, Any],
118
+ api_url: Optional[str] = None,
119
+ debug: bool = False,
120
+ ):
121
+ self.debug = debug
122
+ route_config = config.get("route", {})
123
+ if not isinstance(route_config, dict):
124
+ route_config = {}
125
+
126
+ self.route_client = RouteClient(
127
+ route_config,
128
+ api_url=api_url,
129
+ debug=debug,
130
+ missing_message=(
131
+ "未配置业务拓展点查询 API。请在 ok-cosmic.json 的 route.apiUrl 中配置统一路由,"
132
+ "或设置 COSMIC_ROUTE_API / COSMIC_RUNTIME_ROUTE_API 环境变量;"
133
+ "临时调试也可使用 --api-url 指定统一路由地址。"
134
+ ),
135
+ )
136
+
137
+ def _post(self, payload: Dict[str, Any]) -> Dict[str, Any]:
138
+ return self.route_client.post(payload)
139
+
140
+ @staticmethod
141
+ def _normalize(raw: Dict[str, Any], keyword: str) -> Dict[str, Any]:
142
+ raw_data = raw.get("data")
143
+ records: Optional[List[Any]] = None
144
+ total: Optional[Any] = None
145
+ trace_id = raw.get("traceId")
146
+
147
+ if isinstance(raw_data, list):
148
+ records = raw_data
149
+ elif isinstance(raw_data, dict):
150
+ records, total = _first_list_from_mapping(raw_data)
151
+ trace_id = raw_data.get("traceId") or trace_id
152
+ elif isinstance(raw.get("records"), list):
153
+ records = raw.get("records")
154
+ total = raw.get("total") or raw.get("totalCount") or raw.get("count")
155
+
156
+ if records is None:
157
+ records = []
158
+
159
+ has_sample = any(_record_has_sample(item) for item in records if isinstance(item, dict))
160
+ return {
161
+ "status": "ok",
162
+ "keyword": keyword,
163
+ "traceId": trace_id,
164
+ "total": total,
165
+ "count": len(records),
166
+ "hasSample": has_sample,
167
+ "records": records,
168
+ "data": raw_data,
169
+ "raw": raw,
170
+ }
171
+
172
+ def query(self, keyword: str) -> Dict[str, Any]:
173
+ normalized_keyword = (keyword or "").strip()
174
+ if not normalized_keyword:
175
+ raise ValueError("keyword 不能为空。请传入业务关键词,例如:--keyword 应付")
176
+
177
+ payload = {
178
+ "data": {
179
+ "type": "extpoint",
180
+ "reqData": {
181
+ "keyword": normalized_keyword,
182
+ },
183
+ }
184
+ }
185
+ raw = _unwrap_route_raw(self._post(payload))
186
+
187
+ if raw.get("status") is False:
188
+ message = str(raw.get("message") or "remote api status=false")
189
+ error_code = raw.get("errorCode")
190
+ raise RuntimeError(f"{message} (errorCode={error_code})")
191
+
192
+ return self._normalize(raw, normalized_keyword)
193
+
194
+ @staticmethod
195
+ def _render_record_table(records: List[Any]) -> List[str]:
196
+ if not records:
197
+ return []
198
+
199
+ rows = [
200
+ "### [List] 拓展点列表",
201
+ "| # | 编码 | 名称 | 接口 / 类 | 对象 / 模块 | 示例 | 说明 |",
202
+ "| :--- | :--- | :--- | :--- | :--- | :--- | :--- |",
203
+ ]
204
+ for idx, item in enumerate(records[:120], start=1):
205
+ if not isinstance(item, dict):
206
+ rows.append(
207
+ f"| {idx} | - | - | - | - | - | `{_md_escape(json.dumps(item, ensure_ascii=False))}` |"
208
+ )
209
+ continue
210
+
211
+ name = _pick_value(
212
+ item,
213
+ (
214
+ "name",
215
+ "extPointName",
216
+ "extpointName",
217
+ "pointName",
218
+ "title",
219
+ "sceneName",
220
+ "scenarioName",
221
+ "bizName",
222
+ ),
223
+ )
224
+ number = _pick_value(item, ("number", "code", "sceneCode", "bizCode", "extPointCode"))
225
+ interface = _pick_value(
226
+ item,
227
+ (
228
+ "interface",
229
+ "interfaceName",
230
+ "fullClassName",
231
+ "className",
232
+ "clazz",
233
+ "apiClass",
234
+ "serviceInterface",
235
+ "serviceClass",
236
+ "classPath",
237
+ ),
238
+ )
239
+ app = _pick_value(
240
+ item,
241
+ (
242
+ "app",
243
+ "appName",
244
+ "appId",
245
+ "module",
246
+ "moduleName",
247
+ "domain",
248
+ "product",
249
+ "productName",
250
+ "objectType",
251
+ ),
252
+ )
253
+ desc = _pick_value(
254
+ item,
255
+ (
256
+ "description",
257
+ "desc",
258
+ "remark",
259
+ "memo",
260
+ "summary",
261
+ "scene",
262
+ "scenario",
263
+ "useScene",
264
+ ),
265
+ )
266
+ sample_state = "✔️ 有" if _record_has_sample(item) else "—"
267
+ rows.append(
268
+ f"| {idx} | `{_md_escape(number)}` | {_md_escape(name)} | "
269
+ f"`{_md_escape(interface)}` | {_md_escape(app)} | {sample_state} | {_md_escape(desc)} |"
270
+ )
271
+
272
+ if len(records) > 120:
273
+ rows.append(
274
+ "\n> *结果较多,仅展示前 120 条;请缩小关键词。"
275
+ "只有需要生成代码或查看示例时才使用 --full。*"
276
+ )
277
+
278
+ return rows
279
+
280
+ def render(self, result: Dict[str, Any], full: bool = False) -> str:
281
+ if full:
282
+ return json.dumps(result, ensure_ascii=False, indent=2)
283
+
284
+ lines = [
285
+ "## [ExtPoint] 业务拓展点查询",
286
+ f"**关键词**: `{result.get('keyword') or '-'}`",
287
+ f"**命中数**: `{result.get('count')}`",
288
+ f"**hasSample**: `{str(bool(result.get('hasSample'))).lower()}`",
289
+ ]
290
+ total = result.get("total")
291
+ if total is not None:
292
+ lines.append(f"**远端 total**: `{total}`")
293
+ trace_id = result.get("traceId")
294
+ if trace_id:
295
+ lines.append(f"**traceId**: `{trace_id}`")
296
+
297
+ records = result.get("records")
298
+ if isinstance(records, list) and records:
299
+ lines.append("")
300
+ lines.extend(self._render_record_table(records))
301
+ else:
302
+ lines.append("")
303
+ lines.append("> 未从返回数据中识别出拓展点列表,以下输出原始 data 便于判断接口结构。")
304
+ lines.append("```json")
305
+ lines.append(json.dumps(result.get("data"), ensure_ascii=False, indent=2))
306
+ lines.append("```")
307
+
308
+ lines.append(
309
+ "\n> 下一步:需要生成代码或查看示例时加 `--full`。"
310
+ "如果示例内容足够清晰,可先按示例实现;示例缺失/不完整/签名不确定时,再用 "
311
+ "`cosmic-api-knowledge.py detail <full.class.Name>` 确认方法签名。"
312
+ )
313
+ return "\n".join(lines)
314
+
315
+
316
+ def _load_config_for_query(config_path: Optional[str]) -> Dict[str, Any]:
317
+ """
318
+ Keep standard ok-cosmic config behavior when possible, but allow this online
319
+ query tool to run with explicit --api-url / environment variables if the
320
+ implicit cwd config is absent.
321
+ Explicit --config still remains strict.
322
+ """
323
+ try:
324
+ return load_project_config(config_path)
325
+ except FileNotFoundError:
326
+ if config_path:
327
+ raise
328
+ return {
329
+ "__config_path__": "",
330
+ "__config_dir__": os.getcwd(),
331
+ }
332
+
333
+
334
+ def main():
335
+ parser = FriendlyArgumentParser(
336
+ description="Cosmic ExtPoints Query CLI — 苍穹业务拓展点在线查询",
337
+ formatter_class=argparse.RawDescriptionHelpFormatter,
338
+ epilog="""\
339
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
340
+ 推荐用法
341
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
342
+ # 按关键词查询业务拓展点
343
+ %(prog)s --config ok-cosmic.json get --keyword 应付
344
+
345
+ # keyword 也可作为位置参数
346
+ %(prog)s --config ok-cosmic.json get 应付
347
+
348
+ # 需要生成代码或查看示例时,输出完整 JSON
349
+ %(prog)s --config ok-cosmic.json get --keyword 应付 --full
350
+
351
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
352
+ AI 调用约束
353
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
354
+ - 本脚本只负责定位业务拓展点候选。
355
+ - 摘要和 --full 都会输出 hasSample,便于判断是否需要查看完整示例。
356
+ - 默认不要加 --full;只有需要生成实现代码或查看示例时才使用 --full。
357
+ - --full 返回中示例足够清晰时,可先按示例实现;示例缺失/不完整/签名不确定时再用 cosmic-api-knowledge.py detail 确认方法签名。
358
+ - 统一路由请求体固定为 {"data": {"type": "extpoint", "reqData": {"keyword": "..."}}}。
359
+ """,
360
+ )
361
+ parser.add_argument("--config", help="Path to ok-cosmic.json")
362
+ parser.add_argument("--api-url", help="Override extpoints API URL for this invocation")
363
+ parser.add_argument("--debug", action="store_true")
364
+
365
+ sub_parser = parser.add_subparsers(dest="command")
366
+ get_parser = sub_parser.add_parser("get")
367
+ get_parser.add_argument("keyword_arg", nargs="?", help="业务关键词(也可用 --keyword)")
368
+ get_parser.add_argument("--keyword", help="业务关键词,例如:应付")
369
+ get_parser.add_argument("--full", action="store_true", help="需要生成代码或查看示例时,直接输出完整 JSON")
370
+
371
+ args = parser.parse_args()
372
+ if args.command != "get":
373
+ parser.print_help()
374
+ return
375
+
376
+ keyword = (args.keyword or args.keyword_arg or "").strip()
377
+
378
+ try:
379
+ config = _load_config_for_query(args.config)
380
+ query = ExtPointsQuery(config, api_url=args.api_url, debug=args.debug)
381
+ result = query.query(keyword=keyword)
382
+ print(query.render(result, full=args.full))
383
+ except Exception as e:
384
+ print(f"✖️ 错误: {str(e)}", file=sys.stderr)
385
+ sys.exit(1)
386
+
387
+
388
+ if __name__ == "__main__":
389
+ sys.exit(run_cli(main))