@yorha2b-lab/autodev 4.1.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/.github/scripts/analyze/bot_detect.py +5 -5
  2. package/.github/scripts/analyze/cluster.py +5 -5
  3. package/.github/scripts/collect/traffic.py +11 -11
  4. package/.github/scripts/deploy/publish.py +15 -15
  5. package/.github/scripts/render/dashboard.py +9 -9
  6. package/.github/workflows/bunker-intelligence.yml +4 -4
  7. package/bin/autodev.js +6 -5
  8. package/config.js +1 -1
  9. package/package.json +1 -1
  10. package/src/commands/handlers/api-handler.js +15 -10
  11. package/src/commands/handlers/page-handler.js +21 -19
  12. package/src/commands/handlers/part-handler.js +14 -11
  13. package/src/commands/watch.js +20 -18
  14. package/src/core/context.js +39 -52
  15. package/src/core/react-compiler.js +69 -85
  16. package/src/prompts/mock.js +1 -1
  17. package/src/prompts/react/api-linker.js +1 -1
  18. package/src/prompts/react/watch-api.js +1 -1
  19. package/src/prompts/react/watch-page.js +1 -0
  20. package/src/prompts/react/watch-part.js +1 -0
  21. package/src/services/api-linker.js +21 -59
  22. package/src/services/llm.js +64 -81
  23. package/src/services/proxy-tower.js +17 -12
  24. package/src/utils/{utils.js → core.js} +41 -165
  25. package/src/utils/infrastructure.js +102 -0
  26. package/src/utils/ux.js +115 -0
  27. package/templates/react/components/MyModalForm.js +1 -1
  28. package/templates/react/components/MyModalTable.js +1 -1
  29. package/templates/react/components/index.js +2 -2
  30. package/templates/react/handlebars/handleBlock.hbs +3 -2
  31. package/templates/react/handlebars/hookBlock.hbs +1 -0
  32. package/src/core/task-queue.js +0 -38
  33. /package/src/schema/{page.json → react/page.json} +0 -0
@@ -4,7 +4,7 @@ import matplotlib.pyplot as plt
4
4
 
5
5
 
6
6
  def plot_bot_composition():
7
- print("🤖 Pod 042: 正在绘制‘肉机成分分析图’...")
7
+ print('🤖 Pod 042: 正在绘制‘肉机成分分析图’...')
8
8
  df_c = pd.read_csv('ghrs-data/clones_ledger.csv')
9
9
  df_v = pd.read_csv('ghrs-data/views_ledger.csv')
10
10
  df = pd.merge(df_c, df_v, on='date', how='inner')
@@ -25,19 +25,19 @@ def plot_bot_composition():
25
25
 
26
26
  wedges, texts, autotexts = ax.pie(data, labels=labels, autopct='%1.1f%%',
27
27
  startangle=90, colors=colors, pctdistance=0.85,
28
- explode=(0.05, 0), textprops={'color': "w"})
28
+ explode=(0.05, 0), textprops={'color': 'w'})
29
29
 
30
30
  # 画个中间的黑洞,变成甜甜圈
31
31
  centre_circle = plt.Circle((0, 0), 0.70, fc='#0d1117')
32
32
  fig.gca().add_artist(centre_circle)
33
33
 
34
- ax.set_title("Operational Composition: Meat vs Machine",
34
+ ax.set_title('Operational Composition: Meat vs Machine',
35
35
  color='#33cc33', fontsize=14)
36
36
  plt.tight_layout()
37
37
  os.makedirs('plots', exist_ok=True)
38
38
  plt.savefig('plots/bot_composition.png', dpi=100)
39
- print("✅ 甜甜圈图封存成功。")
39
+ print('✅ 甜甜圈图封存成功。')
40
40
 
41
41
 
42
- if __name__ == "__main__":
42
+ if __name__ == '__main__':
43
43
  plot_bot_composition()
@@ -4,7 +4,7 @@ import matplotlib.pyplot as plt
4
4
 
5
5
 
6
6
  def plot_commander_profiles():
7
- print("🤖 Pod 042: 正在绘制‘指挥官军衔分布图’...")
7
+ print('🤖 Pod 042: 正在绘制‘指挥官军衔分布图’...')
8
8
  df_c = pd.read_csv('ghrs-data/clones_ledger.csv')
9
9
  df_c['intensity'] = df_c['clones'] / df_c['uniques'].replace(0, 1)
10
10
 
@@ -27,14 +27,14 @@ def plot_commander_profiles():
27
27
  ax = sns.barplot(x=rank_counts.index,
28
28
  y=rank_counts.values, palette='viridis')
29
29
 
30
- plt.title("Commander Hierarchy Distribution", color='#0066ff', fontsize=14)
31
- plt.ylabel("Node Count", color='#888')
30
+ plt.title('Commander Hierarchy Distribution', color='#0066ff', fontsize=14)
31
+ plt.ylabel('Node Count', color='#888')
32
32
  plt.grid(axis='y', color='#333', linestyle='--', alpha=0.5)
33
33
 
34
34
  plt.tight_layout()
35
35
  plt.savefig('plots/commander_profiles.png', dpi=100)
36
- print("✅ 军衔分布图封存成功。")
36
+ print('✅ 军衔分布图封存成功。')
37
37
 
38
38
 
39
- if __name__ == "__main__":
39
+ if __name__ == '__main__':
40
40
  plot_commander_profiles()
@@ -7,7 +7,7 @@ REPO = os.getenv('REPO')
7
7
  TOKEN = os.getenv('STATS_TOKEN')
8
8
  HEADERS = {'Authorization': f'token {TOKEN}',
9
9
  'Accept': 'application/vnd.github.v3+json'}
10
- API_BASE = f"https://api.github.com/repos/{REPO}"
10
+ API_BASE = f'https://api.github.com/repos/{REPO}'
11
11
 
12
12
 
13
13
  def fetch_api(url, fallback):
@@ -36,14 +36,14 @@ def merge_ledger(data, ledger_path, col_name):
36
36
  ledger_path, index=False)
37
37
 
38
38
 
39
- if __name__ == "__main__":
40
- print("🤖 Pod 042: Executing Data Mining Protocol...")
39
+ if __name__ == '__main__':
40
+ print('🤖 Pod 042: Executing Data Mining Protocol...')
41
41
 
42
42
  # 抓取原始数据
43
- clones = fetch_api(f"{API_BASE}/traffic/clones", {"clones": []})
44
- views = fetch_api(f"{API_BASE}/traffic/views", {"views": []})
45
- repo_info = fetch_api(API_BASE, {"stargazers_count": 0, "forks_count": 0})
46
- referrers = fetch_api(f"{API_BASE}/traffic/popular/referrers", [])
43
+ clones = fetch_api(f'{API_BASE}/traffic/clones', {'clones': []})
44
+ views = fetch_api(f'{API_BASE}/traffic/views', {'views': []})
45
+ repo_info = fetch_api(API_BASE, {'stargazers_count': 0, 'forks_count': 0})
46
+ referrers = fetch_api(f'{API_BASE}/traffic/popular/referrers', [])
47
47
 
48
48
  # 物理焊接账本
49
49
  merge_ledger(clones['clones'], 'ghrs-data/clones_ledger.csv', 'clones')
@@ -57,10 +57,10 @@ if __name__ == "__main__":
57
57
  c_df = pd.read_csv('ghrs-data/clones_ledger.csv')
58
58
  total_clones = int(c_df['clones'].sum())
59
59
  stats = {
60
- "total_clones": total_clones,
61
- "stars": repo_info['stargazers_count'],
62
- "forks": repo_info['forks_count']
60
+ 'total_clones': total_clones,
61
+ 'stars': repo_info['stargazers_count'],
62
+ 'forks': repo_info['forks_count']
63
63
  }
64
64
  with open('bunker-stats.json', 'w') as f:
65
65
  json.dump(stats, f)
66
- print(f"✅ Ledger synced. Total Clones: {total_clones}")
66
+ print(f'✅ Ledger synced. Total Clones: {total_clones}')
@@ -10,14 +10,14 @@ def assemble_readme():
10
10
  with open('raw_referrers.json', 'r') as f:
11
11
  referrers = json.load(f)
12
12
 
13
- ref_table = "| Referrer | Views | Uniques |\n| :--- | :--- | :--- |\n"
13
+ ref_table = '| Referrer | Views | Uniques |\n| :--- | :--- | :--- |\n'
14
14
  if referrers:
15
15
  for r in referrers:
16
- ref_table += f"| {r['referrer']} | {r['count']} | {r['uniques']} |\n"
16
+ ref_table += f'| {r['referrer']} | {r['count']} | {r['uniques']} |\n'
17
17
  else:
18
- ref_table += "| No Signal | - | - |\n"
18
+ ref_table += '| No Signal | - | - |\n'
19
19
 
20
- report = f"""# 🛰️ 地堡终极运行报告 (Sovereign Dashboard v8.5)
20
+ report = f'''# 🛰️ 地堡终极运行报告 (Sovereign Dashboard v8.5)
21
21
  ## 📊 核心战力指标
22
22
  - **累计物理克隆**: `{stats['total_clones']}` 次
23
23
  - **社群声望**: ⭐ `{stats['stars']}` / 🍴 `{stats['forks']}`
@@ -41,7 +41,7 @@ def assemble_readme():
41
41
  {ref_table}
42
42
 
43
43
  > 📡 物理封存点: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')} CST | Glory to Mankind.
44
- """
44
+ '''
45
45
  with open('README.md', 'w') as f:
46
46
  f.write(report)
47
47
 
@@ -51,20 +51,20 @@ def git_push():
51
51
  stats = json.load(f)
52
52
  # 执行物理封存 Git 指令
53
53
  try:
54
- subprocess.run(["git", "config", "user.name",
55
- "github-actions"], check=True)
56
- subprocess.run(["git", "config", "user.email",
57
- "github-actions@github.com"], check=True)
58
- subprocess.run(["git", "add", "-A"], check=True)
54
+ subprocess.run(['git', 'config', 'user.name',
55
+ 'github-actions'], check=True)
56
+ subprocess.run(['git', 'config', 'user.email',
57
+ 'github-actions@github.com'], check=True)
58
+ subprocess.run(['git', 'add', '-A'], check=True)
59
59
  subprocess.run(
60
- ["git", "commit", "-m", f"chore: sovereign modular update [total {stats['total_clones']}]"], check=True)
60
+ ['git', 'commit', '-m', f'chore: sovereign modular update [total {stats['total_clones']}]'], check=True)
61
61
  subprocess.run(
62
- ["git", "push", "origin", "github-repo-stats", "--force"], check=True)
63
- print("✅ Data sealed and pushed to cloud.")
62
+ ['git', 'push', 'origin', 'github-repo-stats', '--force'], check=True)
63
+ print('✅ Data sealed and pushed to cloud.')
64
64
  except Exception as e:
65
- print(f"⚠️ Git push skipped: {e}")
65
+ print(f'⚠️ Git push skipped: {e}')
66
66
 
67
67
 
68
- if __name__ == "__main__":
68
+ if __name__ == '__main__':
69
69
  assemble_readme()
70
70
  git_push()
@@ -26,7 +26,7 @@ def peak_recon():
26
26
  fontsize=14, fontweight='bold')
27
27
 
28
28
  peak_clone_idx = df['clones'].idxmax()
29
- axA.annotate(f'LEGEND PEAK: {df["clones"].max()}',
29
+ axA.annotate(f'LEGEND PEAK: {df['clones'].max()}',
30
30
  xy=(df.loc[peak_clone_idx, 'date'],
31
31
  df.loc[peak_clone_idx, 'clones']),
32
32
  xytext=(10, 20), textcoords='offset points',
@@ -48,7 +48,7 @@ def peak_recon():
48
48
  5 else '#e74c3c' for r in df['ratio']]
49
49
  axC.bar(df['date'], df['ratio'], color=colors3, alpha=0.7)
50
50
  axC.axhline(y=df['ratio'].mean(), color='#9b59b6',
51
- ls='--', label=f'Avg: {df["ratio"].mean():.2f}')
51
+ ls='--', label=f'Avg: {df['ratio'].mean():.2f}')
52
52
  axC.set_title('Clones/Visitor Ratio (High Ratio = CI/Automation)',
53
53
  fontsize=14, fontweight='bold')
54
54
  axC.legend()
@@ -84,7 +84,7 @@ def intelligence_grid():
84
84
  ax1.fill_between(df['date'], df['clones'],
85
85
  alpha=0.3, color='#2E86AB')
86
86
  ax1.axhline(y=df['clones'].mean(), color='red', linestyle='--',
87
- alpha=0.7, label=f'Avg: {df["clones"].mean():.0f}')
87
+ alpha=0.7, label=f'Avg: {df['clones'].mean():.0f}')
88
88
  ax1.set_title('Daily Clone Trend', fontsize=12, fontweight='bold')
89
89
  ax1.set_ylabel('Clones')
90
90
  ax1.legend()
@@ -100,7 +100,7 @@ def intelligence_grid():
100
100
  ax2.fill_between(df['date'], df['uniques'],
101
101
  alpha=0.3, color='#A23B72')
102
102
  ax2.axhline(y=df['uniques'].mean(), color='red', linestyle='--',
103
- alpha=0.7, label=f'Avg: {df["uniques"].mean():.0f}')
103
+ alpha=0.7, label=f'Avg: {df['uniques'].mean():.0f}')
104
104
  ax2.set_title('Daily Unique Commanders',
105
105
  fontsize=12, fontweight='bold')
106
106
  ax2.set_ylabel('Unique Visitors')
@@ -121,7 +121,7 @@ def intelligence_grid():
121
121
  z = np.polyfit(df['uniques'], df['clones'], 1)
122
122
  p = np.poly1d(z)
123
123
  ax3.plot(df['uniques'].sort_values(), p(df['uniques'].sort_values(
124
- )), "r--", alpha=0.7, label=f'Trend: y={z[0]:.1f}x+{z[1]:.1f}')
124
+ )), 'r--', alpha=0.7, label=f'Trend: y={z[0]:.1f}x+{z[1]:.1f}')
125
125
  ax3.legend()
126
126
  ax3.grid(True, alpha=0.3)
127
127
 
@@ -131,7 +131,7 @@ def intelligence_grid():
131
131
  ax4.hist(df['clones_per_unique'], bins=25,
132
132
  color='#F18F01', alpha=0.7, edgecolor='white')
133
133
  ax4.axvline(x=df['clones_per_unique'].mean(
134
- ), color='red', linestyle='--', label=f'Avg: {df["clones_per_unique"].mean():.2f}')
134
+ ), color='red', linestyle='--', label=f'Avg: {df['clones_per_unique'].mean():.2f}')
135
135
  ax4.set_xlabel('Clones Per Unit')
136
136
  ax4.set_ylabel('Days')
137
137
  ax4.set_title('Clones Per User Distribution',
@@ -218,8 +218,8 @@ def main_dashboard(df_c, df_v):
218
218
  plt.tight_layout()
219
219
  plt.savefig('plots/bunker_main_v7.png', dpi=120)
220
220
 
221
- if __name__ == "__main__":
222
- print("🤖 Pod 042: Rendering Strategic Dashboards...")
221
+ if __name__ == '__main__':
222
+ print('🤖 Pod 042: Rendering Strategic Dashboards...')
223
223
  plt.style.use('dark_background')
224
224
  os.makedirs('plots', exist_ok=True)
225
225
 
@@ -232,4 +232,4 @@ if __name__ == "__main__":
232
232
  intelligence_grid()
233
233
  main_dashboard(df_c, df_v)
234
234
 
235
- print("✅ Dashboards rendered.")
235
+ print('✅ Dashboards rendered.')
@@ -39,25 +39,25 @@ jobs:
39
39
 
40
40
  # 💡 步骤 3:运行脚本,注意现在的相对路径!
41
41
  # 我们在当前根目录运行,调用 scripts_repo 里的脚本,去处理 data_repo 里的数据
42
- - name: "🛰️ Step 1: Data Collection"
42
+ - name: '🛰️ Step 1: Data Collection'
43
43
  run: |
44
44
  cd data_repo
45
45
  python ../scripts_repo/.github/scripts/collect/traffic.py
46
46
 
47
- - name: "🧠 Step 2: Intelligence Analysis"
47
+ - name: '🧠 Step 2: Intelligence Analysis'
48
48
  run: |
49
49
  cd data_repo
50
50
  # 执行“肉机比”扫描与“军衔”聚类分析
51
51
  python ../scripts_repo/.github/scripts/analyze/bot_detect.py
52
52
  python ../scripts_repo/.github/scripts/analyze/cluster.py
53
53
 
54
- - name: "📈 Step 3: Visualization Rendering"
54
+ - name: '📈 Step 3: Visualization Rendering'
55
55
  run: |
56
56
  cd data_repo
57
57
  # 渲染核心看板
58
58
  python ../scripts_repo/.github/scripts/render/dashboard.py
59
59
 
60
- - name: "💾 Step 4: Deployment & Sealing"
60
+ - name: '💾 Step 4: Deployment & Sealing'
61
61
  run: |
62
62
  cd data_repo
63
63
  # 物理封存至 README
package/bin/autodev.js CHANGED
@@ -4,8 +4,7 @@ const path = require('path')
4
4
  const chalk = require('chalk')
5
5
  const pkg = require('../package.json')
6
6
  const { program } = require('commander')
7
- const bunker = require('../src/core/context')
8
- const { language, matrixEffect, bootSequence } = require('../src/utils/utils.js')
7
+ const { language, matrixEffect, bootSequence } = require('../src/utils/ux')
9
8
 
10
9
  program
11
10
  .version(pkg.version)
@@ -40,7 +39,7 @@ program
40
39
  console.log(chalk.green(language('🤖 Pod 042: [报告] config.js 存储完毕。', '🤖 Pod 042: [Report] config.js storage complete.')))
41
40
  }
42
41
 
43
- const bunkerCmd = chalk.yellow('"bunker": "autodev watch"')
42
+ const bunkerCmd = chalk.yellow(`'bunker': 'autodev watch'`)
44
43
  console.log(chalk.cyan(language(
45
44
  `📡 Operator 6O: 呼叫 2B, 地堡部署完毕, 为了更快捷地进入战场,建议手动执行 [物理装配]: 将 ${bunkerCmd} 加入您的 package.json scripts 中`,
46
45
  `📡 Operator 6O: Calling 2B! Bunker deployment is complete. To expedite your entry into the battlefield, I recommend a manual [Physical Assembly]: Add ${bunkerCmd} to your package.json scripts.`
@@ -52,6 +51,7 @@ program
52
51
  .alias('start')
53
52
  .description(language('开启全频道联动监控:支持 Page/Part/API 协同构筑', 'Start full-channel linked monitoring: Coordinated Page/Part/API construction'))
54
53
  .action(() => {
54
+ const bunker = require('../src/core/context')
55
55
  const result = bunker.init(program.opts())
56
56
  if (!result) {
57
57
  return
@@ -59,10 +59,11 @@ program
59
59
  bootSequence(pkg.version)
60
60
  require('../src/commands/watch')()
61
61
  const { config } = bunker.get()
62
- if (config.apiDoc && config.enableAutoAlignment) {
62
+ const { apiDoc, needMock, proxyTarget, enableAutoAlignment } = config
63
+ if (apiDoc && enableAutoAlignment) {
63
64
  require('../src/services/api-linker')()
64
65
  }
65
- if (config.proxyTarget && !config.needMock && config.enableAutoAlignment) {
66
+ if (proxyTarget && !needMock && enableAutoAlignment) {
66
67
  require('../src/services/proxy-tower')()
67
68
  }
68
69
  process.on('SIGINT', () => {
package/config.js CHANGED
@@ -22,6 +22,6 @@ module.exports = {
22
22
  proxyTarget: 'http://id:port',
23
23
  responseSuccess: `response?.code === 200`,
24
24
  // 指向公司的 Swagger JSON 地址
25
- apiDoc: 'http://api.company.com/v2/api-docs',
25
+ apiDoc: '',
26
26
 
27
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yorha2b-lab/autodev",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "基于视觉大模型的前端(react+Antd)全自动 CRUD 代码生成器",
5
5
  "bin": {
6
6
  "autodev": "bin/autodev.js"
@@ -1,16 +1,21 @@
1
- const fs = require('fs')
2
- const ora = require('ora')
3
- const path = require('path')
4
- const chalk = require('chalk')
5
-
6
1
  module.exports = async (filePath, liveResponse = null) => {
7
2
 
8
- const { get } = require('../../core/context')
9
- const { config, options, language, unwrapSignal, alignResponseFields } = get()
3
+ const fs = require('fs')
4
+ const ora = require('ora')
5
+ const path = require('path')
6
+ const chalk = require('chalk')
7
+
8
+ const {
9
+ unwrapSignal,
10
+ config, language,
11
+ alignResponseFields
12
+ } = require('../../core/context').get()
13
+
14
+ const { pagesDir } = config
10
15
 
11
16
  const startTime = Date.now()
12
17
  const fileName = liveResponse?.fileName ?? path.basename(filePath, path.extname(filePath))
13
- const resourcePath = path.join(process.cwd(), config.pagesDir, fileName, 'resource.js')
18
+ const resourcePath = path.join(process.cwd(), pagesDir, fileName, 'resource.js')
14
19
 
15
20
  const spinner = ora({
16
21
  text: chalk.yellow(language(
@@ -57,7 +62,7 @@ module.exports = async (filePath, liveResponse = null) => {
57
62
  return Array.from(new Set(keys))
58
63
  }
59
64
 
60
- const result = await alignResponseFields(options, JSON.stringify(sampleData), extractKeys(resourceStr).join(','))
65
+ const result = await alignResponseFields({ responseStr: JSON.stringify(sampleData), resourceStr: extractKeys(resourceStr).join(',') })
61
66
  let changeCount = 0
62
67
  const resultMapping = {}
63
68
  Object.entries(result).forEach(([oldField, newField]) => {
@@ -81,7 +86,7 @@ module.exports = async (filePath, liveResponse = null) => {
81
86
  Object.entries(resultMapping).forEach(([oldField, newField]) => {
82
87
  // 💡 物理校准:计算空格数量,让箭头对齐在第 15 个字符位
83
88
  // 中文字符长度 * 2 是为了抵消它在终端占的双倍宽度
84
- const padding = " ".repeat(Math.max(1, 15 - oldField.length * 2))
89
+ const padding = ' '.repeat(Math.max(1, 15 - oldField.length * 2))
85
90
  console.log(
86
91
  chalk.gray(` │ `) +
87
92
  chalk.yellow(oldField) +
@@ -1,23 +1,25 @@
1
- const fs = require('fs')
2
- const ora = require('ora')
3
- const path = require('path')
4
- const chalk = require('chalk')
5
- const stringify = require('json-stringify-pretty-compact')
6
-
7
1
  module.exports = async filePath => {
8
2
 
9
- const { get } = require('../../core/context')
3
+ const fs = require('fs')
4
+ const ora = require('ora')
5
+ const path = require('path')
6
+ const chalk = require('chalk')
10
7
 
11
8
  const {
12
- config, language, menus,
13
- pagePrompt, resourceTpl, indexTpl,
14
- recognizePage, generateMock, resource, index
15
- } = get()
9
+ language,
10
+ pagePrompt,
11
+ menus, config,
12
+ index, resource,
13
+ contextStringify,
14
+ generateMock, recognizePage,
15
+ } = require('../../core/context').get()
16
+
17
+ const { useDemo, pagesDir, needMock } = config
16
18
 
17
19
  const startTime = Date.now()
18
20
  const fileName = path.basename(filePath, path.extname(filePath))
19
21
  const mockDir = path.join(process.cwd(), 'mock')
20
- const targetDir = path.join(process.cwd(), config.pagesDir, fileName)
22
+ const targetDir = path.join(process.cwd(), pagesDir, fileName)
21
23
 
22
24
  const spinner = ora({
23
25
  text: chalk.cyan(language(
@@ -41,7 +43,7 @@ module.exports = async filePath => {
41
43
  if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir, { recursive: true })
42
44
 
43
45
  let pageConfig
44
- if (config.useDemo) {
46
+ if (useDemo) {
45
47
  console.log(chalk.yellow(language(
46
48
  `\n🤖 Pod 042: [报告] 拦截到实弹请求。正在空投标准模拟包: example.json\n`,
47
49
  `\n🤖 Pod 042: [Report] Real-fire request intercepted. Dropping simulation package: example.json\n`
@@ -52,23 +54,23 @@ module.exports = async filePath => {
52
54
  `🤖 Pod 042: 正在上传视觉元数据至司令部进行语义分析...\n`,
53
55
  `🤖 Pod 042: Uploading visual metadata to Command for semantic analysis...\n`
54
56
  ))
55
- pageConfig = await recognizePage(pagePrompt, filePath)
57
+ pageConfig = await recognizePage({ prompt: pagePrompt, filePath })
56
58
  }
57
59
 
58
- fs.writeFileSync(path.join(targetDir, 'resource.js'), resource({ pageConfig, resourceTpl }))
59
- fs.writeFileSync(path.join(targetDir, 'index.js'), index({ config, fileName, indexTpl, pageConfig }))
60
+ fs.writeFileSync(path.join(targetDir, 'resource.js'), resource({ pageConfig }))
61
+ fs.writeFileSync(path.join(targetDir, 'index.js'), index({ fileName, pageConfig }))
60
62
 
61
63
  if (!menus.find(m => m.key === fileName)) {
62
64
  menus.push({ label: fileName, key: fileName })
63
65
  }
64
66
 
65
- if (config.needMock) {
67
+ if (needMock) {
66
68
  spinner.text = chalk.yellow(language(
67
69
  `🧑‍💻 9S: 正在突破目标防火墙... 执行数据伪装程序 [${fileName}]`,
68
70
  `🧑‍💻 9S: Piercing target firewall... Executing data camouflage [${fileName}]`
69
71
  ))
70
- const rawContent = await generateMock(pageConfig.table.columns, fileName)
71
- fs.writeFileSync(path.join(mockDir, `${fileName}.js`), `export default ${stringify.default(rawContent, { indent: 4, maxLength: 200 })}`)
72
+ const rawContent = await generateMock({ columns: pageConfig.table.columns, fileName })
73
+ fs.writeFileSync(path.join(mockDir, `${fileName}.js`), `export default ${contextStringify({ context: rawContent })}`)
72
74
  console.log(chalk.green(language(
73
75
  `\n[Success] 9S 报告: Mock 数据生成成功`,
74
76
  `\n[Success] 9S Report: Mock data generation successful.`
@@ -1,20 +1,23 @@
1
- const fs = require('fs')
2
- const ora = require('ora')
3
- const chalk = require('chalk')
4
- const stringify = require('json-stringify-pretty-compact')
5
-
6
1
  module.exports = async filePath => {
7
2
 
8
- const { get } = require('../../core/context')
9
- const { language, partPrompt, recognizePage } = get()
10
- const { cleanCode, formatFormItemAndColumns } = require('../../utils/utils')
3
+ const fs = require('fs')
4
+ const ora = require('ora')
5
+ const chalk = require('chalk')
6
+
7
+ const {
8
+ language,
9
+ partPrompt,
10
+ recognizePage,
11
+ contextStringify,
12
+ cleanCode, formatFormItemAndColumns,
13
+ } = require('../../core/context').get()
11
14
 
12
15
  const startTime = Date.now()
13
16
 
14
17
  const spinner = ora({
15
18
  text: chalk.cyan(language(
16
19
  `[System] 侦测到局部视觉样本。正在执行“碎片构筑协议”...`,
17
- `[System] Partial visual sample detected. Executing "Fragment Construction Protocol"...`
20
+ `[System] Partial visual sample detected. Executing 'Fragment Construction Protocol'...`
18
21
  )),
19
22
  color: 'cyan'
20
23
  }).start()
@@ -25,13 +28,13 @@ module.exports = async filePath => {
25
28
  `🤖 Pod 042: Extracting UI metadata from neural cloud network...\n`
26
29
  ))
27
30
 
28
- const pageConfig = await recognizePage(partPrompt, filePath, 'part')
31
+ const pageConfig = await recognizePage({ prompt: partPrompt, filePath, taskType: 'part' })
29
32
 
30
33
  const { formItems, dictBlocks, processedColumns } = formatFormItemAndColumns({ pageConfig })
31
34
 
32
35
  const result = Object.fromEntries(Object.entries({ formItems, processedColumns }).filter(([key, value]) => value?.length > 0))
33
36
 
34
- let mainConfigStr = cleanCode(stringify.default(result, { indent: 4, maxLength: 200 }))
37
+ let mainConfigStr = cleanCode(contextStringify({ context: result }))
35
38
 
36
39
  let optionsCodeStr = ''
37
40
  dictBlocks.forEach(key => {
@@ -1,22 +1,26 @@
1
- const fs = require('fs')
2
- const path = require('path')
3
- const chalk = require('chalk')
4
- const chokidar = require('chokidar')
5
- const stringify = require('json-stringify-pretty-compact')
1
+ module.exports = () => {
6
2
 
7
- const watch = () => {
3
+ const fs = require('fs')
4
+ const path = require('path')
5
+ const chalk = require('chalk')
6
+ const chokidar = require('chokidar')
8
7
 
9
- const { get } = require('../core/context')
10
- const { copyTemplateDir } = require('../utils/utils.js')
11
- const { createTaskQueue } = require('../core/task-queue.js')
8
+ const {
9
+ options,
10
+ language,
11
+ createTaskQueue,
12
+ contextStringify,
13
+ menus, config, copyTemplateDir,
14
+ apiHandler, pageHandler, partHandler,
15
+ } = require('../core/context').get()
12
16
 
13
- const { menus, config, options, language, apiHandler, pageHandler, partHandler } = get()
17
+ const { hbsDir, hooksDir, utilsDir, componentsDir } = config
14
18
 
15
19
  try {
16
- if (config.hbsDir === '') {
17
- copyTemplateDir(options, 'hooks', config.hooksDir)
18
- copyTemplateDir(options, 'utils', config.utilsDir)
19
- copyTemplateDir(options, 'components', config.componentsDir)
20
+ if (hbsDir === '') {
21
+ copyTemplateDir(options, 'hooks', hooksDir)
22
+ copyTemplateDir(options, 'utils', utilsDir)
23
+ copyTemplateDir(options, 'components', componentsDir)
20
24
  }
21
25
  } catch (error) {
22
26
  console.error(language('❌ 模板构筑失败:', '❌ Template construction failed:'), error)
@@ -31,7 +35,7 @@ const watch = () => {
31
35
  )))
32
36
  const utilsDir = path.join(process.cwd(), config.utilsDir)
33
37
  if (!fs.existsSync(utilsDir)) fs.mkdirSync(utilsDir, { recursive: true })
34
- fs.writeFileSync(path.join(utilsDir, 'menus.js'), `export const menus = ${stringify.default(menus, { indent: 4, maxLength: 50 })}`)
38
+ fs.writeFileSync(path.join(utilsDir, 'menus.js'), `export const menus = ${contextStringify({ context: menus, maxLength: 50 })}`)
35
39
  console.log(chalk.gray(language(
36
40
  '\n🤖 [System] 未检测到运行中的任务,系统待机中...\n',
37
41
  '\n🤖 [System] System is STANDBY.\n'
@@ -64,6 +68,4 @@ const watch = () => {
64
68
  queue.add(() => apiHandler(filePath))
65
69
  }
66
70
  })
67
- }
68
-
69
- module.exports = watch
71
+ }