@yorha2b-lab/autodev 4.2.0 → 5.0.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.
- package/.github/scripts/deploy/publish.py +2 -2
- package/.github/scripts/render/dashboard.py +13 -9
- package/CONTRIBUTING.md +0 -18
- package/bin/autodev.js +4 -4
- package/config.js +3 -3
- package/package.json +1 -3
- package/src/bootstrap/handlebars.js +26 -0
- package/src/bootstrap/handlers.js +10 -0
- package/src/bootstrap/index.js +49 -0
- package/src/bootstrap/infrastructure.js +15 -0
- package/src/bootstrap/openai.js +13 -0
- package/src/bootstrap/prompt.js +10 -0
- package/src/commands/watch.js +14 -29
- package/src/{core/react-compiler.js → framework/react/generator/index.js} +1 -1
- package/src/{prompts/react/watch-part.js → framework/react/prompts/part.js} +1 -1
- package/{templates → src/framework}/react/utils/utils.js +1 -1
- package/src/{commands/handlers/api-handler.js → handlers/apiHandler.js} +6 -6
- package/src/{commands/handlers/page-handler.js → handlers/pageHandler.js} +8 -9
- package/src/{commands/handlers/part-handler.js → handlers/partHandler.js} +7 -7
- package/src/{services/api-linker.js → labs/linker.js} +5 -6
- package/src/{services/proxy-tower.js → labs/tower.js} +5 -6
- package/src/services/llm.js +3 -3
- package/src/utils/infrastructure.js +5 -2
- package/src/core/context.js +0 -93
- /package/{templates → src/framework}/react/components/EditableCell.js +0 -0
- /package/{templates → src/framework}/react/components/MyBaseForm.js +0 -0
- /package/{templates → src/framework}/react/components/MyImage.js +0 -0
- /package/{templates → src/framework}/react/components/MyModalForm.js +0 -0
- /package/{templates → src/framework}/react/components/MyModalTable.js +0 -0
- /package/{templates → src/framework}/react/components/MySearchForm.js +0 -0
- /package/{templates → src/framework}/react/components/MyTable.js +0 -0
- /package/{templates → src/framework}/react/components/index.js +0 -0
- /package/{templates/react → src/framework/react/handlebars}/index.hbs +0 -0
- /package/{templates/react/handlebars → src/framework/react/handlebars/partials}/AlertInfo.hbs +0 -0
- /package/{templates/react/handlebars → src/framework/react/handlebars/partials}/FunctionButtons.hbs +0 -0
- /package/{templates/react/handlebars → src/framework/react/handlebars/partials}/MySearchForm.hbs +0 -0
- /package/{templates/react/handlebars → src/framework/react/handlebars/partials}/MyTable.hbs +0 -0
- /package/{templates/react/handlebars → src/framework/react/handlebars/partials}/handleBlock.hbs +0 -0
- /package/{templates/react/handlebars → src/framework/react/handlebars/partials}/hookBlock.hbs +0 -0
- /package/{templates/react/handlebars → src/framework/react/handlebars/partials}/operateBlock.hbs +0 -0
- /package/{templates/react/handlebars → src/framework/react/handlebars/partials}/renderBlock.hbs +0 -0
- /package/{templates/react/handlebars → src/framework/react/handlebars/partials}/stateBlock.hbs +0 -0
- /package/{templates/react → src/framework/react/handlebars}/resource.hbs +0 -0
- /package/{templates → src/framework}/react/hooks/useTableQuery.js +0 -0
- /package/src/{prompts/react/watch-api.js → framework/react/prompts/api.js} +0 -0
- /package/src/{prompts/react/api-linker.js → framework/react/prompts/linker.js} +0 -0
- /package/src/{prompts → framework/react/prompts}/mock.js +0 -0
- /package/src/{prompts/react/watch-page.js → framework/react/prompts/page.js} +0 -0
- /package/src/{prompts → framework/react/prompts}/system.js +0 -0
- /package/src/{schema/react → framework/react/schema}/page.json +0 -0
|
@@ -13,7 +13,7 @@ def assemble_readme():
|
|
|
13
13
|
ref_table = '| Referrer | Views | Uniques |\n| :--- | :--- | :--- |\n'
|
|
14
14
|
if referrers:
|
|
15
15
|
for r in referrers:
|
|
16
|
-
ref_table += f'| {r[
|
|
16
|
+
ref_table += f'| {r["referrer"]} | {r["count"]} | {r["uniques"]} |\n'
|
|
17
17
|
else:
|
|
18
18
|
ref_table += '| No Signal | - | - |\n'
|
|
19
19
|
|
|
@@ -57,7 +57,7 @@ def git_push():
|
|
|
57
57
|
'github-actions@github.com'], check=True)
|
|
58
58
|
subprocess.run(['git', 'add', '-A'], check=True)
|
|
59
59
|
subprocess.run(
|
|
60
|
-
['git', 'commit', '-m', f'chore: sovereign modular update [total {stats[
|
|
60
|
+
['git', 'commit', '-m', f'chore: sovereign modular update [total {stats["total_clones"]}]'], check=True)
|
|
61
61
|
subprocess.run(
|
|
62
62
|
['git', 'push', 'origin', 'github-repo-stats', '--force'], check=True)
|
|
63
63
|
print('✅ Data sealed and pushed to cloud.')
|
|
@@ -5,6 +5,7 @@ import seaborn as sns
|
|
|
5
5
|
import matplotlib.pyplot as plt
|
|
6
6
|
import matplotlib.dates as mdates
|
|
7
7
|
|
|
8
|
+
|
|
8
9
|
def peak_recon():
|
|
9
10
|
df = pd.read_csv('ghrs-data/clones_ledger.csv')
|
|
10
11
|
df['date'] = pd.to_datetime(df['date'])
|
|
@@ -26,7 +27,7 @@ def peak_recon():
|
|
|
26
27
|
fontsize=14, fontweight='bold')
|
|
27
28
|
|
|
28
29
|
peak_clone_idx = df['clones'].idxmax()
|
|
29
|
-
axA.annotate(f'LEGEND PEAK: {df[
|
|
30
|
+
axA.annotate(f'LEGEND PEAK: {df["clones"].max()}',
|
|
30
31
|
xy=(df.loc[peak_clone_idx, 'date'],
|
|
31
32
|
df.loc[peak_clone_idx, 'clones']),
|
|
32
33
|
xytext=(10, 20), textcoords='offset points',
|
|
@@ -48,7 +49,7 @@ def peak_recon():
|
|
|
48
49
|
5 else '#e74c3c' for r in df['ratio']]
|
|
49
50
|
axC.bar(df['date'], df['ratio'], color=colors3, alpha=0.7)
|
|
50
51
|
axC.axhline(y=df['ratio'].mean(), color='#9b59b6',
|
|
51
|
-
ls='--', label=f'Avg: {df[
|
|
52
|
+
ls='--', label=f'Avg: {df["ratio"].mean():.2f}')
|
|
52
53
|
axC.set_title('Clones/Visitor Ratio (High Ratio = CI/Automation)',
|
|
53
54
|
fontsize=14, fontweight='bold')
|
|
54
55
|
axC.legend()
|
|
@@ -56,6 +57,7 @@ def peak_recon():
|
|
|
56
57
|
plt.tight_layout()
|
|
57
58
|
plt.savefig('plots/bunker_peak_recon.png', dpi=100)
|
|
58
59
|
|
|
60
|
+
|
|
59
61
|
def intelligence_grid():
|
|
60
62
|
df = pd.read_csv('ghrs-data/clones_ledger.csv')
|
|
61
63
|
df['date'] = pd.to_datetime(df['date'])
|
|
@@ -84,7 +86,7 @@ def intelligence_grid():
|
|
|
84
86
|
ax1.fill_between(df['date'], df['clones'],
|
|
85
87
|
alpha=0.3, color='#2E86AB')
|
|
86
88
|
ax1.axhline(y=df['clones'].mean(), color='red', linestyle='--',
|
|
87
|
-
alpha=0.7, label=f'Avg: {df[
|
|
89
|
+
alpha=0.7, label=f'Avg: {df["clones"].mean():.0f}')
|
|
88
90
|
ax1.set_title('Daily Clone Trend', fontsize=12, fontweight='bold')
|
|
89
91
|
ax1.set_ylabel('Clones')
|
|
90
92
|
ax1.legend()
|
|
@@ -100,7 +102,7 @@ def intelligence_grid():
|
|
|
100
102
|
ax2.fill_between(df['date'], df['uniques'],
|
|
101
103
|
alpha=0.3, color='#A23B72')
|
|
102
104
|
ax2.axhline(y=df['uniques'].mean(), color='red', linestyle='--',
|
|
103
|
-
alpha=0.7, label=f'Avg: {df[
|
|
105
|
+
alpha=0.7, label=f'Avg: {df["uniques"].mean():.0f}')
|
|
104
106
|
ax2.set_title('Daily Unique Commanders',
|
|
105
107
|
fontsize=12, fontweight='bold')
|
|
106
108
|
ax2.set_ylabel('Unique Visitors')
|
|
@@ -121,7 +123,7 @@ def intelligence_grid():
|
|
|
121
123
|
z = np.polyfit(df['uniques'], df['clones'], 1)
|
|
122
124
|
p = np.poly1d(z)
|
|
123
125
|
ax3.plot(df['uniques'].sort_values(), p(df['uniques'].sort_values(
|
|
124
|
-
)),
|
|
126
|
+
)), "r--", alpha=0.7, label=f'Trend: y={z[0]:.1f}x+{z[1]:.1f}')
|
|
125
127
|
ax3.legend()
|
|
126
128
|
ax3.grid(True, alpha=0.3)
|
|
127
129
|
|
|
@@ -131,7 +133,7 @@ def intelligence_grid():
|
|
|
131
133
|
ax4.hist(df['clones_per_unique'], bins=25,
|
|
132
134
|
color='#F18F01', alpha=0.7, edgecolor='white')
|
|
133
135
|
ax4.axvline(x=df['clones_per_unique'].mean(
|
|
134
|
-
), color='red', linestyle='--', label=f'Avg: {df[
|
|
136
|
+
), color='red', linestyle='--', label=f'Avg: {df["clones_per_unique"].mean():.2f}')
|
|
135
137
|
ax4.set_xlabel('Clones Per Unit')
|
|
136
138
|
ax4.set_ylabel('Days')
|
|
137
139
|
ax4.set_title('Clones Per User Distribution',
|
|
@@ -178,6 +180,7 @@ def intelligence_grid():
|
|
|
178
180
|
plt.tight_layout(rect=[0, 0.03, 1, 0.95])
|
|
179
181
|
plt.savefig('plots/bunker_intelligence_grid.png', dpi=100)
|
|
180
182
|
|
|
183
|
+
|
|
181
184
|
def load_clean(path, col):
|
|
182
185
|
df = pd.read_csv(path)
|
|
183
186
|
df['date'] = pd.to_datetime(df['date'], errors='coerce')
|
|
@@ -218,8 +221,9 @@ def main_dashboard(df_c, df_v):
|
|
|
218
221
|
plt.tight_layout()
|
|
219
222
|
plt.savefig('plots/bunker_main_v7.png', dpi=120)
|
|
220
223
|
|
|
221
|
-
|
|
222
|
-
|
|
224
|
+
|
|
225
|
+
if __name__ == "__main__":
|
|
226
|
+
print("🤖 Pod 042: Rendering Strategic Dashboards...")
|
|
223
227
|
plt.style.use('dark_background')
|
|
224
228
|
os.makedirs('plots', exist_ok=True)
|
|
225
229
|
|
|
@@ -232,4 +236,4 @@ if __name__ == '__main__':
|
|
|
232
236
|
intelligence_grid()
|
|
233
237
|
main_dashboard(df_c, df_v)
|
|
234
238
|
|
|
235
|
-
print(
|
|
239
|
+
print("✅ Dashboards rendered.")
|
package/CONTRIBUTING.md
CHANGED
|
@@ -75,24 +75,6 @@ cp .env.example .env
|
|
|
75
75
|
# 编辑 .env 文件,填入您的API密钥
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
### 项目结构
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
auto-crud-copilot/
|
|
82
|
-
├── bin/ # 可执行文件
|
|
83
|
-
├── src/
|
|
84
|
-
│ ├── commands/ # 命令实现
|
|
85
|
-
│ ├── core/ # 核心逻辑
|
|
86
|
-
│ ├── prompts/ # AI提示词
|
|
87
|
-
│ ├── services/ # 服务层
|
|
88
|
-
│ └── utils/ # 工具函数
|
|
89
|
-
├── templates/ # 代码模板
|
|
90
|
-
│ ├── react/
|
|
91
|
-
│ ├── vue/
|
|
92
|
-
│ └── angular/
|
|
93
|
-
└── config.js # 配置文件
|
|
94
|
-
```
|
|
95
|
-
|
|
96
78
|
- 提交信息遵循[Conventional Commits](https://www.conventionalcommits.org/zh-hans/v1.0.0/)规范
|
|
97
79
|
|
|
98
80
|
### 测试
|
package/bin/autodev.js
CHANGED
|
@@ -51,20 +51,20 @@ program
|
|
|
51
51
|
.alias('start')
|
|
52
52
|
.description(language('开启全频道联动监控:支持 Page/Part/API 协同构筑', 'Start full-channel linked monitoring: Coordinated Page/Part/API construction'))
|
|
53
53
|
.action(() => {
|
|
54
|
-
const bunker = require('../src/
|
|
54
|
+
const bunker = require('../src/bootstrap')
|
|
55
55
|
const result = bunker.init(program.opts())
|
|
56
56
|
if (!result) {
|
|
57
57
|
return
|
|
58
58
|
}
|
|
59
59
|
bootSequence(pkg.version)
|
|
60
60
|
require('../src/commands/watch')()
|
|
61
|
-
const { config } =
|
|
61
|
+
const { config } = result.infrastructure
|
|
62
62
|
const { apiDoc, needMock, proxyTarget, enableAutoAlignment } = config
|
|
63
63
|
if (apiDoc && enableAutoAlignment) {
|
|
64
|
-
require('../src/
|
|
64
|
+
require('../src/labs/linker')()
|
|
65
65
|
}
|
|
66
66
|
if (proxyTarget && !needMock && enableAutoAlignment) {
|
|
67
|
-
require('../src/
|
|
67
|
+
require('../src/labs/tower')()
|
|
68
68
|
}
|
|
69
69
|
process.on('SIGINT', () => {
|
|
70
70
|
console.log('\n')
|
package/config.js
CHANGED
|
@@ -18,10 +18,10 @@ module.exports = {
|
|
|
18
18
|
utilsDir: 'src/utils',
|
|
19
19
|
componentsDir: 'src/components',
|
|
20
20
|
|
|
21
|
-
// 代理目标
|
|
22
|
-
proxyTarget: 'http://id:port',
|
|
23
|
-
responseSuccess: `response?.code === 200`,
|
|
24
21
|
// 指向公司的 Swagger JSON 地址
|
|
25
22
|
apiDoc: '',
|
|
23
|
+
// 代理目标
|
|
24
|
+
proxyTarget: '',
|
|
25
|
+
responseSuccess: `response?.code === 200`,
|
|
26
26
|
|
|
27
27
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yorha2b-lab/autodev",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "基于视觉大模型的前端(react+Antd)全自动 CRUD 代码生成器",
|
|
5
5
|
"bin": {
|
|
6
6
|
"autodev": "bin/autodev.js"
|
|
@@ -14,8 +14,6 @@
|
|
|
14
14
|
"ai",
|
|
15
15
|
"vision",
|
|
16
16
|
"react",
|
|
17
|
-
"vue",
|
|
18
|
-
"angular",
|
|
19
17
|
"antd",
|
|
20
18
|
"umi",
|
|
21
19
|
"code-generation",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module.exports = ({ config, template, contextStringify }) => {
|
|
2
|
+
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const Handlebars = require('handlebars')
|
|
6
|
+
|
|
7
|
+
Handlebars.registerHelper('raw', opt => opt.fn())
|
|
8
|
+
Handlebars.registerHelper('stringify', (context, maxLength = 200) => context ? new Handlebars.SafeString(contextStringify({ context, maxLength })) : '[]')
|
|
9
|
+
|
|
10
|
+
const { hbsDir } = config
|
|
11
|
+
const tplDir = hbsDir !== '' ? path.join(process.cwd(), hbsDir) : path.join(__dirname, `../framework/${template}/handlebars`)
|
|
12
|
+
const partialsDir = hbsDir !== '' ? path.join(process.cwd(), hbsDir) : path.join(__dirname, `../framework/${template}/handlebars/partials`)
|
|
13
|
+
|
|
14
|
+
fs.readdirSync(partialsDir).forEach(file => {
|
|
15
|
+
if (file.endsWith('.hbs')) {
|
|
16
|
+
const name = path.basename(file, '.hbs') // 去掉后缀拿名字
|
|
17
|
+
const content = fs.readFileSync(path.join(partialsDir, file), 'utf-8')
|
|
18
|
+
Handlebars.registerPartial(name, `${content}\n`)
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
indexTpl: Handlebars.compile(fs.readFileSync(path.join(tplDir, 'index.hbs'), 'utf-8')),
|
|
24
|
+
resourceTpl: Handlebars.compile(fs.readFileSync(path.join(tplDir, 'resource.hbs'), 'utf-8')),
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module.exports = () => {
|
|
2
|
+
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
|
|
6
|
+
const handlersPath = path.join(__dirname, `../handlers`)
|
|
7
|
+
const handlers = fs.readdirSync(handlersPath).map(handler => [path.basename(handler, '.js'), require(path.join(handlersPath, handler))])
|
|
8
|
+
|
|
9
|
+
return Object.fromEntries(handlers)
|
|
10
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const chalk = require('chalk')
|
|
4
|
+
|
|
5
|
+
let instance = null
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
|
|
9
|
+
init: options => {
|
|
10
|
+
|
|
11
|
+
const template = options.template
|
|
12
|
+
const ux = require('../utils/ux')
|
|
13
|
+
|
|
14
|
+
const generatorPath = path.join(__dirname, `../framework/${template}/generator`)
|
|
15
|
+
if (!fs.existsSync(generatorPath)) {
|
|
16
|
+
console.error(chalk.red(ux.language(`❌ 暂不支持 [${template}] 框架。欢迎提交 Pull Request 贡献。`, `❌ [${template}] framework not supported. Welcome to contribute a Pull Request to help.`)))
|
|
17
|
+
return
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const infrastructure = require('../utils/infrastructure')
|
|
21
|
+
|
|
22
|
+
const openAI = require('./openai')()
|
|
23
|
+
const core = require('../utils/core')
|
|
24
|
+
const handlers = require('./handlers')()
|
|
25
|
+
const config = infrastructure.getConfig()
|
|
26
|
+
const menus = infrastructure.getExistingMenus()
|
|
27
|
+
const prompts = require('./prompt')({ template })
|
|
28
|
+
require('./infrastructure')({ ux, config, options, ...infrastructure })
|
|
29
|
+
const llm = require('../services/llm')({ config, openAI, template, ...prompts })
|
|
30
|
+
const handlebars = require('./handlebars')({ config, template, ...infrastructure })
|
|
31
|
+
const generator = require(generatorPath)({ config, ...core, ...handlebars, ...infrastructure })
|
|
32
|
+
|
|
33
|
+
instance = {
|
|
34
|
+
ux,
|
|
35
|
+
llm,
|
|
36
|
+
core,
|
|
37
|
+
openAI,
|
|
38
|
+
prompts,
|
|
39
|
+
handlers,
|
|
40
|
+
generator,
|
|
41
|
+
handlebars,
|
|
42
|
+
cli: options,
|
|
43
|
+
infrastructure: { menus, config, ...infrastructure },
|
|
44
|
+
}
|
|
45
|
+
return instance
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
get: () => instance
|
|
49
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module.exports = ({ ux, config, options, copyTemplateDir }) => {
|
|
2
|
+
|
|
3
|
+
const { language } = ux
|
|
4
|
+
const { hbsDir, hooksDir, utilsDir, componentsDir } = config
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
if (hbsDir === '') {
|
|
8
|
+
copyTemplateDir(options, 'hooks', hooksDir)
|
|
9
|
+
copyTemplateDir(options, 'utils', utilsDir)
|
|
10
|
+
copyTemplateDir(options, 'components', componentsDir)
|
|
11
|
+
}
|
|
12
|
+
} catch (error) {
|
|
13
|
+
console.error(language('❌ 模板构筑失败:', '❌ Template construction failed:'), error)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module.exports = () => {
|
|
2
|
+
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const OpenAI = require('openai')
|
|
6
|
+
|
|
7
|
+
const pkgEnv = path.resolve(__dirname, '../.env')
|
|
8
|
+
const localEnv = path.resolve(process.cwd(), '.env')
|
|
9
|
+
require('dotenv').config({ path: fs.existsSync(localEnv) ? localEnv : pkgEnv })
|
|
10
|
+
const openAI = new OpenAI({ apiKey: process.env.API_KEY, baseURL: process.env.BASE_URL })
|
|
11
|
+
|
|
12
|
+
return openAI
|
|
13
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module.exports = ({ template }) => {
|
|
2
|
+
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
|
|
6
|
+
const promptsPath = path.join(__dirname, `../framework/${template}/prompts`)
|
|
7
|
+
const prompts = fs.readdirSync(promptsPath).map(prompt => [`${path.basename(prompt, '.js')}Prompt`, require(path.join(promptsPath, prompt))])
|
|
8
|
+
|
|
9
|
+
return Object.fromEntries(prompts)
|
|
10
|
+
}
|
package/src/commands/watch.js
CHANGED
|
@@ -5,26 +5,12 @@ module.exports = () => {
|
|
|
5
5
|
const chalk = require('chalk')
|
|
6
6
|
const chokidar = require('chokidar')
|
|
7
7
|
|
|
8
|
-
const {
|
|
9
|
-
options,
|
|
10
|
-
language,
|
|
11
|
-
createTaskQueue,
|
|
12
|
-
contextStringify,
|
|
13
|
-
menus, config, copyTemplateDir,
|
|
14
|
-
apiHandler, pageHandler, partHandler,
|
|
15
|
-
} = require('../core/context').get()
|
|
8
|
+
const { ux, core, handlers, infrastructure } = require('../bootstrap').get()
|
|
16
9
|
|
|
17
|
-
const {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
copyTemplateDir(options, 'hooks', hooksDir)
|
|
22
|
-
copyTemplateDir(options, 'utils', utilsDir)
|
|
23
|
-
copyTemplateDir(options, 'components', componentsDir)
|
|
24
|
-
}
|
|
25
|
-
} catch (error) {
|
|
26
|
-
console.error(language('❌ 模板构筑失败:', '❌ Template construction failed:'), error)
|
|
27
|
-
}
|
|
10
|
+
const { language } = ux
|
|
11
|
+
const { createTaskQueue } = core
|
|
12
|
+
const { apiHandler, pageHandler, partHandler } = handlers
|
|
13
|
+
const { menus, config, contextStringify } = infrastructure
|
|
28
14
|
|
|
29
15
|
const queue = createTaskQueue(2)
|
|
30
16
|
|
|
@@ -54,18 +40,17 @@ module.exports = () => {
|
|
|
54
40
|
'📡 Operator 6O: Calling 2B, all-channel linked monitoring is ready!'
|
|
55
41
|
)))
|
|
56
42
|
|
|
57
|
-
|
|
43
|
+
const routes = [
|
|
44
|
+
{ match: 'response', handler: apiHandler },
|
|
45
|
+
{ match: 'screenShot', handler: pageHandler },
|
|
46
|
+
{ match: 'screenPart', handler: partHandler },
|
|
47
|
+
]
|
|
58
48
|
|
|
49
|
+
watcher.on('add', filePath => {
|
|
59
50
|
const absolutePath = path.resolve(filePath)
|
|
60
|
-
|
|
61
|
-
if (
|
|
62
|
-
queue.add(() =>
|
|
63
|
-
}
|
|
64
|
-
else if (absolutePath.includes('screenPart')) {
|
|
65
|
-
queue.add(() => partHandler(filePath))
|
|
66
|
-
}
|
|
67
|
-
else if (absolutePath.includes('response')) {
|
|
68
|
-
queue.add(() => apiHandler(filePath))
|
|
51
|
+
const route = routes.find(r => absolutePath.includes(r.match))
|
|
52
|
+
if (route) {
|
|
53
|
+
queue.add(() => route.handler(filePath))
|
|
69
54
|
}
|
|
70
55
|
})
|
|
71
56
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module.exports = ({ config,
|
|
1
|
+
module.exports = ({ config, indexTpl, cleanCode, resourceTpl, contextStringify, generateSmartImports, formatFormItemAndColumns, }) => {
|
|
2
2
|
|
|
3
3
|
const { needMock, responseSuccess } = config
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ module.exports = `
|
|
|
8
8
|
3. 必须严格遵守以下字段规范。
|
|
9
9
|
|
|
10
10
|
## 1. 表格 (Table)
|
|
11
|
-
- 结构: { columns: [{ title: '列名', dataIndex: '
|
|
11
|
+
- 结构: { columns: [{ title: '列名', dataIndex: '***englishName***', type: '' }] }
|
|
12
12
|
- ⚠️ 字段白名单: [title, dataIndex, sorter, render, filters, onFilter]
|
|
13
13
|
- **注意**: type为text时必须省略type属性。
|
|
14
14
|
- 禁止输出:
|
|
@@ -100,7 +100,7 @@ export const timeRender = ({ time, date, minute }) => {
|
|
|
100
100
|
* @param {Function} [formatter] - 数据预处理回调
|
|
101
101
|
* @param {Array} columns - 表格列配置,支持 exportRender 优先级
|
|
102
102
|
*/
|
|
103
|
-
export const exportDataToExcel = async (url, options, columns, fileName, formatter) => {
|
|
103
|
+
export const exportDataToExcel = async ({ url, options, columns, fileName, formatter }) => {
|
|
104
104
|
/* const response = await request(url, options)
|
|
105
105
|
const result = formatter ? formatter(response) : (response?.data ?? [])
|
|
106
106
|
if (result?.length > 0) {
|
|
@@ -5,14 +5,14 @@ module.exports = async (filePath, liveResponse = null) => {
|
|
|
5
5
|
const path = require('path')
|
|
6
6
|
const chalk = require('chalk')
|
|
7
7
|
|
|
8
|
-
const {
|
|
9
|
-
unwrapSignal,
|
|
10
|
-
config, language,
|
|
11
|
-
alignResponseFields
|
|
12
|
-
} = require('../../core/context').get()
|
|
8
|
+
const { ux, llm, core, infrastructure } = require('../bootstrap').get()
|
|
13
9
|
|
|
14
|
-
const {
|
|
10
|
+
const { language } = ux
|
|
11
|
+
const { unwrapSignal } = core
|
|
12
|
+
const { config } = infrastructure
|
|
13
|
+
const { alignResponseFields } = llm
|
|
15
14
|
|
|
15
|
+
const { pagesDir } = config
|
|
16
16
|
const startTime = Date.now()
|
|
17
17
|
const fileName = liveResponse?.fileName ?? path.basename(filePath, path.extname(filePath))
|
|
18
18
|
const resourcePath = path.join(process.cwd(), pagesDir, fileName, 'resource.js')
|
|
@@ -5,14 +5,13 @@ module.exports = async filePath => {
|
|
|
5
5
|
const path = require('path')
|
|
6
6
|
const chalk = require('chalk')
|
|
7
7
|
|
|
8
|
-
const {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} = require('../../core/context').get()
|
|
8
|
+
const { ux, llm, prompts, generator, infrastructure } = require('../bootstrap').get()
|
|
9
|
+
|
|
10
|
+
const { language } = ux
|
|
11
|
+
const { pagePrompt } = prompts
|
|
12
|
+
const { index, resource } = generator
|
|
13
|
+
const { generateMock, recognizePage } = llm
|
|
14
|
+
const { menus, config, contextStringify } = infrastructure
|
|
16
15
|
|
|
17
16
|
const { useDemo, pagesDir, needMock } = config
|
|
18
17
|
|
|
@@ -48,7 +47,7 @@ module.exports = async filePath => {
|
|
|
48
47
|
`\n🤖 Pod 042: [报告] 拦截到实弹请求。正在空投标准模拟包: example.json\n`,
|
|
49
48
|
`\n🤖 Pod 042: [Report] Real-fire request intercepted. Dropping simulation package: example.json\n`
|
|
50
49
|
)))
|
|
51
|
-
pageConfig = require('
|
|
50
|
+
pageConfig = require('../../example/example.json')
|
|
52
51
|
} else {
|
|
53
52
|
spinner.text = chalk.cyan(language(
|
|
54
53
|
`🤖 Pod 042: 正在上传视觉元数据至司令部进行语义分析...\n`,
|
|
@@ -4,13 +4,13 @@ module.exports = async filePath => {
|
|
|
4
4
|
const ora = require('ora')
|
|
5
5
|
const chalk = require('chalk')
|
|
6
6
|
|
|
7
|
-
const {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} =
|
|
7
|
+
const { ux, llm, core, prompts, infrastructure } = require('../bootstrap').get()
|
|
8
|
+
|
|
9
|
+
const { language } = ux
|
|
10
|
+
const { partPrompt } = prompts
|
|
11
|
+
const { recognizePage } = llm
|
|
12
|
+
const { contextStringify } = infrastructure
|
|
13
|
+
const { cleanCode, formatFormItemAndColumns } = core
|
|
14
14
|
|
|
15
15
|
const startTime = Date.now()
|
|
16
16
|
|
|
@@ -4,12 +4,11 @@ module.exports = async () => {
|
|
|
4
4
|
const path = require('path')
|
|
5
5
|
const chalk = require('chalk')
|
|
6
6
|
|
|
7
|
-
const {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} = require('../core/context').get()
|
|
7
|
+
const { ux, llm, infrastructure } = require('../bootstrap').get()
|
|
8
|
+
|
|
9
|
+
const { language } = ux
|
|
10
|
+
const { apiLinker } = llm
|
|
11
|
+
const { config, getLocalScore, getSemanticKeywords, } = infrastructure
|
|
13
12
|
|
|
14
13
|
const { apiDoc, pagesDir } = config
|
|
15
14
|
if (!apiDoc) return
|
|
@@ -10,13 +10,12 @@ module.exports = () => {
|
|
|
10
10
|
const chalk = require('chalk')
|
|
11
11
|
const httpProxy = require('http-proxy')
|
|
12
12
|
|
|
13
|
-
const {
|
|
14
|
-
config,
|
|
15
|
-
language,
|
|
16
|
-
apiHandler,
|
|
17
|
-
unwrapSignal, isQuerySignal
|
|
18
|
-
} = require('../core/context').get()
|
|
13
|
+
const { ux, core, handlers, infrastructure } = require('../bootstrap').get()
|
|
19
14
|
|
|
15
|
+
const { language } = ux
|
|
16
|
+
const { apiHandler } = handlers
|
|
17
|
+
const { config } = infrastructure
|
|
18
|
+
const { unwrapSignal, isQuerySignal } = core
|
|
20
19
|
const { routeMap = {}, proxyTarget } = config
|
|
21
20
|
|
|
22
21
|
const TOWER_PORT = 42153
|
package/src/services/llm.js
CHANGED
|
@@ -43,12 +43,12 @@ const askAI = async ({ model, openAI, messages, response_format = { type: 'json_
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
module.exports = ({ config, openAI, template,
|
|
46
|
+
module.exports = ({ config, openAI, template, systemPrompt, apiPrompt, mockPrompt, linkerPrompt }) => {
|
|
47
47
|
|
|
48
48
|
const sharp = require('sharp')
|
|
49
49
|
|
|
50
50
|
const { textModel, visionModel } = config
|
|
51
|
-
const { UI_DESIGNER, API_DESIGNER, MOCK_DESIGNER } =
|
|
51
|
+
const { UI_DESIGNER, API_DESIGNER, MOCK_DESIGNER } = systemPrompt
|
|
52
52
|
|
|
53
53
|
return {
|
|
54
54
|
generateMock: async ({ columns, fileName }) => {
|
|
@@ -101,7 +101,7 @@ module.exports = ({ config, openAI, template, sysPrompt, apiPrompt, mockPrompt,
|
|
|
101
101
|
]
|
|
102
102
|
}
|
|
103
103
|
],
|
|
104
|
-
response_format: taskType === 'page' ? { type: 'json_schema', strict: true, json_schema: require(`../
|
|
104
|
+
response_format: taskType === 'page' ? { type: 'json_schema', strict: true, json_schema: require(`../framework/${template}/schema/page.json`) } : { type: 'json_object' }
|
|
105
105
|
})
|
|
106
106
|
},
|
|
107
107
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
const fs = require('fs')
|
|
11
11
|
const path = require('path')
|
|
12
12
|
const { Segment, useDefault } = require('segmentit')
|
|
13
|
+
const stringify = require('json-stringify-pretty-compact')
|
|
13
14
|
const segmentit = useDefault(new Segment())
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -87,7 +88,7 @@ const getLocalScore = (api, pageKeywords, moduleName) => {
|
|
|
87
88
|
*/
|
|
88
89
|
const copyTemplateDir = (options, templateSubDir, targetSubDir) => {
|
|
89
90
|
const targetDir = path.join(process.cwd(), targetSubDir)
|
|
90
|
-
const sourceDir = path.join(__dirname,
|
|
91
|
+
const sourceDir = path.join(__dirname, `../framework/${options.template}/${templateSubDir}`)
|
|
91
92
|
if (!fs.existsSync(sourceDir)) return
|
|
92
93
|
fs.mkdirSync(targetDir, { recursive: true })
|
|
93
94
|
fs.readdirSync(sourceDir).forEach(file => {
|
|
@@ -99,4 +100,6 @@ const copyTemplateDir = (options, templateSubDir, targetSubDir) => {
|
|
|
99
100
|
})
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
const contextStringify = ({ context, indent = 4, maxLength = 200 }) => stringify.default(context, { indent, maxLength })
|
|
104
|
+
|
|
105
|
+
module.exports = { getConfig, getLocalScore, getExistingMenus, copyTemplateDir, contextStringify, getSemanticKeywords }
|
package/src/core/context.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const chalk = require('chalk')
|
|
4
|
-
const OpenAI = require('openai')
|
|
5
|
-
const Handlebars = require('handlebars')
|
|
6
|
-
const stringify = require('json-stringify-pretty-compact')
|
|
7
|
-
|
|
8
|
-
const contextStringify = ({ context, indent = 4, maxLength = 200 }) => stringify.default(context, { indent, maxLength })
|
|
9
|
-
|
|
10
|
-
Handlebars.registerHelper('raw', opt => opt.fn())
|
|
11
|
-
Handlebars.registerHelper('stringify', (context, maxLength = 200) => context ? new Handlebars.SafeString(contextStringify({ context, maxLength })) : '[]')
|
|
12
|
-
|
|
13
|
-
let instance = null
|
|
14
|
-
|
|
15
|
-
module.exports = {
|
|
16
|
-
|
|
17
|
-
init: options => {
|
|
18
|
-
|
|
19
|
-
const template = options.template
|
|
20
|
-
const uxCtx = require('../utils/ux')
|
|
21
|
-
const coreCtx = require('../utils/core')
|
|
22
|
-
const infrastructureCtx = require('../utils/infrastructure')
|
|
23
|
-
|
|
24
|
-
const { language } = uxCtx
|
|
25
|
-
const { getConfig, getExistingMenus } = infrastructureCtx
|
|
26
|
-
|
|
27
|
-
const config = getConfig()
|
|
28
|
-
const { hbsDir } = config
|
|
29
|
-
|
|
30
|
-
const menus = getExistingMenus()
|
|
31
|
-
const apiHandler = require('../commands/handlers/api-handler')
|
|
32
|
-
const pageHandler = require('../commands/handlers/page-handler')
|
|
33
|
-
const partHandler = require('../commands/handlers/part-handler')
|
|
34
|
-
const tplDir = hbsDir !== '' ? path.join(process.cwd(), hbsDir) : path.join(__dirname, `../../templates/${template}`)
|
|
35
|
-
|
|
36
|
-
const compilerPath = path.join(__dirname, `./${template}-compiler.js`)
|
|
37
|
-
if (!fs.existsSync(compilerPath)) {
|
|
38
|
-
console.error(chalk.red(language(`❌ 暂不支持 [${template}] 框架。欢迎提交 Pull Request 贡献。`, `❌ [${template}] framework not supported. Welcome to contribute a Pull Request to help.`)))
|
|
39
|
-
return
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const partialsDir = hbsDir !== '' ? path.join(process.cwd(), hbsDir, 'handlebars') : path.join(__dirname, `../../templates/${template}/handlebars`)
|
|
43
|
-
fs.readdirSync(partialsDir).forEach(file => {
|
|
44
|
-
if (file.endsWith('.hbs')) {
|
|
45
|
-
const name = path.basename(file, '.hbs') // 去掉后缀拿名字
|
|
46
|
-
const content = fs.readFileSync(path.join(partialsDir, file), 'utf-8')
|
|
47
|
-
Handlebars.registerPartial(name, `${content}\n`)
|
|
48
|
-
}
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
const promptCtx = {
|
|
52
|
-
mockPrompt: require(`../prompts/mock.js`),
|
|
53
|
-
sysPrompt: require(`../prompts/system.js`),
|
|
54
|
-
apiPrompt: require(`../prompts/${template}/watch-api.js`),
|
|
55
|
-
pagePrompt: require(`../prompts/${template}/watch-page.js`),
|
|
56
|
-
partPrompt: require(`../prompts/${template}/watch-part.js`),
|
|
57
|
-
linkerPrompt: require(`../prompts/${template}/api-linker.js`),
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const hbsTplCtx = {
|
|
61
|
-
indexTpl: Handlebars.compile(fs.readFileSync(path.join(tplDir, 'index.hbs'), 'utf-8')),
|
|
62
|
-
resourceTpl: Handlebars.compile(fs.readFileSync(path.join(tplDir, 'resource.hbs'), 'utf-8')),
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const pkgEnv = path.resolve(__dirname, '../.env')
|
|
66
|
-
const localEnv = path.resolve(process.cwd(), '.env')
|
|
67
|
-
require('dotenv').config({ path: fs.existsSync(localEnv) ? localEnv : pkgEnv })
|
|
68
|
-
const openAI = new OpenAI({ apiKey: process.env.API_KEY, baseURL: process.env.BASE_URL })
|
|
69
|
-
|
|
70
|
-
const cliCtx = { options }
|
|
71
|
-
const handlerCtx = { apiHandler, pageHandler, partHandler }
|
|
72
|
-
const finalInfrastructureCtx = { menus, config, ...infrastructureCtx }
|
|
73
|
-
const llmCtx = require('../services/llm')({ config, openAI, template, ...promptCtx })
|
|
74
|
-
const compileCtx = require(compilerPath)({ config, contextStringify, ...coreCtx, ...hbsTplCtx })
|
|
75
|
-
|
|
76
|
-
instance = {
|
|
77
|
-
openAI,
|
|
78
|
-
...uxCtx,
|
|
79
|
-
...cliCtx,
|
|
80
|
-
...llmCtx,
|
|
81
|
-
...coreCtx,
|
|
82
|
-
...promptCtx,
|
|
83
|
-
...hbsTplCtx,
|
|
84
|
-
...handlerCtx,
|
|
85
|
-
...compileCtx,
|
|
86
|
-
contextStringify,
|
|
87
|
-
...finalInfrastructureCtx,
|
|
88
|
-
}
|
|
89
|
-
return instance
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
get: () => instance
|
|
93
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/{templates/react/handlebars → src/framework/react/handlebars/partials}/AlertInfo.hbs
RENAMED
|
File without changes
|
/package/{templates/react/handlebars → src/framework/react/handlebars/partials}/FunctionButtons.hbs
RENAMED
|
File without changes
|
/package/{templates/react/handlebars → src/framework/react/handlebars/partials}/MySearchForm.hbs
RENAMED
|
File without changes
|
|
File without changes
|
/package/{templates/react/handlebars → src/framework/react/handlebars/partials}/handleBlock.hbs
RENAMED
|
File without changes
|
/package/{templates/react/handlebars → src/framework/react/handlebars/partials}/hookBlock.hbs
RENAMED
|
File without changes
|
/package/{templates/react/handlebars → src/framework/react/handlebars/partials}/operateBlock.hbs
RENAMED
|
File without changes
|
/package/{templates/react/handlebars → src/framework/react/handlebars/partials}/renderBlock.hbs
RENAMED
|
File without changes
|
/package/{templates/react/handlebars → src/framework/react/handlebars/partials}/stateBlock.hbs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|