@yorha2b-lab/autodev 2.1.15 → 2.1.16

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.
@@ -1,15 +1,15 @@
1
- name: Bunker Native Stats & Intelligence
1
+ name: Bunker Sovereign Intelligence (v7.0)
2
2
 
3
3
  on:
4
4
  schedule:
5
- - cron: '45 19 * * *' # 北京时间凌晨 03:45 自动巡航
5
+ - cron: '45 19 * * *' # 北京时间凌晨 03:45
6
6
  workflow_dispatch:
7
7
 
8
8
  env:
9
9
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
10
10
 
11
11
  jobs:
12
- recon-and-ledger:
12
+ all-seeing-eye:
13
13
  runs-on: ubuntu-latest
14
14
  permissions:
15
15
  contents: write
@@ -21,113 +21,187 @@ jobs:
21
21
  token: ${{ secrets.STATS_TOKEN }}
22
22
  fetch-depth: 0
23
23
 
24
- # 1. 环境准备:安装绘图依赖
25
24
  - name: Setup Plotting Environment
26
25
  run: |
27
26
  python -m pip install --upgrade pip
28
- pip install matplotlib pandas
27
+ pip install matplotlib pandas seaborn
29
28
 
30
- # 2. 情报采集与账本物理焊接
31
- - name: Intelligence Gathering & Sovereign Merge
29
+ # 2. 全频道数据搜刮协议 [逻辑升级:专业 JSON 构筑]
30
+ - name: Full Spectrum Data Mining
32
31
  run: |
33
- echo "🤖 Pod 042: 启动‘全频道情报采集协议’..."
34
- curl -s -H "Authorization: token ${{ secrets.STATS_TOKEN }}" \
35
- -H "Accept: application/vnd.github.v3+json" \
36
- https://api.github.com/repos/${{ github.repository }}/traffic/clones > raw_clones.json
37
-
38
- curl -s -H "Authorization: token ${{ secrets.STATS_TOKEN }}" \
39
- -H "Accept: application/vnd.github.v3+json" \
40
- https://api.github.com/repos/${{ github.repository }}/traffic/popular/referrers > raw_referrers.json
32
+ echo "🤖 Pod 042: 启动‘全领域信号搜刮协议’..."
33
+ AUTH="-H 'Authorization: token ${{ secrets.STATS_TOKEN }}' -H 'Accept: application/vnd.github.v3+json'"
34
+ API="https://api.github.com/repos/${{ github.repository }}"
35
+
36
+ eval curl -s $AUTH $API/traffic/clones > raw_clones.json
37
+ eval curl -s $AUTH $API/traffic/popular/referrers > raw_referrers.json
38
+ eval curl -s $AUTH $API/traffic/views > raw_views.json
39
+ eval curl -s $AUTH $API > raw_repo.json
41
40
 
42
41
  mkdir -p ghrs-data
43
- echo "date,clones,uniques" > /tmp/new_data.csv
44
- jq -r '.clones[] | "\(.timestamp[0:10]),\(.count),\(.uniques)"' raw_clones.json >> /tmp/new_data.csv
45
42
 
46
- LEDGER="ghrs-data/clones_ledger.csv"
47
- if [ ! -f "$LEDGER" ]; then
48
- cp /tmp/new_data.csv "$LEDGER"
43
+ # --- 物理焊接:Views 账本 ---
44
+ echo "date,views,uniques" > /tmp/new_views.csv
45
+ jq -r '.views[] | "\(.timestamp[0:10]),\(.count),\(.uniques)"' raw_views.json >> /tmp/new_views.csv
46
+
47
+ V_LEDGER="ghrs-data/views_ledger.csv"
48
+ if [ ! -f "$V_LEDGER" ]; then
49
+ cp /tmp/new_views.csv "$V_LEDGER"
50
+ else
51
+ (tail -n +2 "$V_LEDGER"; tail -n +2 /tmp/new_views.csv) | grep -v "date" | \
52
+ sed 's/\//-/g' | awk -F',' '!a[$1]++' | sort -r > /tmp/final_v_data.csv
53
+ echo "date,views,uniques" > "$V_LEDGER"
54
+ cat /tmp/final_v_data.csv >> "$V_LEDGER"
55
+ fi
56
+
57
+ # --- 物理焊接:Clones 账本 ---
58
+ echo "date,clones,uniques" > /tmp/new_clones.csv
59
+ jq -r '.clones[] | "\(.timestamp[0:10]),\(.count),\(.uniques)"' raw_clones.json >> /tmp/new_clones.csv
60
+
61
+ C_LEDGER="ghrs-data/clones_ledger.csv"
62
+ if [ ! -f "$C_LEDGER" ]; then
63
+ cp /tmp/new_clones.csv "$C_LEDGER"
49
64
  else
50
- echo "📡 执行物理序列重组..."
51
- (head -n 1 "$LEDGER"; tail -n +2 "$LEDGER"; tail -n +2 /tmp/new_data.csv) | \
52
- sed 's/\//-/g' | \
53
- awk -F',' 'NR>1 {
54
- split($1, a, "-");
55
- if(length(a[2])==1) a[2]="0"a[2];
56
- if(length(a[3])==1) a[3]="0"a[3];
57
- printf "%s-%s-%s,%s,%s\n", a[1], a[2], a[3], $2, $3
58
- }' | awk -F',' '!a[$1]++' | sort -r > /tmp/final_ledger.csv
59
- echo "date,clones,uniques" > "$LEDGER"
60
- cat /tmp/final_ledger.csv >> "$LEDGER"
65
+ (tail -n +2 "$C_LEDGER"; tail -n +2 /tmp/new_clones.csv) | grep -v "date" | \
66
+ sed 's/\//-/g' | awk -F',' '!a[$1]++' | sort -r > /tmp/final_c_data.csv
67
+ echo "date,clones,uniques" > "$C_LEDGER"
68
+ cat /tmp/final_c_data.csv >> "$C_LEDGER"
61
69
  fi
62
70
 
63
- TOTAL_CLONES=$(awk -F',' 'NR>1 {sum+=$2} END {print sum}' "$LEDGER")
64
- echo "{\"total_clones\": $TOTAL_CLONES}" > bunker-stats.json
71
+ # --- 战绩核算 (使用高级变量防护) ---
72
+ TOTAL_CLONES=$(grep -v "date" "$C_LEDGER" | awk -F',' '{sum+=$2} END {print sum}')
73
+ TOTAL_CLONES=${TOTAL_CLONES:-0}
74
+ STARS=$(jq '.stargazers_count // 0' raw_repo.json)
75
+ FORKS=$(jq '.forks_count // 0' raw_repo.json)
76
+
77
+ # 💡 偷师点:用 jq 物理合成 JSON,彻底杜绝语法错误
78
+ jq -n \
79
+ --arg tc "$TOTAL_CLONES" \
80
+ --arg st "$STARS" \
81
+ --arg fk "$FORKS" \
82
+ '{total_clones: ($tc|tonumber), stars: ($st|tonumber), forks: ($fk|tonumber)}' > bunker-stats.json
83
+
84
+ echo "✅ 地堡 7.4 核心战绩封存达成:$TOTAL_CLONES"
65
85
 
66
- # 3. 🧬 【核心新增】:构筑战绩可视化图像
67
- - name: Construct Visual Radar
86
+ # 3. 🧬 【地堡 7.2 终极修复版】:带强力类型转换的看板构筑
87
+ - name: Construct Sovereign Dashboard
68
88
  run: |
69
- echo "🤖 Pod 042: 执行‘图像构筑协议’..."
89
+ echo "🤖 Pod 042: 执行‘全频道看板构筑协议 [类型强转版]’..."
70
90
  python3 <<EOF
71
91
  import pandas as pd
72
92
  import matplotlib.pyplot as plt
93
+ import seaborn as sns
73
94
  import os
74
95
 
75
- # 读取账本并反转顺序(变为正序绘图)
76
- df = pd.read_csv('ghrs-data/clones_ledger.csv')
77
- df['date'] = pd.to_datetime(df['date'])
78
- df = df.sort_values('date')
96
+ # 💡 偷师点:定义一个“暴力清洗”函数,确保数据类型绝对纯净
97
+ def load_hard_clean_csv(path, col_name):
98
+ df = pd.read_csv(path)
99
+ # 1. 强制转换日期,指定格式并踢走非日期行
100
+ df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d', errors='coerce')
101
+ df = df.dropna(subset=['date'])
102
+
103
+ # 2. 🔥 核心修正:强制将数据列转换为数字,脏数据变 NaN 然后填 0
104
+ target_col = col_name.lower()
105
+ if target_col in df.columns:
106
+ df[col_name] = pd.to_numeric(df[target_col], errors='coerce').fillna(0)
107
+
108
+ return df[['date', col_name]]
79
109
 
80
- # 样式设置:地堡深邃黑
81
- plt.style.use('dark_background')
82
- fig, ax = plt.subplots(figsize=(10, 5))
83
-
84
- # 绘制曲线(地堡绿)
85
- ax.plot(df['date'], df['clones'], color='#33cc33', marker='o', markersize=4, linewidth=2, label='Daily Clones')
86
- ax.fill_between(df['date'], df['clones'], color='#33cc33', alpha=0.2)
87
-
88
- ax.set_title('YoRHa Bunker - Physical Construction Trend', fontsize=14, pad=20, color='#33cc33')
89
- ax.set_ylabel('Clone Count', color='#888')
90
- ax.grid(color='#444', linestyle='--', linewidth=0.5)
91
-
92
- # 旋转日期防挤占
93
- plt.xticks(rotation=45, color='#888')
94
- plt.yticks(color='#888')
95
-
96
- # 自动保存
97
- os.makedirs('plots', exist_ok=True)
98
- plt.tight_layout()
99
- plt.savefig('plots/clones_trend.png', dpi=100)
110
+ try:
111
+ # 分别读取并清洗两个账本
112
+ df_c = load_hard_clean_csv('ghrs-data/clones_ledger.csv', 'Clones')
113
+ df_v = load_hard_clean_csv('ghrs-data/views_ledger.csv', 'Views')
114
+
115
+ # 物理对齐与合并(按日期合并)
116
+ df = pd.merge(df_c, df_v, on='date', how='outer').fillna(0)
117
+ df = df.sort_values('date')
118
+
119
+ # 确保合并后的数据也是 float 类型,防止绘图器罢工
120
+ df['Clones'] = df['Clones'].astype(float)
121
+ df['Views'] = df['Views'].astype(float)
122
+ df['cumulative'] = df['Clones'].cumsum()
123
+
124
+ # --- 开始绘图 ---
125
+ plt.style.use('dark_background')
126
+ fig = plt.figure(figsize=(12, 10))
127
+ gs = fig.add_gridspec(3, 1)
128
+
129
+ # 子图 1:Views vs Clones
130
+ ax1 = fig.add_subplot(gs[0])
131
+ plot_df = df.tail(30)
132
+ ax1.plot(plot_df['date'], plot_df['Views'], color='#ffffff', label='Views (Web)', alpha=0.5, linestyle='--')
133
+ ax1.plot(plot_df['date'], plot_df['Clones'], color='#33cc33', label='Clones (Terminal)', linewidth=2)
134
+ ax1.fill_between(plot_df['date'], plot_df['Clones'], color='#33cc33', alpha=0.1)
135
+ ax1.set_title('Strategic Recon: Web Visitors vs Terminal Commandos (Last 30 Days)', color='#33cc33', pad=15)
136
+ ax1.legend()
137
+ ax1.grid(color='#444', linestyle='--', alpha=0.3)
138
+
139
+ # 子图 2:累计荣光抛物线
140
+ ax2 = fig.add_subplot(gs[1])
141
+ ax2.fill_between(df['date'], df['cumulative'], color='#0066ff', alpha=0.2)
142
+ ax2.plot(df['date'], df['cumulative'], color='#0066ff', linewidth=3)
143
+ ax2.set_title('Bunker Glory: Total Cumulative Clones', color='#0066ff', pad=15)
144
+ ax2.grid(color='#444', linestyle=':', alpha=0.3)
145
+
146
+ # 子图 3:作战热力图
147
+ ax3 = fig.add_subplot(gs[2])
148
+ df['week'] = df['date'].dt.isocalendar().week
149
+ df['day'] = df['date'].dt.day_name()
150
+ pivot = df.pivot_table(index='day', columns='week', values='Clones', aggfunc='sum').fillna(0)
151
+ days_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
152
+ pivot = pivot.reindex(days_order)
153
+ sns.heatmap(pivot, cmap='Greens', ax=ax3, cbar=False, annot=False, linewidths=2, linecolor='#1a1a1a')
154
+ ax3.set_title('Deployment Matrix: All-Time Activity', color='#33cc33', pad=15)
155
+ ax3.set_xlabel('Weeks of the Year')
156
+ ax3.set_ylabel('')
157
+
158
+ os.makedirs('plots', exist_ok=True)
159
+ plt.tight_layout()
160
+ plt.savefig('plots/bunker_dashboard.png', dpi=120)
161
+ print(f"✅ 视觉矩阵重构成功!当前全量战绩:{df['cumulative'].max()}")
162
+ except Exception as e:
163
+ print(f"❌ 构筑失败:检测到物理层逻辑冲突: {e}")
164
+ import traceback
165
+ traceback.print_exc()
166
+ exit(1)
100
167
  EOF
101
168
 
102
169
  # 4. [报表装修]
103
- - name: Assemble Report
170
+ - name: Assemble Sovereignty Report
104
171
  run: |
105
- echo "# 🛰️ 地堡运行报告 (Sovereign Report)" > README.md
106
- echo "### 📊 累计物理克隆总数: **$(grep -oE "[0-9]+" bunker-stats.json | head -n 1)**" >> README.md
172
+ STATS="bunker-stats.json"
173
+ TOTAL=$(jq '.total_clones' $STATS)
174
+ STARS=$(jq '.stars' $STATS)
175
+ FORKS=$(jq '.forks' $STATS)
176
+
177
+ echo "# 🛰️ 地堡终极运行报告 (Sovereign Dashboard)" > README.md
178
+ echo "## 📊 核心战力指标" >> README.md
179
+ echo "- **物理克隆总计**: \`$TOTAL\` 次" >> README.md
180
+ echo "- **当前社群声望**: ⭐ \`$STARS\` / 🍴 \`$FORKS\`" >> README.md
181
+ echo "- **地堡协议防护**: AGPL-3.0 生效中" >> README.md
107
182
  echo "" >> README.md
108
183
 
109
- # 💡 物理植入图片
110
- echo "#### 📈 战绩增长雷达 (Growth Radar)" >> README.md
111
- echo "![Clones Trend](./plots/clones_trend.png)" >> README.md
184
+ echo "### 🖥️ 实时作战看板 (Visual Radar)" >> README.md
185
+ echo "![Dashboard](./plots/bunker_dashboard.png)" >> README.md
112
186
  echo "" >> README.md
113
187
 
114
- echo "#### 📡 流量来源实时追踪 (Top Referrers)" >> README.md
115
- echo "| 来源站点 | 总访问量 | 独立指挥官 |" >> README.md
188
+ echo "#### 📡 全球流量来源 (Top Referrers)" >> README.md
189
+ echo "| 来源站点 | 访问量 | 独立指挥官 |" >> README.md
116
190
  echo "| :--- | :--- | :--- |" >> README.md
117
191
  if [ -s raw_referrers.json ]; then
118
192
  jq -r '.[] | "| \(.referrer) | \(.count) | \(.uniques) |"' raw_referrers.json >> README.md
119
193
  else
120
- echo "| 暂无外部来源信号 | - | - |" >> README.md
194
+ echo "| 信号屏蔽中 | - | - |" >> README.md
121
195
  fi
122
196
  echo "" >> README.md
123
- echo "> 📡 信号状态:全频道在线 | 数据物理封存点: $(date +'%Y-%m-%d %H:%M:%S') CST" >> README.md
197
+ echo "> 📡 数据已物理封存:$(date +'%Y-%m-%d %H:%M:%S') CST | Glory to Mankind." >> README.md
124
198
 
125
- # 5. 最终物理封存
126
- - name: Sync Ledger to Cloud
199
+ # 5. 封存推送
200
+ - name: Final Sealing
127
201
  run: |
128
202
  git config user.name github-actions
129
203
  git config user.email github-actions@github.com
130
204
  git add -A
131
- TOTAL=$(grep -oE "[0-9]+" bunker-stats.json | head -n 1)
132
- git commit -m "chore: sovereign update v5.0 - total $TOTAL [$(date +'%Y-%m-%d')]" || echo "no changes"
205
+ TOTAL=$(jq '.total_clones' bunker-stats.json)
206
+ git commit -m "chore: sovereign update v7.0 - total $TOTAL" || echo "no changes"
133
207
  git push origin github-repo-stats --force
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yorha2b-lab/autodev",
3
- "version": "2.1.15",
3
+ "version": "2.1.16",
4
4
  "description": "基于视觉大模型的前端(react+Antd)全自动 CRUD 代码生成器",
5
5
  "bin": {
6
6
  "autodev": "bin/autodev.js"
@@ -5,11 +5,11 @@ import { MySearchForm } from './MySearchForm'
5
5
  import { useTableQuery } from '../hooks/useTableQuery'
6
6
 
7
7
 
8
- export const MyModalTable = ({ api, onOk, title, width, footer, visible, columns, setModal, formItems, rowSelection, formatResponse, functionButtons, extraParams = {} }) => {
8
+ export const MyModalTable = ({ api, onOk, title, width, footer, visible, columns, operate, setModal, formItems, setModalForm, rowSelection, formatResponse, functionButtons, extraParams = {} }) => {
9
9
 
10
10
  const [pending, setPending] = useState(false)
11
11
 
12
- const { total, loading, dataSource, search, setSearch } = useTableQuery(api, formatResponse, extraParams)
12
+ const { total, loading, dataSource, search, refresh, setSearch, setDataSource } = useTableQuery(api, formatResponse, extraParams)
13
13
 
14
14
  const handleSearch = values => setSearch({ ...search, ...values, pageNo: 1 })
15
15
 
@@ -33,13 +33,15 @@ export const MyModalTable = ({ api, onOk, title, width, footer, visible, columns
33
33
  {formItems?.length > 0 && <MySearchForm search={search} formItems={formItems} setSearch={handleSearch} syncUrlParams={false} />}
34
34
  {functionButtons?.length > 0 && <Space>{functionButtons.map(item => <Button key={item.name} type={item.type} onClick={item.onClick}>{item.name}</Button>)}</Space>}
35
35
  <MyTable
36
+ pagination={true}
36
37
  loading={loading}
37
- columns={columns}
38
38
  scroll={{ y: 400 }}
39
39
  dataSource={dataSource}
40
40
  rowSelection={rowSelection}
41
41
  onChange={handleTableChange}
42
- pagination={{ total: total, showSizeChanger: true, current: search.pageNo, pageSize: search.pageSize }} />
42
+ setDataSource={setDataSource}
43
+ columns={operate ? columns.concat(operate({ refresh, setModalForm })) : columns}
44
+ />
43
45
  </Modal>
44
46
  )
45
47
  }
@@ -1,5 +1,5 @@
1
1
  const [form] = Form.useForm()
2
- const [modal, setModal] = useState({})
2
+ const [modal, setModal] = useState({ visible:false, title:'', formItems:[] })
3
3
  {{#if hasRowSelection}}
4
4
  const [selectedRows, setSelectedRows] = useState([])
5
5
  {{/if}}
@@ -21,7 +21,7 @@ export default props => {
21
21
 
22
22
  return (
23
23
  <Card {{#if hasTabs}}tabList={tabs} activeTabKey={activeKey} onTabChange={onTabChange}{{/if}}>
24
- {modal.visible && <MyModalForm {...modal} formItems={modalItems} submit={modalSubmit} setModal={setModal} />}
24
+ {modal.visible && <MyModalForm {...modal} submit={modalSubmit} setModal={setModal} />}
25
25
  {{#each pageStruct as |partialName|}}
26
26
  {{> (partialName) @root }}
27
27
  {{/each}}