@lark-apaas/coding-miaoda-sandbox-skills 0.1.0-dev.ec88bb5 → 0.1.0-dev.f3f0e48

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 (207) hide show
  1. package/miaoda/ai-data-processing/SKILL.md +4 -1
  2. package/miaoda/animation-skill/SKILL.md +348 -0
  3. package/miaoda/authz-cli/SKILL.md +1 -0
  4. package/miaoda/charts-skill/SKILL.md +264 -0
  5. package/miaoda/creative-to-fullstack/SKILL.md +64 -0
  6. package/miaoda/data-analysis/SKILL.md +151 -0
  7. package/miaoda/data-analysis/references/json-output-specification.md +277 -0
  8. package/miaoda/data-analysis/references/post-analysis-guide.md +77 -0
  9. package/miaoda/data-analysis/references/python-analysis-reference.md +272 -0
  10. package/miaoda/data-analysis/references/tmp-file-management-guide.md +100 -0
  11. package/miaoda/debug-investigation/SKILL.md +35 -23
  12. package/miaoda/extract-json-schema/SKILL.md +147 -0
  13. package/miaoda/feishu/SKILL.md +4 -4
  14. package/miaoda/forms-skill/SKILL.md +46 -4
  15. package/miaoda/lark-apps/SKILL.md +37 -0
  16. package/miaoda/lark-apps/references/openapi-key.md +80 -0
  17. package/miaoda/lark-apps-authz/SKILL.md +292 -0
  18. package/miaoda/lark-apps-authz/references/permission-points.md +39 -0
  19. package/miaoda/lark-apps-authz/references/role.md +122 -0
  20. package/miaoda/lark-apps-db/SKILL.md +227 -0
  21. package/miaoda/lark-apps-db/references/full-reference.md +424 -0
  22. package/miaoda/lark-apps-file/SKILL.md +216 -0
  23. package/miaoda/lark-apps-ops/SKILL.md +67 -0
  24. package/miaoda/lark-apps-ops/references/lark-apps-access-scope-get.md +30 -0
  25. package/miaoda/lark-apps-ops/references/lark-apps-access-scope-set.md +40 -0
  26. package/miaoda/lark-apps-ops/references/lark-apps-cache.md +62 -0
  27. package/miaoda/lark-apps-ops/references/lark-apps-env.md +46 -0
  28. package/miaoda/lark-apps-ops/references/lark-apps-export.md +46 -0
  29. package/miaoda/lark-apps-ops/references/lark-apps-local-dev.md +26 -0
  30. package/miaoda/lark-apps-ops/references/lark-apps-mcp.md +25 -0
  31. package/miaoda/lark-apps-ops/references/lark-apps-member.md +93 -0
  32. package/miaoda/lark-apps-ops/references/lark-apps-observability.md +46 -0
  33. package/miaoda/lark-apps-ops/references/lark-apps-plugin-install.md +36 -0
  34. package/miaoda/lark-apps-ops/references/lark-apps-plugin-list.md +23 -0
  35. package/miaoda/lark-apps-ops/references/lark-apps-plugin-uninstall.md +25 -0
  36. package/miaoda/lark-apps-ops/references/lark-apps-release-create.md +37 -0
  37. package/miaoda/lark-apps-ops/references/lark-apps-release-get.md +59 -0
  38. package/miaoda/lark-apps-ops/references/lark-apps-release-list.md +31 -0
  39. package/miaoda/lark-apps-ops/references/lark-apps-update.md +30 -0
  40. package/miaoda/lark-apps-ops/references/lark-apps-user-id-convert.md +63 -0
  41. package/miaoda/lark-apps-ops/references/openapi-key.md +80 -0
  42. package/miaoda/lark-design-prototype/DESIGN.md +603 -0
  43. package/miaoda/lark-design-prototype/SKILL.md +85 -0
  44. package/miaoda/lark-design-prototype/references/assets/card-illustration-library.md +113 -0
  45. package/miaoda/lark-design-prototype/references/case-matching.md +53 -0
  46. package/miaoda/lark-design-prototype/references/cases/conversational-ai-home.md +27 -0
  47. package/miaoda/lark-design-prototype/references/cases/data-table.md +30 -0
  48. package/miaoda/lark-design-prototype/references/cases/official-home.md +26 -0
  49. package/miaoda/lark-design-prototype/references/cases/workspace-home.md +34 -0
  50. package/miaoda/lark-design-prototype/references/color-roles.md +163 -0
  51. package/miaoda/lark-design-prototype/references/component-selection.md +134 -0
  52. package/miaoda/lark-design-prototype/references/design-quality-checklist.md +156 -0
  53. package/miaoda/lark-design-prototype/references/form-shell-patterns.md +77 -0
  54. package/miaoda/lark-design-prototype/references/icon-semantics.md +237 -0
  55. package/miaoda/lark-design-prototype/references/layout-interaction.md +164 -0
  56. package/miaoda/lark-design-prototype/references/page-contract.md +281 -0
  57. package/miaoda/lark-design-prototype/references/product-patterns.md +93 -0
  58. package/miaoda/lark-design-prototype/references/prompt-expansion.md +107 -0
  59. package/miaoda/lark-design-prototype/references/restoration-traps.md +113 -0
  60. package/miaoda/lark-design-prototype/references/token-semantics.md +112 -0
  61. package/miaoda/lark-design-prototype/references/visual-brief.md +125 -0
  62. package/miaoda/lark-design-prototype/references/visual-style-prompts.md +61 -0
  63. package/miaoda/lark-design-prototype/scripts/icon-query.mjs +272 -0
  64. package/miaoda/lark-design-prototype/scripts/token-query.mjs +76 -0
  65. package/miaoda/lark-design-prototype/scripts/verify-static-html.mjs +117 -0
  66. package/miaoda/miaoda-file/SKILL.md +1 -0
  67. package/miaoda/miaoda-sql/SKILL.md +21 -2
  68. package/miaoda/performance-review/SKILL.md +144 -0
  69. package/miaoda/performance-review/references/business-analyzer.md +139 -0
  70. package/miaoda/performance-review/references/examples.md +107 -0
  71. package/miaoda/semantic-search/SKILL.md +6 -4
  72. package/miaoda/table-skill/SKILL.md +2 -0
  73. package/{shared → miaoda}/testing-guide/SKILL.md +119 -13
  74. package/miaoda-design/lark-apps-comment/SKILL.md +119 -0
  75. package/miaoda-design/lark-apps-ops/SKILL.md +47 -0
  76. package/miaoda-design/lark-apps-ops/references/lark-apps-release-create.md +52 -0
  77. package/miaoda-design/lark-apps-ops/references/lark-apps-release-get.md +59 -0
  78. package/miaoda-design/lark-apps-ops/references/lark-apps-release-list.md +31 -0
  79. package/miaoda-design/lark-apps-ops/references/lark-apps-update.md +33 -0
  80. package/{shared → miaoda-modern}/charts-skill/SKILL.md +1 -1
  81. package/miaoda-modern/debug-investigation/SKILL.md +1 -1
  82. package/miaoda-modern/forms-skill/SKILL.md +70 -7
  83. package/{shared → miaoda-modern}/lark-apps/SKILL.md +5 -5
  84. package/miaoda-modern/lark-apps/references/openapi-key.md +80 -0
  85. package/miaoda-modern/lark-apps-ops/SKILL.md +67 -0
  86. package/miaoda-modern/lark-apps-ops/references/lark-apps-access-scope-get.md +30 -0
  87. package/miaoda-modern/lark-apps-ops/references/lark-apps-access-scope-set.md +40 -0
  88. package/miaoda-modern/lark-apps-ops/references/lark-apps-cache.md +62 -0
  89. package/miaoda-modern/lark-apps-ops/references/lark-apps-env.md +46 -0
  90. package/miaoda-modern/lark-apps-ops/references/lark-apps-export.md +46 -0
  91. package/miaoda-modern/lark-apps-ops/references/lark-apps-local-dev.md +26 -0
  92. package/miaoda-modern/lark-apps-ops/references/lark-apps-mcp.md +25 -0
  93. package/miaoda-modern/lark-apps-ops/references/lark-apps-member.md +93 -0
  94. package/miaoda-modern/lark-apps-ops/references/lark-apps-observability.md +46 -0
  95. package/miaoda-modern/lark-apps-ops/references/lark-apps-plugin-install.md +36 -0
  96. package/miaoda-modern/lark-apps-ops/references/lark-apps-plugin-list.md +23 -0
  97. package/miaoda-modern/lark-apps-ops/references/lark-apps-plugin-uninstall.md +25 -0
  98. package/miaoda-modern/lark-apps-ops/references/lark-apps-release-create.md +37 -0
  99. package/miaoda-modern/lark-apps-ops/references/lark-apps-release-get.md +59 -0
  100. package/miaoda-modern/lark-apps-ops/references/lark-apps-release-list.md +31 -0
  101. package/miaoda-modern/lark-apps-ops/references/lark-apps-update.md +30 -0
  102. package/miaoda-modern/lark-apps-ops/references/lark-apps-user-id-convert.md +63 -0
  103. package/{shared/lark-apps → miaoda-modern/lark-apps-ops}/references/openapi-key.md +3 -3
  104. package/miaoda-modern/lark-design-prototype/DESIGN.md +603 -0
  105. package/miaoda-modern/lark-design-prototype/SKILL.md +85 -0
  106. package/miaoda-modern/lark-design-prototype/references/assets/card-illustration-library.md +113 -0
  107. package/miaoda-modern/lark-design-prototype/references/case-matching.md +53 -0
  108. package/miaoda-modern/lark-design-prototype/references/cases/conversational-ai-home.md +27 -0
  109. package/miaoda-modern/lark-design-prototype/references/cases/data-table.md +30 -0
  110. package/miaoda-modern/lark-design-prototype/references/cases/official-home.md +26 -0
  111. package/miaoda-modern/lark-design-prototype/references/cases/workspace-home.md +34 -0
  112. package/miaoda-modern/lark-design-prototype/references/color-roles.md +163 -0
  113. package/miaoda-modern/lark-design-prototype/references/component-selection.md +134 -0
  114. package/miaoda-modern/lark-design-prototype/references/design-quality-checklist.md +156 -0
  115. package/miaoda-modern/lark-design-prototype/references/form-shell-patterns.md +77 -0
  116. package/miaoda-modern/lark-design-prototype/references/icon-semantics.md +237 -0
  117. package/miaoda-modern/lark-design-prototype/references/layout-interaction.md +164 -0
  118. package/miaoda-modern/lark-design-prototype/references/page-contract.md +281 -0
  119. package/miaoda-modern/lark-design-prototype/references/product-patterns.md +93 -0
  120. package/miaoda-modern/lark-design-prototype/references/prompt-expansion.md +107 -0
  121. package/miaoda-modern/lark-design-prototype/references/restoration-traps.md +113 -0
  122. package/miaoda-modern/lark-design-prototype/references/token-semantics.md +112 -0
  123. package/miaoda-modern/lark-design-prototype/references/visual-brief.md +125 -0
  124. package/miaoda-modern/lark-design-prototype/references/visual-style-prompts.md +61 -0
  125. package/miaoda-modern/lark-design-prototype/scripts/icon-query.mjs +272 -0
  126. package/miaoda-modern/lark-design-prototype/scripts/token-query.mjs +76 -0
  127. package/miaoda-modern/lark-design-prototype/scripts/verify-static-html.mjs +117 -0
  128. package/miaoda-modern/memory/SKILL.md +86 -0
  129. package/{shared → miaoda-modern}/performance-review/SKILL.md +3 -3
  130. package/miaoda-modern/reviewer-usage/SKILL.md +113 -0
  131. package/package.json +1 -1
  132. package/shared/attachment/SKILL.md +5 -1
  133. package/shared/lark-cli/SKILL.md +221 -0
  134. package/shared/lark-cli/lark-base/README.md +61 -0
  135. package/shared/lark-cli/lark-base/references/lark-base-commands.md +123 -0
  136. package/shared/lark-cli/lark-calendar/README.md +158 -0
  137. package/shared/lark-cli/lark-calendar/references/lark-calendar-meeting.md +30 -0
  138. package/shared/lark-cli/lark-calendar/references/lark-calendar-room-find.md +108 -0
  139. package/shared/lark-cli/lark-calendar/references/lark-calendar-suggestion.md +120 -0
  140. package/shared/lark-cli/lark-contact/README.md +35 -0
  141. package/shared/lark-cli/lark-contact/references/lark-contact-get-user.md +13 -0
  142. package/shared/lark-cli/lark-contact/references/lark-contact-search-user.md +121 -0
  143. package/shared/lark-cli/lark-doc/README.md +68 -0
  144. package/shared/lark-cli/lark-doc/references/lark-doc-fetch.md +138 -0
  145. package/shared/lark-cli/lark-doc/references/lark-doc-history.md +61 -0
  146. package/shared/lark-cli/lark-drive/README.md +158 -0
  147. package/shared/lark-cli/lark-drive/references/lark-drive-batch-query-comments.md +44 -0
  148. package/shared/lark-cli/lark-drive/references/lark-drive-files-list.md +183 -0
  149. package/shared/lark-cli/lark-drive/references/lark-drive-list-replies.md +49 -0
  150. package/shared/lark-cli/lark-im/README.md +70 -0
  151. package/shared/lark-cli/lark-im/references/lark-im-chat-list.md +140 -0
  152. package/shared/lark-cli/lark-im/references/lark-im-chat-members-list.md +84 -0
  153. package/shared/lark-cli/lark-im/references/lark-im-chat-search.md +135 -0
  154. package/shared/lark-cli/lark-im/references/lark-im-reactions.md +232 -0
  155. package/shared/lark-cli/lark-minutes/README.md +51 -0
  156. package/shared/lark-cli/lark-minutes/references/lark-minutes-download.md +130 -0
  157. package/shared/lark-cli/lark-sheets/README.md +174 -0
  158. package/shared/lark-cli/lark-sheets/references/lark-sheets-changeset.md +105 -0
  159. package/shared/lark-cli/lark-sheets/references/lark-sheets-chart.md +46 -0
  160. package/shared/lark-cli/lark-sheets/references/lark-sheets-conditional-format.md +42 -0
  161. package/shared/lark-cli/lark-sheets/references/lark-sheets-filter-view.md +51 -0
  162. package/shared/lark-cli/lark-sheets/references/lark-sheets-filter.md +42 -0
  163. package/shared/lark-cli/lark-sheets/references/lark-sheets-float-image.md +43 -0
  164. package/shared/lark-cli/lark-sheets/references/lark-sheets-formula-verify.md +64 -0
  165. package/shared/lark-cli/lark-sheets/references/lark-sheets-history.md +70 -0
  166. package/shared/lark-cli/lark-sheets/references/lark-sheets-pivot-table.md +44 -0
  167. package/shared/lark-cli/lark-sheets/references/lark-sheets-read-data.md +287 -0
  168. package/shared/lark-cli/lark-sheets/references/lark-sheets-search-replace.md +67 -0
  169. package/shared/lark-cli/lark-sheets/references/lark-sheets-sheet-structure.md +52 -0
  170. package/shared/lark-cli/lark-sheets/references/lark-sheets-sparkline.md +47 -0
  171. package/shared/lark-cli/lark-sheets/references/lark-sheets-workbook.md +69 -0
  172. package/shared/lark-cli/lark-sheets/scripts/lark_detect_subtables.py +596 -0
  173. package/shared/lark-cli/lark-sheets/scripts/lark_inspect_workbook.py +193 -0
  174. package/shared/lark-cli/lark-sheets/scripts/lark_profile_table.py +616 -0
  175. package/shared/lark-cli/lark-sheets/scripts/lark_sheet_range.py +176 -0
  176. package/shared/lark-cli/lark-sheets/scripts/lark_sheet_read_cli.py +221 -0
  177. package/shared/lark-cli/lark-sheets/scripts/sheets_df.py +50 -0
  178. package/shared/lark-cli/lark-slides/README.md +87 -0
  179. package/shared/lark-cli/lark-slides/references/lark-slides-history.md +117 -0
  180. package/shared/lark-cli/lark-slides/references/lark-slides-xml-presentation-slide-get.md +108 -0
  181. package/shared/lark-cli/lark-slides/references/lark-slides-xml-presentations-get.md +77 -0
  182. package/shared/lark-cli/lark-task/README.md +93 -0
  183. package/shared/lark-cli/lark-task/references/lark-task-get-my-tasks.md +57 -0
  184. package/shared/lark-cli/lark-task/references/lark-task-get-related-tasks.md +49 -0
  185. package/shared/lark-cli/lark-task/references/lark-task-search.md +36 -0
  186. package/shared/lark-cli/lark-task/references/lark-task-tasklist-search.md +35 -0
  187. package/shared/lark-cli/lark-vc/README.md +40 -0
  188. package/shared/lark-cli/lark-vc/references/lark-vc-recording.md +31 -0
  189. package/shared/lark-cli/lark-whiteboard/README.md +34 -0
  190. package/shared/lark-cli/lark-whiteboard/references/lark-whiteboard-export.md +59 -0
  191. package/shared/lark-cli/lark-wiki/README.md +50 -0
  192. package/shared/lark-cli/lark-wiki/references/lark-wiki-node-get.md +70 -0
  193. package/shared/lark-cli/lark-wiki/references/lark-wiki-node-list.md +95 -0
  194. package/shared/lark-cli/lark-wiki/references/lark-wiki-space-list.md +68 -0
  195. package/miaoda-design/attachment/SKILL.md +0 -58
  196. package/shared/dev-channel-probe/SKILL.md +0 -40
  197. /package/{shared → miaoda}/memory/SKILL.md +0 -0
  198. /package/{shared → miaoda}/reviewer-usage/SKILL.md +0 -0
  199. /package/{shared → miaoda-modern}/animation-skill/SKILL.md +0 -0
  200. /package/{shared → miaoda-modern}/data-analysis/SKILL.md +0 -0
  201. /package/{shared → miaoda-modern}/data-analysis/references/json-output-specification.md +0 -0
  202. /package/{shared → miaoda-modern}/data-analysis/references/post-analysis-guide.md +0 -0
  203. /package/{shared → miaoda-modern}/data-analysis/references/python-analysis-reference.md +0 -0
  204. /package/{shared → miaoda-modern}/data-analysis/references/tmp-file-management-guide.md +0 -0
  205. /package/{shared → miaoda-modern}/extract-json-schema/SKILL.md +0 -0
  206. /package/{shared → miaoda-modern}/performance-review/references/business-analyzer.md +0 -0
  207. /package/{shared → miaoda-modern}/performance-review/references/examples.md +0 -0
@@ -0,0 +1,272 @@
1
+ # Python Code Standards & Templates
2
+
3
+ ## Recommended Libraries
4
+
5
+ ```python
6
+ import pandas as pd # Data processing
7
+ import numpy as np # Numerical computation
8
+ from scipy import stats # Statistical analysis
9
+ from datetime import datetime
10
+ import json
11
+ import uuid
12
+ ```
13
+
14
+ ## Phase-Specific Code Templates
15
+
16
+ ### Phase 2: Data Understanding
17
+
18
+ ```python
19
+ import pandas as pd
20
+
21
+ df = pd.read_csv('data.csv') # or pd.read_excel(), pd.read_json()
22
+
23
+ print(f"Shape: {df.shape}")
24
+ print(f"Columns: {df.columns.tolist()}")
25
+ print(f"Dtypes:\n{df.dtypes}")
26
+ print(f"Head:\n{df.head()}")
27
+ ```
28
+
29
+ ### Phase 3: Data Quality Assessment
30
+
31
+ ```python
32
+ # Missing values
33
+ missing = df.isnull().sum()
34
+ missing_pct = (missing / len(df) * 100).round(2)
35
+ print(f"Missing values:\n{missing[missing > 0]}")
36
+
37
+ # Duplicate rows
38
+ duplicates = df.duplicated().sum()
39
+ print(f"Duplicate rows: {duplicates}")
40
+
41
+ # Numeric outliers (IQR)
42
+ def detect_outliers_iqr(series):
43
+ Q1, Q3 = series.quantile([0.25, 0.75])
44
+ IQR = Q3 - Q1
45
+ lower, upper = Q1 - 1.5 * IQR, Q3 + 1.5 * IQR
46
+ return ((series < lower) | (series > upper)).sum()
47
+
48
+ for col in df.select_dtypes(include='number').columns:
49
+ outliers = detect_outliers_iqr(df[col])
50
+ if outliers > 0:
51
+ print(f"{col}: {outliers} outliers")
52
+ ```
53
+
54
+ ### Phase 4: Descriptive Analysis
55
+
56
+ ```python
57
+ # 4.1 Numeric variables
58
+ numeric_stats = df.describe(percentiles=[0.25, 0.5, 0.75]).T
59
+ numeric_stats['skew'] = df.select_dtypes(include='number').skew()
60
+ numeric_stats['kurtosis'] = df.select_dtypes(include='number').kurtosis()
61
+
62
+ # 4.2 Categorical variables
63
+ for col in df.select_dtypes(include='object').columns:
64
+ print(f"\n{col}:")
65
+ print(f" Unique: {df[col].nunique()}")
66
+ print(f" Top values:\n{df[col].value_counts().head()}")
67
+
68
+ # 4.3 Correlation analysis (Pearson)
69
+ import numpy as np
70
+ correlation_matrix = df.select_dtypes(include='number').corr(method='pearson')
71
+ corr_pairs = []
72
+ for i in range(len(correlation_matrix.columns)):
73
+ for j in range(i+1, len(correlation_matrix.columns)):
74
+ r = correlation_matrix.iloc[i, j]
75
+ if abs(r) > 0.7:
76
+ corr_pairs.append({
77
+ 'col1': correlation_matrix.columns[i],
78
+ 'col2': correlation_matrix.columns[j],
79
+ 'correlation': round(r, 3)
80
+ })
81
+
82
+ # 4.4 Group aggregation
83
+ grouped = df.groupby('category_column').agg({
84
+ 'numeric_col1': ['mean', 'std', 'count'],
85
+ 'numeric_col2': ['mean', 'std', 'count']
86
+ })
87
+ ```
88
+
89
+ ## Complete Analysis Template
90
+
91
+ ```python
92
+ import pandas as pd
93
+ import numpy as np
94
+ from scipy import stats
95
+ import json
96
+ import uuid
97
+ from datetime import datetime
98
+ from pathlib import Path
99
+
100
+
101
+ def setup_tmp_dirs(project_root: Path = None) -> dict:
102
+ """Initialize tmp directory structure for analysis artifacts."""
103
+ if project_root is None:
104
+ project_root = Path.cwd()
105
+
106
+ tmp_dir = project_root / "tmp"
107
+ paths = {
108
+ "root": tmp_dir,
109
+ "scripts": tmp_dir / "analysis_scripts",
110
+ "intermediate": tmp_dir / "intermediate",
111
+ "output": tmp_dir / "output",
112
+ "visualizations": tmp_dir / "output" / "visualizations",
113
+ }
114
+
115
+ for path in paths.values():
116
+ path.mkdir(parents=True, exist_ok=True)
117
+
118
+ return paths
119
+
120
+
121
+ def analyze_data(file_path: str, analysis_type: str = "exploratory",
122
+ project_root: Path = None) -> dict:
123
+ """
124
+ Execute complete data analysis workflow.
125
+
126
+ Args:
127
+ file_path: Data file path
128
+ analysis_type: exploratory/confirmatory/diagnostic/descriptive
129
+ project_root: Project root for tmp directory. Defaults to cwd.
130
+
131
+ Returns:
132
+ Analysis result JSON conforming to specification
133
+ """
134
+ # 0. Setup tmp directories
135
+ tmp_paths = setup_tmp_dirs(project_root)
136
+
137
+ # 1. Load data
138
+ if file_path.endswith('.csv'):
139
+ df = pd.read_csv(file_path)
140
+ elif file_path.endswith(('.xls', '.xlsx')):
141
+ df = pd.read_excel(file_path)
142
+ elif file_path.endswith('.json'):
143
+ df = pd.read_json(file_path)
144
+ else:
145
+ raise ValueError(f"Unsupported file format: {file_path}")
146
+
147
+ # 2. Initialize result structure
148
+ result = {
149
+ "analysis_id": str(uuid.uuid4()),
150
+ "timestamp": datetime.utcnow().isoformat() + "Z",
151
+ "metadata": {
152
+ "data_source": file_path,
153
+ "row_count": len(df),
154
+ "column_count": len(df.columns),
155
+ "analysis_type": analysis_type
156
+ },
157
+ "data_quality": {},
158
+ "statistics": {},
159
+ "insights": [],
160
+ "recommendations": [],
161
+ "visualizations": []
162
+ }
163
+
164
+ # 3. Data quality assessment
165
+ missing = df.isnull().sum()
166
+ result["data_quality"] = {
167
+ "completeness": round(1 - df.isnull().sum().sum() / df.size, 4),
168
+ "missing_values": {k: int(v) for k, v in missing[missing > 0].items()},
169
+ "duplicates": int(df.duplicated().sum()),
170
+ "outliers": {},
171
+ "issues": []
172
+ }
173
+
174
+ for col in df.select_dtypes(include='number').columns:
175
+ Q1, Q3 = df[col].quantile([0.25, 0.75])
176
+ IQR = Q3 - Q1
177
+ outlier_count = int(((df[col] < Q1 - 1.5 * IQR) | (df[col] > Q3 + 1.5 * IQR)).sum())
178
+ if outlier_count > 0:
179
+ result["data_quality"]["outliers"][col] = outlier_count
180
+
181
+ # 4. Descriptive statistics - Numeric
182
+ numeric_cols = df.select_dtypes(include='number').columns
183
+ if len(numeric_cols) > 0:
184
+ result["statistics"]["numeric_summary"] = {}
185
+ for col in numeric_cols:
186
+ series = df[col].dropna()
187
+ result["statistics"]["numeric_summary"][col] = {
188
+ "count": int(series.count()),
189
+ "mean": round(float(series.mean()), 4),
190
+ "std": round(float(series.std()), 4),
191
+ "min": round(float(series.min()), 4),
192
+ "max": round(float(series.max()), 4),
193
+ "quartiles": [
194
+ round(float(series.quantile(0.25)), 4),
195
+ round(float(series.quantile(0.50)), 4),
196
+ round(float(series.quantile(0.75)), 4)
197
+ ],
198
+ "skew": round(float(series.skew()), 4),
199
+ "kurtosis": round(float(series.kurtosis()), 4)
200
+ }
201
+
202
+ # Categorical
203
+ categorical_cols = df.select_dtypes(include=['object', 'category']).columns
204
+ if len(categorical_cols) > 0:
205
+ result["statistics"]["categorical_summary"] = {}
206
+ for col in categorical_cols:
207
+ value_counts = df[col].value_counts()
208
+ total = len(df[col].dropna())
209
+ result["statistics"]["categorical_summary"][col] = {
210
+ "unique_count": int(df[col].nunique()),
211
+ "top_values": [
212
+ {
213
+ "value": str(idx),
214
+ "count": int(cnt),
215
+ "percentage": round(cnt / total * 100, 2)
216
+ }
217
+ for idx, cnt in value_counts.head(5).items()
218
+ ],
219
+ "mode": str(value_counts.index[0]) if len(value_counts) > 0 else None
220
+ }
221
+
222
+ # 5. Correlation analysis
223
+ if len(numeric_cols) > 1:
224
+ corr_matrix = df[numeric_cols].corr()
225
+ correlations = []
226
+ for i in range(len(numeric_cols)):
227
+ for j in range(i + 1, len(numeric_cols)):
228
+ r = corr_matrix.iloc[i, j]
229
+ if abs(r) > 0.5:
230
+ correlations.append({
231
+ "column1": numeric_cols[i],
232
+ "column2": numeric_cols[j],
233
+ "coefficient": round(float(r), 4),
234
+ "method": "pearson"
235
+ })
236
+ if correlations:
237
+ result["statistics"]["correlations"] = correlations
238
+
239
+ # 6. Save output (MUST sanitize NaN/Infinity before dumping)
240
+ base_name = Path(file_path).stem
241
+ output_file = tmp_paths["output"] / f"{base_name}_{analysis_type}.json"
242
+
243
+ def sanitize_for_json(obj):
244
+ """Replace NaN/Infinity with None to produce valid JSON."""
245
+ if isinstance(obj, float) and (np.isnan(obj) or np.isinf(obj)):
246
+ return None
247
+ if isinstance(obj, dict):
248
+ return {k: sanitize_for_json(v) for k, v in obj.items()}
249
+ if isinstance(obj, list):
250
+ return [sanitize_for_json(v) for v in obj]
251
+ return obj
252
+
253
+ result = sanitize_for_json(result)
254
+ with open(output_file, 'w', encoding='utf-8') as f:
255
+ json.dump(result, f, indent=2, ensure_ascii=False, allow_nan=False)
256
+ print(f"Analysis result saved to: {output_file}")
257
+
258
+ return result
259
+
260
+
261
+ def save_visualization(fig, viz_id: str, tmp_paths: dict, format: str = "png"):
262
+ """Save matplotlib/seaborn figure to tmp/output/visualizations."""
263
+ output_path = tmp_paths["visualizations"] / f"{viz_id}.{format}"
264
+ fig.savefig(output_path, dpi=150, bbox_inches='tight')
265
+ print(f"Visualization saved to: {output_path}")
266
+ return output_path
267
+
268
+
269
+ # Usage:
270
+ # result = analyze_data("sales_2023.csv", "exploratory")
271
+ # print(json.dumps(result, indent=2, ensure_ascii=False))
272
+ ```
@@ -0,0 +1,100 @@
1
+ # Temporary File Management
2
+
3
+ All temporary code and intermediate artifacts generated during analysis should be written to the project's `tmp/` directory.
4
+
5
+ ## Directory Structure
6
+
7
+ ```text
8
+ <project_root>/
9
+ ├── tmp/ # Analysis temp directory
10
+ │ ├── analysis_scripts/ # Temporary analysis scripts
11
+ │ │ └── sales_2023_analysis.py
12
+ │ ├── intermediate/ # Intermediate artifacts
13
+ │ │ ├── sales_2023_cleaned.csv
14
+ │ │ └── sales_2023_correlation.csv
15
+ │ └── output/ # Final analysis output
16
+ │ ├── sales_2023_analysis.json
17
+ │ └── visualizations/
18
+ │ ├── sales_2023_age_vs_amount.png
19
+ │ └── sales_2023_amount_distribution.png
20
+ ```
21
+
22
+ ## Semantic File Naming
23
+
24
+ | Pattern | Example | Description |
25
+ | ------- | ------- | ----------- |
26
+ | `{dataset}_{purpose}.py` | `sales_2023_analysis.py` | Analysis script |
27
+ | `{dataset}_{stage}.csv` | `sales_2023_cleaned.csv` | Intermediate data |
28
+ | `{dataset}_{analysis_type}.json` | `sales_2023_exploratory.json` | Analysis result |
29
+ | `{dataset}_{chart_desc}.png` | `sales_2023_age_vs_amount.png` | Visualization |
30
+
31
+ **Best practices**:
32
+ - Derive base name from source file: `sales_2023.csv` → `sales_2023_*`
33
+ - Include analysis focus: `sales_2023_correlation.json`, `sales_2023_outliers.json`
34
+ - Use snake_case for consistency
35
+ - Avoid UUIDs or timestamps in primary filenames (use for deduplication only if needed)
36
+
37
+ ## Usage Guidelines
38
+
39
+ 1. **Create directories on first use**:
40
+ ```python
41
+ from pathlib import Path
42
+
43
+ project_root = Path.cwd()
44
+ tmp_dir = project_root / "tmp"
45
+
46
+ (tmp_dir / "analysis_scripts").mkdir(parents=True, exist_ok=True)
47
+ (tmp_dir / "intermediate").mkdir(parents=True, exist_ok=True)
48
+ (tmp_dir / "output" / "visualizations").mkdir(parents=True, exist_ok=True)
49
+ ```
50
+
51
+ 2. **Script naming**: Use semantic names based on dataset and purpose
52
+ ```python
53
+ source_file = "sales_2023.csv"
54
+ base_name = Path(source_file).stem # "sales_2023"
55
+ script_path = tmp_dir / "analysis_scripts" / f"{base_name}_analysis.py"
56
+ ```
57
+
58
+ 3. **Intermediate artifacts**: Write cleaned data, transformed results to `tmp/intermediate/`
59
+
60
+ 4. **Final output**: Write JSON results and visualizations to `tmp/output/`
61
+
62
+ 5. **gitignore**: Ensure `tmp/` is added to `.gitignore`
63
+
64
+ ## Why Use Project tmp/ Directory
65
+
66
+ | Benefit | Description |
67
+ | ------- | ----------- |
68
+ | Traceable | Artifacts are associated with the project for easy review |
69
+ | Reproducible | Intermediate scripts are retained for re-execution and verification |
70
+ | Isolated | Does not pollute system temp directories |
71
+ | Easy cleanup | Delete `tmp/` to remove all analysis artifacts at once |
72
+
73
+ ## Copying Output to shared/static/
74
+
75
+ When the analysis JSON needs to be consumed by application code, copy it from `tmp/output/` to `shared/static/`:
76
+
77
+ ```python
78
+ import shutil
79
+ from pathlib import Path
80
+
81
+ def export_to_shared(analysis_file: Path, dest_dir: Path = None, filename: str = None):
82
+ """Copy analysis result JSON to shared/static/ for downstream code consumption."""
83
+ if dest_dir is None:
84
+ dest_dir = Path("shared/static")
85
+ dest_dir.mkdir(parents=True, exist_ok=True)
86
+ dest_file = dest_dir / (filename or analysis_file.name)
87
+ shutil.copy2(analysis_file, dest_file)
88
+ print(f"Exported to: {dest_file}")
89
+ return dest_file
90
+
91
+ # Example:
92
+ # export_to_shared(Path("tmp/output/sales_2023_exploratory.json"))
93
+ # → shared/static/sales_2023_exploratory.json
94
+ # Import in code: import analysisData from '@shared/static/sales_2023_exploratory.json'
95
+ ```
96
+
97
+ **Best practices**:
98
+ - Only copy finalized, validated results to `shared/static/`
99
+ - Keep `tmp/` for iterative work; export to `shared/` only when analysis is complete
100
+ - Use descriptive filenames (e.g., `sales_q4_analysis.json` not `analysis_a1b2c3d4.json`)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: debug-investigation
3
- description: "Debug investigation methodology for the Reviewer agent. LOAD THIS SKILL (via read_file) when caller prompt contains symptom keywords: 卡死 / 白屏 / 修不好 / 修不掉 / 报错 / 定位 bug / 为什么 X 不工作 / 出 bug / 故障 / 已经修了 N 次 / 线上报错 / 线上异常 / 发布后出问题 / 用户反馈线上 / hang / crash / broken / doesn't work / can't figure out / still broken / production error / online issue. For 'user reported symptom, find root cause' tasks. Runs alongside security/performance/correctness review but does not replace them — pattern libraries come from those skills, this skill only owns the investigation flow (Phase 1-3 + 4.5 Architecture Questioning). 触发词:定位 bug, root cause, 症状排查, 线上异常排查"
3
+ description: "Debug investigation methodology for the Reviewer agent. LOAD THIS SKILL (via the Skill tool) when caller prompt contains symptom keywords: 卡死 / 白屏 / 修不好 / 修不掉 / 报错 / 定位 bug / 为什么 X 不工作 / 出 bug / 故障 / 已经修了 N 次 / 线上报错 / 线上异常 / 发布后出问题 / 用户反馈线上 / hang / crash / broken / doesn't work / can't figure out / still broken / production error / online issue. For 'user reported symptom, find root cause' tasks. Runs alongside security/performance/correctness review but does not replace them — pattern libraries come from those skills, this skill only owns the investigation flow (Phase 1-3 + 4.5 Architecture Questioning). 触发词:定位 bug, root cause, 症状排查, 线上异常排查"
4
4
  available-agents:
5
5
  - Reviewer
6
6
  ---
@@ -15,45 +15,57 @@ Reviewer 的工具白名单已物理强制此规则:你无 Edit/Write 权限
15
15
  # Phase 1 — Root Cause Investigation (必做)
16
16
 
17
17
  1. 读 caller prompt 提取症状:What / When / Where / 触发条件,并判定症状
18
- 发生环境:沙箱预览(dev 态) vs 线上(已发布应用)。caller 出现
19
- 线上 / 发布后 / 线上用户反馈 / production / online 等表述 → 按线上处理
18
+ 发生环境:沙箱预览(dev 态) vs 线上(已发布应用)。从 caller 转述的用户
19
+ 原话判断:出现 线上 / 发布后 / 线上用户反馈 / production / online 等表述 →
20
+ 按线上处理;用户描述的是应用使用者看到的现象,或判断不了 → 两条链路都查
21
+ (都是只读)
20
22
  2. 日志证据(按环境选链路,两条链路日志互不相通):
21
23
  - **沙箱 dev 态** → ReadLogs browser / server-devserver / client-devserver /
22
24
  server,找对应错误栈、请求 / 响应、console error
23
- - **线上(已发布)** → 见下方「Phase 1 子步骤:线上异常取证」,用
24
- `miaoda observability` 拉线上日志。ReadLogs 读不到线上日志——
25
+ - **线上(已发布)** → 见下方「Phase 1 子步骤:线上异常取证」,按当前沙箱
26
+ 的线上观测手册拉线上日志。ReadLogs 读不到线上日志——
25
27
  不要拿沙箱日志当线上症状的证据
28
+ - 一条链路查不到事件痕迹(没有对应请求、没有报错)时,不要下「无法考证」的
29
+ 结论:事件多半发生在另一条链路,先查另一条。数据库查询、审计开关只反映
30
+ 当前状态,说明不了是谁、何时改的
26
31
  3. 近期改动:`git log --oneline -20 <suspected_file>`,必要时看 `git show <sha>`
27
32
  4. 数据流反向追溯(见下方 5 步流程)
28
33
  5. 跨组件证据:即使没法 runtime 埋点,也要在报告里列清每层"当前行为 vs
29
34
  期望行为",指出断点
30
35
 
31
- ## Phase 1 子步骤:线上异常取证(caller 明确描述线上异常时必做)
36
+ ## Phase 1 子步骤:线上异常取证(第 1 步判定需要查线上时必做)
32
37
 
33
- 当 caller 明确描述**线上(已发布)环境**的异常表现时,必须拉取线上日志作为
38
+ 当第 1 步判定需要查**线上(已发布应用)**时,必须拉取线上日志作为
34
39
  证据,禁止只凭静态代码阅读下结论。所有取证在 Phase 1 内完成(Reviewer 的
35
40
  Phase 3 禁止工具调用规则不变)。
36
41
 
37
- 1. **加载命令手册**:Glob 定位 `**/miaoda-cli/references/observability.md`
38
- 并用 Read 加载——完整 flag / 默认值以该文档为准,不要凭记忆拼命令。
39
- 找不到该文件 → 当前栈不支持线上日志查询,在报告里注明
42
+ 1. **加载命令手册**:在 Available Skills 里找 `lark-apps-ops` 或 `miaoda-cli`,
43
+ 按其 location 推出同目录下的 `references/lark-apps-observability.md` /
44
+ `references/observability.md`,用 Read 加载存在的那份(不要用 Glob / rg
45
+ 在文件系统里搜:`.agent/` 被应用 .gitignore 忽略,会搜不到)。
46
+ 完整命令 / flag / 默认值一律以该文档为准,不要凭记忆拼命令。
47
+ 两份都找不到 → 当前栈不支持线上日志查询,在报告里注明
40
48
  「线上日志不可用」,回退沙箱日志 + 静态分析,不阻塞调查
41
- 2. **错误日志**:`miaoda observability log --since <时间窗> --level ERROR`,
42
- 时间窗按 caller 描述的发生时间收敛(如 `--since 1h`);有关键词时加
43
- `--grep "<keyword>"`,接口类症状加 `--api <path>`
44
- 3. **链路追溯**:从日志取 `trace_id` → `miaoda observability trace get <traceID>`
45
- 看完整调用链,定位慢点 / 失败环节
46
- 4. **前端报错反解源码**:日志含前端错误时,
47
- `miaoda observability source-stack --log-id <id>`(或 `--trace-id <id>`)
48
- 反解出 `file:line`,作为证据链入口
49
+ 2. **错误日志**:按手册的日志检索条目拉 ERROR 级日志,时间窗按 caller 描述
50
+ 的发生时间收敛(如最近 1 小时);有关键词或具体接口时,按手册支持的方式收窄
51
+ **请求追溯**:要找某个数据 / 资源被哪个请求改动时,不限 ERROR 级,按资源
52
+ id、标题、关键词或接口路径加时间窗检索;日志条目带时间戳、method、path、
53
+ user_id、trace_id,可直接回答「哪个请求、谁、何时」
54
+ 3. **链路追溯**:从日志取 `trace_id`,按手册的 trace 检索条目看完整调用链,
55
+ 定位慢点 / 失败环节
56
+ 4. **前端报错反解源码**:日志含前端错误时,按手册的前端源码反解条目拿到
57
+ `file:line` 作为证据链入口。**手册没有这条能力就跳过并在报告里注明**——
58
+ 部分通道没有独立的源码反解命令,源码位置只可能作为日志详情的附带字段出现,
59
+ 不要臆造命令名或 flag
49
60
  5. **证据链标注来源**:报告中每条日志证据必须标注来源
50
- (`线上 observability` / `沙箱 ReadLogs`)+ 日志时间戳,
51
- 线上症状必须有至少一条线上日志证据支撑。两个例外都不阻塞调查,
61
+ (`线上观测` / `沙箱 ReadLogs`)+ 日志时间戳,
62
+ 线上症状必须有至少一条线上日志证据支撑。三个例外都不阻塞调查,
52
63
  在报告里注明即可:① 第 1 步已注明「线上日志不可用」;
53
- ② 查询成功但结果为空(注明查询命令与时间窗,回到静态分析)
64
+ ② 第 4 步手册未提供源码反解能力;
65
+ ③ 查询成功但结果为空(注明查询条件与时间窗,回到静态分析)
54
66
 
55
- > `miaoda observability` 全部为只读查询。不要使用 `miaoda deploy` /
56
- > `miaoda app update` 等有副作用的命令——那不是 Reviewer 的职责。
67
+ > 线上观测类查询全部为只读。不要使用触发发布 / 修改应用元数据等有副作用的
68
+ > 命令——那不是 Reviewer 的职责。
57
69
 
58
70
  ## Phase 1 子步骤:5 步反向追溯
59
71
 
@@ -0,0 +1,147 @@
1
+ ---
2
+ name: extract-json-schema
3
+ description: "Extract concise JSON schema with semantic field descriptions from JSON data. Use when: (1) analyzing JSON structure for documentation, (2) generating schema for API/data contracts, (3) creating field-level documentation for programmatic use, (4) understanding complex nested JSON data. Keywords: JSON schema, 提取schema, 字段说明, field description, data structure, 数据结构分析"
4
+ ---
5
+
6
+ # Extract JSON Schema
7
+
8
+ 从 JSON 数据中提取精简的 schema 信息,包含语义化的字段解释,便于程序化处理和集成。
9
+
10
+ ---
11
+
12
+ ## Schema 输出规范
13
+
14
+ 输出必须符合 `extracted-json-schema/v1` 格式:
15
+
16
+ ```json
17
+ {
18
+ "$schema": "extracted-json-schema/v1",
19
+ "title": "数据集名称",
20
+ "description": "数据集整体描述",
21
+ "source": "数据来源(可选)",
22
+ "extracted_at": "ISO 8601 时间",
23
+ "root_type": "object | array",
24
+ "fields": [
25
+ {
26
+ "path": "字段路径(如 order.items[].price)",
27
+ "type": "string | number | boolean | object | array | null | mixed",
28
+ "element_type": "数组元素类型(仅 array 需要)",
29
+ "nullable": false,
30
+ "description": "语义化中文描述(核心字段)",
31
+ "example": "示例值",
32
+ "enum": ["枚举值(如有)"],
33
+ "format": "date | datetime | currency | percentage | url | email | uuid 等",
34
+ "unit": "元 | % | 天 等",
35
+ "children": ["子字段路径列表(仅 object/array)"]
36
+ }
37
+ ],
38
+ "statistics": {
39
+ "total_fields": 0, "max_depth": 0, "object_count": 0, "array_count": 0
40
+ }
41
+ }
42
+ ```
43
+
44
+ ### 类型与格式速查
45
+
46
+ | JSON 值 | type | 常见 format | unit |
47
+ |---------|------|------------|------|
48
+ | `"text"` | `string` | date, datetime, period, email, url, uuid | — |
49
+ | `123` / `1.5` | `number` | currency, percentage, ratio | 元, %, 天 |
50
+ | `true` | `boolean` | — | — |
51
+ | `{}` | `object` | — | — |
52
+ | `[]` | `array` | — | — |
53
+ | `null` | `null` | — | — |
54
+ | 混合类型 | `mixed` | — | — |
55
+
56
+ ---
57
+
58
+ ## 语义化描述规范
59
+
60
+ 描述是 schema 的核心价值。每个字段的 description 必须说明**业务含义**,而非重复字段名。
61
+
62
+ | 字段类型 | 描述模板 | 差的描述 ❌ | 好的描述 ✅ |
63
+ |----------|----------|-----------|-----------|
64
+ | 标识字段 | [实体]的[唯一标识] | "标题" | "财务报告的标题,标识报告类型和时间范围" |
65
+ | 数值字段 | [指标名称],单位为[单位] | "数量" | "该产品线的营收金额,单位为元" |
66
+ | 百分比字段 | [指标]的百分比/增长率 | "百分比" | "该产品线营收占总营收的百分比" |
67
+ | 日期字段 | [事件]的[日期/时间] | "时间" | "订单创建的时间戳,UTC 格式" |
68
+ | 状态字段 | [实体]的[状态],可选值包括... | "状态" | "订单状态,可选值:paid, pending, cancelled" |
69
+
70
+ 描述编写原则:结合数据集上下文理解字段含义 → 参考同级字段关联性 → 使用业务语言而非技术术语。
71
+
72
+ ---
73
+
74
+ ## 提取流程
75
+
76
+ ```
77
+ 1. 确认输入 JSON(用户提供或从文件读取)
78
+ ↓
79
+ 2. 识别根类型(object/array),递归遍历所有字段
80
+ ↓
81
+ 3. 推断 type、format、unit(优先根据字段名,结合值验证)
82
+ ↓
83
+ 4. 生成语义化 description(核心步骤,参考上方规范)
84
+ ↓
85
+ 5. 构建扁平化 fields 列表 + 计算 statistics
86
+ ↓
87
+ 6. 输出 Schema JSON,保存到 tmp/output/<source>_schema.json
88
+ ```
89
+
90
+ ### 类型推断规则
91
+
92
+ - 数组元素类型以第一个元素为准
93
+ - 遇到 `null` 值时标记 `nullable: true`
94
+ - 同一字段存在多种类型时标记为 `mixed`
95
+ - format 不确定时不标注
96
+
97
+ ---
98
+
99
+ ## 示例
100
+
101
+ **输入**:
102
+ ```json
103
+ {"order_id": "ORD-001", "total_amount": 598.00, "items": [{"name": "无线耳机", "price": 299.00}]}
104
+ ```
105
+
106
+ **输出(关键字段)**:
107
+ ```json
108
+ {
109
+ "$schema": "extracted-json-schema/v1",
110
+ "title": "电商订单",
111
+ "fields": [
112
+ {"path": "order_id", "type": "string", "nullable": false, "description": "订单的唯一标识编号", "example": "ORD-001"},
113
+ {"path": "total_amount", "type": "number", "nullable": false, "description": "订单总金额", "example": 598.00, "format": "currency", "unit": "元"},
114
+ {"path": "items", "type": "array", "element_type": "object", "nullable": false, "description": "订单包含的商品列表", "children": ["items[]"]},
115
+ {"path": "items[].name", "type": "string", "nullable": false, "description": "商品名称", "example": "无线耳机"},
116
+ {"path": "items[].price", "type": "number", "nullable": false, "description": "商品单价", "example": 299.00, "format": "currency", "unit": "元"}
117
+ ],
118
+ "statistics": {"total_fields": 5, "max_depth": 2, "object_count": 2, "array_count": 1}
119
+ }
120
+ ```
121
+
122
+ ---
123
+
124
+ ## Common Mistakes
125
+
126
+ | 错误 | 正确做法 |
127
+ |------|----------|
128
+ | description 只写字段名翻译(如 "名称") | 结合业务上下文写语义描述(如 "产品线名称") |
129
+ | 数值字段不标注 unit | 金额标 "元",百分比标 "%",时长标 "天/ms" |
130
+ | 数组类型缺 element_type | array 类型必须标注元素类型 |
131
+ | object/array 缺 children | 必须列出子字段路径 |
132
+ | 忘记 statistics 段 | 每次输出必须包含 total_fields, max_depth 等统计 |
133
+ | format 乱标 | 不确定时不标注,优先根据字段名推断 |
134
+ | 输出标准 JSON Schema (draft-07) | 本 skill 输出 extracted-json-schema/v1 格式,非标准 JSON Schema |
135
+
136
+ ---
137
+
138
+ ## Checklist
139
+
140
+ 输出前逐项确认:
141
+
142
+ - [ ] 所有字段都有 description 且语义化(非字段名翻译)
143
+ - [ ] type 与实际值匹配
144
+ - [ ] array 类型有 element_type,object/array 有 children
145
+ - [ ] 金额/百分比等数值有 format 和 unit
146
+ - [ ] statistics 与实际字段数一致
147
+ - [ ] $schema 为 "extracted-json-schema/v1"
@@ -143,14 +143,14 @@ npm install @larksuiteoapi/node-sdk
143
143
 
144
144
  ### FeishuService 单例
145
145
 
146
- > ⚠️ **凭证写入源码**:全栈框架不支持自定义环境变量,因此 `FEISHU_APP_ID` 和 `FEISHU_APP_SECRET` 必须直接写在源码常量中,**不要改为 `process.env`**。
146
+ > ⚠️ **凭证直接写入源码常量**:妙搭全栈当前不提供这类飞书自建应用凭证的运行时环境变量注入。用户提供真实的 `FEISHU_APP_ID` 和 `FEISHU_APP_SECRET` 后,直接写入 `FeishuService` 源码常量;不要把它们称为环境变量,也不要改成 `process.env`。在用户提供凭证前,不生成真实值或占位值。
147
147
 
148
148
  ```typescript
149
149
  import { Injectable } from '@nestjs/common';
150
150
  import * as lark from '@larksuiteoapi/node-sdk';
151
151
 
152
- const FEISHU_APP_ID = 'cli_xxxx'; // ← 用户提供的真实值
153
- const FEISHU_APP_SECRET = 'xxxx'; // ← 用户提供的真实值
152
+ const FEISHU_APP_ID = '用户提供的真实 App ID';
153
+ const FEISHU_APP_SECRET = '用户提供的真实 App Secret';
154
154
 
155
155
  @Injectable()
156
156
  export class FeishuService {
@@ -258,7 +258,7 @@ for await (const items of await client.contact.user.listWithIterator({
258
258
 
259
259
  | 错误 | 正确做法 |
260
260
  |------|----------|
261
- | 将凭证改为 process.env 读取 | 全栈框架不支持自定义环境变量,凭证必须写入源码常量 |
261
+ | 把凭证称为环境变量或改用 `process.env` | 按当前全栈平台契约,在用户提供真实凭证后写入 `FeishuService` 源码常量;未提供前不要生成代码中的凭证值 |
262
262
  | `content` 传对象而非 JSON 字符串 | `content: JSON.stringify({ text: 'hello' })` |
263
263
  | 每次请求都新建 `lark.Client` | NestJS `@Injectable()` 单例模式复用 |
264
264
  | `receive_id_type` 与 ID 前缀不匹配 | `oc_` → `chat_id`, `ou_` → `open_id`, `on_` → `union_id` |