@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.
- package/miaoda/ai-data-processing/SKILL.md +4 -1
- package/miaoda/animation-skill/SKILL.md +348 -0
- package/miaoda/authz-cli/SKILL.md +1 -0
- package/miaoda/charts-skill/SKILL.md +264 -0
- package/miaoda/creative-to-fullstack/SKILL.md +64 -0
- package/miaoda/data-analysis/SKILL.md +151 -0
- package/miaoda/data-analysis/references/json-output-specification.md +277 -0
- package/miaoda/data-analysis/references/post-analysis-guide.md +77 -0
- package/miaoda/data-analysis/references/python-analysis-reference.md +272 -0
- package/miaoda/data-analysis/references/tmp-file-management-guide.md +100 -0
- package/miaoda/debug-investigation/SKILL.md +35 -23
- package/miaoda/extract-json-schema/SKILL.md +147 -0
- package/miaoda/feishu/SKILL.md +4 -4
- package/miaoda/forms-skill/SKILL.md +46 -4
- package/miaoda/lark-apps/SKILL.md +37 -0
- package/miaoda/lark-apps/references/openapi-key.md +80 -0
- package/miaoda/lark-apps-authz/SKILL.md +292 -0
- package/miaoda/lark-apps-authz/references/permission-points.md +39 -0
- package/miaoda/lark-apps-authz/references/role.md +122 -0
- package/miaoda/lark-apps-db/SKILL.md +227 -0
- package/miaoda/lark-apps-db/references/full-reference.md +424 -0
- package/miaoda/lark-apps-file/SKILL.md +216 -0
- package/miaoda/lark-apps-ops/SKILL.md +67 -0
- package/miaoda/lark-apps-ops/references/lark-apps-access-scope-get.md +30 -0
- package/miaoda/lark-apps-ops/references/lark-apps-access-scope-set.md +40 -0
- package/miaoda/lark-apps-ops/references/lark-apps-cache.md +62 -0
- package/miaoda/lark-apps-ops/references/lark-apps-env.md +46 -0
- package/miaoda/lark-apps-ops/references/lark-apps-export.md +46 -0
- package/miaoda/lark-apps-ops/references/lark-apps-local-dev.md +26 -0
- package/miaoda/lark-apps-ops/references/lark-apps-mcp.md +25 -0
- package/miaoda/lark-apps-ops/references/lark-apps-member.md +93 -0
- package/miaoda/lark-apps-ops/references/lark-apps-observability.md +46 -0
- package/miaoda/lark-apps-ops/references/lark-apps-plugin-install.md +36 -0
- package/miaoda/lark-apps-ops/references/lark-apps-plugin-list.md +23 -0
- package/miaoda/lark-apps-ops/references/lark-apps-plugin-uninstall.md +25 -0
- package/miaoda/lark-apps-ops/references/lark-apps-release-create.md +37 -0
- package/miaoda/lark-apps-ops/references/lark-apps-release-get.md +59 -0
- package/miaoda/lark-apps-ops/references/lark-apps-release-list.md +31 -0
- package/miaoda/lark-apps-ops/references/lark-apps-update.md +30 -0
- package/miaoda/lark-apps-ops/references/lark-apps-user-id-convert.md +63 -0
- package/miaoda/lark-apps-ops/references/openapi-key.md +80 -0
- package/miaoda/lark-design-prototype/DESIGN.md +603 -0
- package/miaoda/lark-design-prototype/SKILL.md +85 -0
- package/miaoda/lark-design-prototype/references/assets/card-illustration-library.md +113 -0
- package/miaoda/lark-design-prototype/references/case-matching.md +53 -0
- package/miaoda/lark-design-prototype/references/cases/conversational-ai-home.md +27 -0
- package/miaoda/lark-design-prototype/references/cases/data-table.md +30 -0
- package/miaoda/lark-design-prototype/references/cases/official-home.md +26 -0
- package/miaoda/lark-design-prototype/references/cases/workspace-home.md +34 -0
- package/miaoda/lark-design-prototype/references/color-roles.md +163 -0
- package/miaoda/lark-design-prototype/references/component-selection.md +134 -0
- package/miaoda/lark-design-prototype/references/design-quality-checklist.md +156 -0
- package/miaoda/lark-design-prototype/references/form-shell-patterns.md +77 -0
- package/miaoda/lark-design-prototype/references/icon-semantics.md +237 -0
- package/miaoda/lark-design-prototype/references/layout-interaction.md +164 -0
- package/miaoda/lark-design-prototype/references/page-contract.md +281 -0
- package/miaoda/lark-design-prototype/references/product-patterns.md +93 -0
- package/miaoda/lark-design-prototype/references/prompt-expansion.md +107 -0
- package/miaoda/lark-design-prototype/references/restoration-traps.md +113 -0
- package/miaoda/lark-design-prototype/references/token-semantics.md +112 -0
- package/miaoda/lark-design-prototype/references/visual-brief.md +125 -0
- package/miaoda/lark-design-prototype/references/visual-style-prompts.md +61 -0
- package/miaoda/lark-design-prototype/scripts/icon-query.mjs +272 -0
- package/miaoda/lark-design-prototype/scripts/token-query.mjs +76 -0
- package/miaoda/lark-design-prototype/scripts/verify-static-html.mjs +117 -0
- package/miaoda/miaoda-file/SKILL.md +1 -0
- package/miaoda/miaoda-sql/SKILL.md +21 -2
- package/miaoda/performance-review/SKILL.md +144 -0
- package/miaoda/performance-review/references/business-analyzer.md +139 -0
- package/miaoda/performance-review/references/examples.md +107 -0
- package/miaoda/semantic-search/SKILL.md +6 -4
- package/miaoda/table-skill/SKILL.md +2 -0
- package/{shared → miaoda}/testing-guide/SKILL.md +119 -13
- package/miaoda-design/lark-apps-comment/SKILL.md +119 -0
- package/miaoda-design/lark-apps-ops/SKILL.md +47 -0
- package/miaoda-design/lark-apps-ops/references/lark-apps-release-create.md +52 -0
- package/miaoda-design/lark-apps-ops/references/lark-apps-release-get.md +59 -0
- package/miaoda-design/lark-apps-ops/references/lark-apps-release-list.md +31 -0
- package/miaoda-design/lark-apps-ops/references/lark-apps-update.md +33 -0
- package/{shared → miaoda-modern}/charts-skill/SKILL.md +1 -1
- package/miaoda-modern/debug-investigation/SKILL.md +1 -1
- package/miaoda-modern/forms-skill/SKILL.md +70 -7
- package/{shared → miaoda-modern}/lark-apps/SKILL.md +5 -5
- package/miaoda-modern/lark-apps/references/openapi-key.md +80 -0
- package/miaoda-modern/lark-apps-ops/SKILL.md +67 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-access-scope-get.md +30 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-access-scope-set.md +40 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-cache.md +62 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-env.md +46 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-export.md +46 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-local-dev.md +26 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-mcp.md +25 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-member.md +93 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-observability.md +46 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-plugin-install.md +36 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-plugin-list.md +23 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-plugin-uninstall.md +25 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-release-create.md +37 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-release-get.md +59 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-release-list.md +31 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-update.md +30 -0
- package/miaoda-modern/lark-apps-ops/references/lark-apps-user-id-convert.md +63 -0
- package/{shared/lark-apps → miaoda-modern/lark-apps-ops}/references/openapi-key.md +3 -3
- package/miaoda-modern/lark-design-prototype/DESIGN.md +603 -0
- package/miaoda-modern/lark-design-prototype/SKILL.md +85 -0
- package/miaoda-modern/lark-design-prototype/references/assets/card-illustration-library.md +113 -0
- package/miaoda-modern/lark-design-prototype/references/case-matching.md +53 -0
- package/miaoda-modern/lark-design-prototype/references/cases/conversational-ai-home.md +27 -0
- package/miaoda-modern/lark-design-prototype/references/cases/data-table.md +30 -0
- package/miaoda-modern/lark-design-prototype/references/cases/official-home.md +26 -0
- package/miaoda-modern/lark-design-prototype/references/cases/workspace-home.md +34 -0
- package/miaoda-modern/lark-design-prototype/references/color-roles.md +163 -0
- package/miaoda-modern/lark-design-prototype/references/component-selection.md +134 -0
- package/miaoda-modern/lark-design-prototype/references/design-quality-checklist.md +156 -0
- package/miaoda-modern/lark-design-prototype/references/form-shell-patterns.md +77 -0
- package/miaoda-modern/lark-design-prototype/references/icon-semantics.md +237 -0
- package/miaoda-modern/lark-design-prototype/references/layout-interaction.md +164 -0
- package/miaoda-modern/lark-design-prototype/references/page-contract.md +281 -0
- package/miaoda-modern/lark-design-prototype/references/product-patterns.md +93 -0
- package/miaoda-modern/lark-design-prototype/references/prompt-expansion.md +107 -0
- package/miaoda-modern/lark-design-prototype/references/restoration-traps.md +113 -0
- package/miaoda-modern/lark-design-prototype/references/token-semantics.md +112 -0
- package/miaoda-modern/lark-design-prototype/references/visual-brief.md +125 -0
- package/miaoda-modern/lark-design-prototype/references/visual-style-prompts.md +61 -0
- package/miaoda-modern/lark-design-prototype/scripts/icon-query.mjs +272 -0
- package/miaoda-modern/lark-design-prototype/scripts/token-query.mjs +76 -0
- package/miaoda-modern/lark-design-prototype/scripts/verify-static-html.mjs +117 -0
- package/miaoda-modern/memory/SKILL.md +86 -0
- package/{shared → miaoda-modern}/performance-review/SKILL.md +3 -3
- package/miaoda-modern/reviewer-usage/SKILL.md +113 -0
- package/package.json +1 -1
- package/shared/attachment/SKILL.md +5 -1
- package/shared/lark-cli/SKILL.md +221 -0
- package/shared/lark-cli/lark-base/README.md +61 -0
- package/shared/lark-cli/lark-base/references/lark-base-commands.md +123 -0
- package/shared/lark-cli/lark-calendar/README.md +158 -0
- package/shared/lark-cli/lark-calendar/references/lark-calendar-meeting.md +30 -0
- package/shared/lark-cli/lark-calendar/references/lark-calendar-room-find.md +108 -0
- package/shared/lark-cli/lark-calendar/references/lark-calendar-suggestion.md +120 -0
- package/shared/lark-cli/lark-contact/README.md +35 -0
- package/shared/lark-cli/lark-contact/references/lark-contact-get-user.md +13 -0
- package/shared/lark-cli/lark-contact/references/lark-contact-search-user.md +121 -0
- package/shared/lark-cli/lark-doc/README.md +68 -0
- package/shared/lark-cli/lark-doc/references/lark-doc-fetch.md +138 -0
- package/shared/lark-cli/lark-doc/references/lark-doc-history.md +61 -0
- package/shared/lark-cli/lark-drive/README.md +158 -0
- package/shared/lark-cli/lark-drive/references/lark-drive-batch-query-comments.md +44 -0
- package/shared/lark-cli/lark-drive/references/lark-drive-files-list.md +183 -0
- package/shared/lark-cli/lark-drive/references/lark-drive-list-replies.md +49 -0
- package/shared/lark-cli/lark-im/README.md +70 -0
- package/shared/lark-cli/lark-im/references/lark-im-chat-list.md +140 -0
- package/shared/lark-cli/lark-im/references/lark-im-chat-members-list.md +84 -0
- package/shared/lark-cli/lark-im/references/lark-im-chat-search.md +135 -0
- package/shared/lark-cli/lark-im/references/lark-im-reactions.md +232 -0
- package/shared/lark-cli/lark-minutes/README.md +51 -0
- package/shared/lark-cli/lark-minutes/references/lark-minutes-download.md +130 -0
- package/shared/lark-cli/lark-sheets/README.md +174 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-changeset.md +105 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-chart.md +46 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-conditional-format.md +42 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-filter-view.md +51 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-filter.md +42 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-float-image.md +43 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-formula-verify.md +64 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-history.md +70 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-pivot-table.md +44 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-read-data.md +287 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-search-replace.md +67 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-sheet-structure.md +52 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-sparkline.md +47 -0
- package/shared/lark-cli/lark-sheets/references/lark-sheets-workbook.md +69 -0
- package/shared/lark-cli/lark-sheets/scripts/lark_detect_subtables.py +596 -0
- package/shared/lark-cli/lark-sheets/scripts/lark_inspect_workbook.py +193 -0
- package/shared/lark-cli/lark-sheets/scripts/lark_profile_table.py +616 -0
- package/shared/lark-cli/lark-sheets/scripts/lark_sheet_range.py +176 -0
- package/shared/lark-cli/lark-sheets/scripts/lark_sheet_read_cli.py +221 -0
- package/shared/lark-cli/lark-sheets/scripts/sheets_df.py +50 -0
- package/shared/lark-cli/lark-slides/README.md +87 -0
- package/shared/lark-cli/lark-slides/references/lark-slides-history.md +117 -0
- package/shared/lark-cli/lark-slides/references/lark-slides-xml-presentation-slide-get.md +108 -0
- package/shared/lark-cli/lark-slides/references/lark-slides-xml-presentations-get.md +77 -0
- package/shared/lark-cli/lark-task/README.md +93 -0
- package/shared/lark-cli/lark-task/references/lark-task-get-my-tasks.md +57 -0
- package/shared/lark-cli/lark-task/references/lark-task-get-related-tasks.md +49 -0
- package/shared/lark-cli/lark-task/references/lark-task-search.md +36 -0
- package/shared/lark-cli/lark-task/references/lark-task-tasklist-search.md +35 -0
- package/shared/lark-cli/lark-vc/README.md +40 -0
- package/shared/lark-cli/lark-vc/references/lark-vc-recording.md +31 -0
- package/shared/lark-cli/lark-whiteboard/README.md +34 -0
- package/shared/lark-cli/lark-whiteboard/references/lark-whiteboard-export.md +59 -0
- package/shared/lark-cli/lark-wiki/README.md +50 -0
- package/shared/lark-cli/lark-wiki/references/lark-wiki-node-get.md +70 -0
- package/shared/lark-cli/lark-wiki/references/lark-wiki-node-list.md +95 -0
- package/shared/lark-cli/lark-wiki/references/lark-wiki-space-list.md +68 -0
- package/miaoda-design/attachment/SKILL.md +0 -58
- package/shared/dev-channel-probe/SKILL.md +0 -40
- /package/{shared → miaoda}/memory/SKILL.md +0 -0
- /package/{shared → miaoda}/reviewer-usage/SKILL.md +0 -0
- /package/{shared → miaoda-modern}/animation-skill/SKILL.md +0 -0
- /package/{shared → miaoda-modern}/data-analysis/SKILL.md +0 -0
- /package/{shared → miaoda-modern}/data-analysis/references/json-output-specification.md +0 -0
- /package/{shared → miaoda-modern}/data-analysis/references/post-analysis-guide.md +0 -0
- /package/{shared → miaoda-modern}/data-analysis/references/python-analysis-reference.md +0 -0
- /package/{shared → miaoda-modern}/data-analysis/references/tmp-file-management-guide.md +0 -0
- /package/{shared → miaoda-modern}/extract-json-schema/SKILL.md +0 -0
- /package/{shared → miaoda-modern}/performance-review/references/business-analyzer.md +0 -0
- /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
|
|
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
|
|
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
|
-
|
|
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
|
|
36
|
+
## Phase 1 子步骤:线上异常取证(第 1 步判定需要查线上时必做)
|
|
32
37
|
|
|
33
|
-
|
|
38
|
+
当第 1 步判定需要查**线上(已发布应用)**时,必须拉取线上日志作为
|
|
34
39
|
证据,禁止只凭静态代码阅读下结论。所有取证在 Phase 1 内完成(Reviewer 的
|
|
35
40
|
Phase 3 禁止工具调用规则不变)。
|
|
36
41
|
|
|
37
|
-
1.
|
|
38
|
-
|
|
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.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
51
|
-
|
|
61
|
+
(`线上观测` / `沙箱 ReadLogs`)+ 日志时间戳,
|
|
62
|
+
线上症状必须有至少一条线上日志证据支撑。三个例外都不阻塞调查,
|
|
52
63
|
在报告里注明即可:① 第 1 步已注明「线上日志不可用」;
|
|
53
|
-
②
|
|
64
|
+
② 第 4 步手册未提供源码反解能力;
|
|
65
|
+
③ 查询成功但结果为空(注明查询条件与时间窗,回到静态分析)
|
|
54
66
|
|
|
55
|
-
>
|
|
56
|
-
>
|
|
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"
|
package/miaoda/feishu/SKILL.md
CHANGED
|
@@ -143,14 +143,14 @@ npm install @larksuiteoapi/node-sdk
|
|
|
143
143
|
|
|
144
144
|
### FeishuService 单例
|
|
145
145
|
|
|
146
|
-
> ⚠️
|
|
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 = '
|
|
153
|
-
const FEISHU_APP_SECRET = '
|
|
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
|
-
|
|
|
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` |
|