@yorha2b-lab/autodev 5.0.0 → 5.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.
package/bin/autodev.js CHANGED
@@ -4,73 +4,59 @@ 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 { language, matrixEffect, bootSequence } = require('../src/utils/ux')
7
+ const { local, matrixEffect, bootSequence } = require('../src/utils/ux')
8
+
9
+ const dialogs = require('../src/bootstrap/registry')({ dir: path.join(__dirname, '../src/dialogs') })
10
+ const dialog = dialogs[local]
8
11
 
9
12
  program
10
13
  .version(pkg.version)
11
- .description(language('AI驱动的前端CRUD代码生成器', 'AI-powered frontend CRUD code generator'))
14
+ .description(dialog.bunker.desc)
12
15
 
13
- program.option('-t, --template <type>', language('指定前端框架模板', 'Specify frontend framework template'), 'react')
16
+ program.option('-t, --template <type>', dialog.bunker.argDesc, 'react')
14
17
 
15
18
  program
16
19
  .command('init')
17
- .description(language('在当前目录初始化地堡构筑环境', 'Initialize Bunker construction environment'))
20
+ .description(dialog.bunker.initDesc)
18
21
  .action(() => {
19
- const tplConfig = path.resolve(__dirname, '../config.js')
20
- const tplEnv = path.resolve(__dirname, '../.env.example')
21
- const targetEnv = path.join(process.cwd(), '.env')
22
- const targetConfig = path.join(process.cwd(), 'config.js')
23
-
24
- fs.mkdirSync(path.join(process.cwd(), 'response'), { recursive: true })
25
- fs.mkdirSync(path.join(process.cwd(), 'screenShot'), { recursive: true })
26
- fs.mkdirSync(path.join(process.cwd(), 'screenPart'), { recursive: true })
27
-
28
- if (fs.existsSync(targetEnv)) {
29
- console.log(chalk.yellow(language('🤖 Pod 042: [警告] 终端已存在 .env 文件,跳过生成。', '🤖 Pod 042: [Warning] .env already exists.')))
30
- } else {
31
- fs.copyFileSync(tplEnv, targetEnv)
32
- console.log(chalk.green(language('🤖 Pod 042: [报告] .env 存储完毕。', '🤖 Pod 042: [Report] .env storage complete.')))
22
+ const battlefield = {
23
+ dirs: ['response', 'screenShot', 'screenPart'],
24
+ files: [
25
+ { from: '.env.example', to: '.env', exist: 'envCheck', success: 'envCopy' },
26
+ { from: 'config.js', to: 'config.js', exist: 'configCheck', success: 'configCopy' }
27
+ ]
33
28
  }
34
-
35
- if (fs.existsSync(targetConfig)) {
36
- console.log(chalk.yellow(language('🤖 Pod 042: [警告] 终端已存在 config.js 文件,跳过生成。', '🤖 Pod 042: [Warning] config.js already exists.')))
37
- } else {
38
- fs.copyFileSync(tplConfig, targetConfig)
39
- console.log(chalk.green(language('🤖 Pod 042: [报告] config.js 存储完毕。', '🤖 Pod 042: [Report] config.js storage complete.')))
29
+ const installer = {
30
+ dirs: dir => fs.mkdirSync(path.join(process.cwd(), dir), { recursive: true }),
31
+ files: ({ from, to, exist, success }) => {
32
+ const target = path.join(process.cwd(), to)
33
+ if (fs.existsSync(target)) {
34
+ return console.log(chalk.yellow(dialog.bunker[exist]))
35
+ }
36
+ fs.copyFileSync(path.resolve(__dirname, `../${from}`), target)
37
+ console.log(chalk.green(dialog.bunker[success]))
38
+ }
40
39
  }
41
-
40
+ Object.entries(battlefield).forEach(([type, items]) => items.forEach(installer[type]))
42
41
  const bunkerCmd = chalk.yellow(`'bunker': 'autodev watch'`)
43
- console.log(chalk.cyan(language(
44
- `📡 Operator 6O: 呼叫 2B, 地堡部署完毕, 为了更快捷地进入战场,建议手动执行 [物理装配]: 将 ${bunkerCmd} 加入您的 package.json scripts 中`,
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.`
46
- )))
42
+ console.log(chalk.cyan(dialog.bunker.initComplete(bunkerCmd)))
47
43
  })
48
44
 
49
45
  program
50
46
  .command('watch')
51
47
  .alias('start')
52
- .description(language('开启全频道联动监控:支持 Page/Part/API 协同构筑', 'Start full-channel linked monitoring: Coordinated Page/Part/API construction'))
53
- .action(() => {
48
+ .description(dialog.bunker.watchDesc)
49
+ .action(async () => {
54
50
  const bunker = require('../src/bootstrap')
55
- const result = bunker.init(program.opts())
51
+ const result = bunker.init(program.opts(), dialog)
56
52
  if (!result) {
57
53
  return
58
54
  }
59
- bootSequence(pkg.version)
55
+ await bootSequence(pkg.version)
60
56
  require('../src/commands/watch')()
61
- const { config } = result.infrastructure
62
- const { apiDoc, needMock, proxyTarget, enableAutoAlignment } = config
63
- if (apiDoc && enableAutoAlignment) {
64
- require('../src/labs/linker')()
65
- }
66
- if (proxyTarget && !needMock && enableAutoAlignment) {
67
- require('../src/labs/tower')()
68
- }
69
57
  process.on('SIGINT', () => {
70
- console.log('\n')
71
- console.log(chalk.gray('--------------------------------------------------'))
72
- console.log(chalk.white(' [System] ') + chalk.yellow(language('正在断开神经云链接,执行数据物理封存...', 'Disconnecting Neural Link, Executing Physical Assembly...')))
73
- matrixEffect(500)
58
+ result.yorha.commander.report(dialog.bunker.systemOffline, 'gray')
59
+ matrixEffect(500, dialog)
74
60
  })
75
61
  })
76
62
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yorha2b-lab/autodev",
3
- "version": "5.0.0",
3
+ "version": "5.2.0",
4
4
  "description": "基于视觉大模型的前端(react+Antd)全自动 CRUD 代码生成器",
5
5
  "bin": {
6
6
  "autodev": "bin/autodev.js"
@@ -0,0 +1,15 @@
1
+ module.exports = ({ config, yorha, dialog, template, foundation }) => {
2
+
3
+ const { copyTemplateDir } = foundation
4
+ const { hbsDir, hooksDir, utilsDir, componentsDir } = config
5
+
6
+ try {
7
+ if (hbsDir === '') {
8
+ copyTemplateDir(template, 'hooks', hooksDir)
9
+ copyTemplateDir(template, 'utils', utilsDir)
10
+ copyTemplateDir(template, 'components', componentsDir)
11
+ }
12
+ } catch (error) {
13
+ yorha.commander.report(dialog.bunker.copyTemplateError(error), 'red')
14
+ }
15
+ }
@@ -1,49 +1,54 @@
1
1
  const fs = require('fs')
2
2
  const path = require('path')
3
- const chalk = require('chalk')
4
3
 
5
4
  let instance = null
6
5
 
7
6
  module.exports = {
8
7
 
9
- init: options => {
8
+ init: ({ template }, dialog) => {
10
9
 
11
- const template = options.template
12
- const ux = require('../utils/ux')
10
+ const yorha = require('./yorha')()
13
11
 
14
12
  const generatorPath = path.join(__dirname, `../framework/${template}/generator`)
15
13
  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.`)))
14
+ yorha.commander.report(dialog.bunker.frameworkNotSupported(template), 'red')
17
15
  return
18
16
  }
19
17
 
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 },
18
+ const foundation = require('../utils/foundation')
19
+ const config = foundation.getConfig()
20
+
21
+ const accessPoint = {
22
+ yorha,
23
+ config,
24
+ dialog,
25
+ template,
26
+ foundation,
27
+ openAI: require('./openai')(),
28
+ core: require('../utils/core'),
29
+ menus: foundation.getExistingMenus(),
30
+ handlebars: require('./handlebar')({ config, template, ...foundation }),
31
+ handlers: require('./registry')({ dir: path.join(__dirname, '../handlers') }),
32
+ prompts: require('./registry')({ dir: path.join(__dirname, `../framework/${template}/prompts`) }),
44
33
  }
34
+
35
+ require('./foundation')(accessPoint)
36
+ const llm = require('../services/llm')(accessPoint)
37
+ const generator = require(generatorPath)(accessPoint)
38
+ const labs = require('./labs')({ llm, ...accessPoint })
39
+
40
+
41
+ instance = { llm, labs, generator, ...accessPoint }
45
42
  return instance
46
43
  },
47
44
 
48
- get: () => instance
45
+ get: () => instance,
46
+
47
+ reboot() {
48
+ const { template, dialog } = instance
49
+ delete require.cache[require.resolve(path.join(process.cwd(), 'config.js'))]
50
+ instance.labs?.shutdown?.()
51
+ instance = null
52
+ return this.init({ template }, dialog)
53
+ }
49
54
  }
@@ -0,0 +1,21 @@
1
+ let tower
2
+
3
+ module.exports = accessPoint => {
4
+
5
+ const { apiDoc, needMock, proxyTarget, enableAutoAlignment } = accessPoint.config
6
+
7
+ if (!needMock && proxyTarget && enableAutoAlignment) {
8
+ tower = require('../labs/tower')(accessPoint)
9
+ }
10
+
11
+ if (apiDoc && enableAutoAlignment) {
12
+ require('../labs/linker')(accessPoint)
13
+ }
14
+
15
+ return {
16
+ shutdown() {
17
+ tower?.close()
18
+ }
19
+
20
+ }
21
+ }
@@ -0,0 +1,14 @@
1
+ module.exports = ({ dir }) => {
2
+
3
+ const fs = require('fs')
4
+ const path = require('path')
5
+
6
+ return Object.fromEntries(
7
+ fs.readdirSync(dir)
8
+ .filter(file => file.endsWith('.js'))
9
+ .map(file => [
10
+ path.basename(file, '.js'),
11
+ require(path.join(dir, file))
12
+ ])
13
+ )
14
+ }
@@ -0,0 +1,36 @@
1
+ module.exports = () => {
2
+
3
+ const ora = require('ora')
4
+ const chalk = require('chalk')
5
+
6
+ const createMember = ({ name }) => ({
7
+ start(text) {
8
+ const spinner = ora({ text: chalk.cyan(`\n${name} ${text}`) }).start()
9
+ return spinner
10
+ },
11
+ fail(spinner, text) {
12
+ spinner.fail(chalk.red(`\n${name} ${text}`))
13
+ },
14
+ report(text, color = 'yellow') {
15
+ console.log(chalk[color](`\n${name} ${text}`))
16
+ },
17
+ update(spinner, text) {
18
+ spinner.text = chalk.cyan(`\n${name} ${text}`)
19
+ },
20
+ warning(spinner, text) {
21
+ spinner.warn(chalk.yellow(`\n${name} ${text}`))
22
+ },
23
+ success(spinner, text) {
24
+ spinner.succeed(chalk.green(`\n${name} ${text}`))
25
+ },
26
+ })
27
+
28
+ return {
29
+ nineS: createMember({ name: '[YoRHa::9S]' }),
30
+ commander: createMember({ name: '[BUNKER]' }),
31
+ pod042: createMember({ name: '[YoRHa::Pod042]' }),
32
+ pod153: createMember({ name: '[YoRHa::Pod153]' }),
33
+ operator6O: createMember({ name: '[YoRHa::6O]' }),
34
+ }
35
+
36
+ }
@@ -2,55 +2,51 @@ module.exports = () => {
2
2
 
3
3
  const fs = require('fs')
4
4
  const path = require('path')
5
- const chalk = require('chalk')
6
5
  const chokidar = require('chokidar')
7
6
 
8
- const { ux, core, handlers, infrastructure } = require('../bootstrap').get()
7
+ const bootstrap = require('../bootstrap')
8
+ const { core, menus, yorha, config, dialog, handlers, foundation } = bootstrap.get()
9
9
 
10
- const { language } = ux
11
10
  const { createTaskQueue } = core
12
- const { apiHandler, pageHandler, partHandler } = handlers
13
- const { menus, config, contextStringify } = infrastructure
11
+ const { contextStringify } = foundation
12
+ const { pod042, commander, operator6O } = yorha
14
13
 
15
14
  const queue = createTaskQueue(2)
16
15
 
17
16
  queue.onIdle(() => {
18
- console.log(chalk.green(language(
19
- '\n🤖 Pod 042: [报告] 队列已空,正在向 Bunker 同步 Menu 路由配置...',
20
- '\n🤖 Pod 042: [Report] Queue empty. Syncing Menu configuration to Bunker...'
21
- )))
17
+ pod042.report(dialog.pod042.queueEmpty)
22
18
  const utilsDir = path.join(process.cwd(), config.utilsDir)
23
19
  if (!fs.existsSync(utilsDir)) fs.mkdirSync(utilsDir, { recursive: true })
24
20
  fs.writeFileSync(path.join(utilsDir, 'menus.js'), `export const menus = ${contextStringify({ context: menus, maxLength: 50 })}`)
25
- console.log(chalk.gray(language(
26
- '\n🤖 [System] 未检测到运行中的任务,系统待机中...\n',
27
- '\n🤖 [System] System is STANDBY.\n'
28
- )))
21
+ commander.report(dialog.bunker.systemStandby, 'gray')
29
22
  })
30
23
 
31
- const watcher = chokidar.watch(['./screenShot', './screenPart', './response'], {
24
+ const options = {
32
25
  persistent: true,
33
26
  ignoreInitial: true,
34
27
  ignored: /(^|[\/\\])\../,
35
28
  awaitWriteFinish: { stabilityThreshold: 500, pollInterval: 100 }
36
- })
29
+ }
30
+
31
+ const fileWatcher = chokidar.watch(['./config.js'], options)
32
+ const dirWatcher = chokidar.watch(['./screenShot', './screenPart', './response'], options)
37
33
 
38
- console.log(chalk.magenta(language(
39
- '📡 Operator 6O: 呼叫 2B,地堡全频道联动监控已就绪!',
40
- '📡 Operator 6O: Calling 2B, all-channel linked monitoring is ready!'
41
- )))
34
+ operator6O.report(dialog.operator6O.call2B)
42
35
 
43
- const routes = [
44
- { match: 'response', handler: apiHandler },
45
- { match: 'screenShot', handler: pageHandler },
46
- { match: 'screenPart', handler: partHandler },
47
- ]
36
+ const routes = Object.values(handlers)
48
37
 
49
- watcher.on('add', filePath => {
38
+ dirWatcher.on('add', filePath => {
50
39
  const absolutePath = path.resolve(filePath)
51
- const route = routes.find(r => absolutePath.includes(r.match))
40
+ const route = routes.find(route => absolutePath.includes(route.watch))
52
41
  if (route) {
53
- queue.add(() => route.handler(filePath))
42
+ queue.add(() => route.handle(filePath))
43
+ }
44
+ })
45
+
46
+ fileWatcher.on('change', file => {
47
+ if (file.endsWith('config.js')) {
48
+ bootstrap.reboot()
54
49
  }
55
50
  })
51
+
56
52
  }
@@ -0,0 +1,62 @@
1
+ module.exports = {
2
+ nineS: {
3
+ dataCamouflageComplete: 'Mock data generation successful',
4
+ scanningField: 'Scanning field differences... Bridging semantic gaps',
5
+ dataCamouflage: fileName => `Piercing target firewall... Executing data camouflage [${fileName}]`,
6
+ },
7
+ pod042: {
8
+ queueEmpty: 'Queue empty. Syncing Menu configuration to Bunker...',
9
+ extractingUiMetadata: 'Extracting UI metadata from neural cloud network...',
10
+ simulate: 'Real-fire request intercepted. Dropping simulation package: example.json',
11
+ uploadVisualMetadata: 'Uploading visual metadata to Command for semantic analysis...',
12
+ partialConstruction: time => `Report: Partial construction achieved. Elapsed: ${time}s`,
13
+ constructionAborted: virus => `Construction aborted. Logic virus or timeout detected: ${virus}`,
14
+ visualPartCaptured: `Partial visual sample detected. Executing 'Fragment Construction Protocol'...`,
15
+ intercept: fileName => `Module [${fileName}] already exists. Construction skipped to prevent overwrite.`,
16
+ partialRecommendation: '│ Recommendation: Please manually assemble the above code block into your target file',
17
+ partialConstructionAborted: virus => `[Warning] Fragment construction failed. Logic interference detected: ${virus}`,
18
+ assemblyComplete: (fileName, time) => `Protocol complete. Physical assembly of [${fileName}] achieved. Elapsed: ${time}s`,
19
+ visualCaptured: fileName => `Visual sensor captured: [${fileName}]. Allocating Bunker resources for physical construction...`,
20
+ },
21
+ pod153: {
22
+ signalLinkFault: virus => `Signal Link Fault: ${virus}`,
23
+ signalSynchronized: count => `Signal Synchronized: ${count} nodes energized`,
24
+ formatError: 'Data format is not standard JSON, will try to align by character',
25
+ alignmentFailed: virus => `Alignment failed. Encountered powerful API firewall: ${virus}`,
26
+ autonomousAddressing: `Initiating 'Full-Channel Autonomous Addressing Protocol [Semantic Scan]'...`,
27
+ inactiveModule: fileName => `Inactive module: [${fileName}]. Requesting 9S for precise alignment...`,
28
+ reconEncryptedData: fileName => `Encrypted data source [${fileName}] detected. Initiating semantic alignment...`,
29
+ capturedRuntimeSignal: fileName => `Captured runtime signal [${fileName}]. Executing semantic alignment protocol...`,
30
+ unknownModule: fileName => `Module [${fileName}] resource not found in Bunker database. Please execute visual construction first`,
31
+ bridgeProtocolComplete: (count, time) => `Semantic bridge protocol complete. Corrected ${count} field deviations. Elapsed: ${time}s`,
32
+ },
33
+ bunker: {
34
+ exit: 'Signal Lost',
35
+ envCopy: '.env storage complete',
36
+ envCheck: '.env already exists',
37
+ systemStandby: 'System is STANDBY',
38
+ configCheck: 'config.js already exists',
39
+ configCopy: 'config.js storage complete',
40
+ argDesc: 'Specify frontend framework template',
41
+ desc: 'AI-powered frontend CRUD code generator',
42
+ dataSynced: 'All data synced to Bunker storage nodes',
43
+ initDesc: 'Initialize Bunker construction environment',
44
+ star: 'If it saves you time, feel free to give it a ⭐ on GitHub',
45
+ copyTemplateError: virus => `Template construction failed: ${virus}`,
46
+ towerOnline: port => `Signal Intercept Tower Online [Band: ${port}]`,
47
+ linkSevered: 'Link Severed: Check network status or Black Box resonance',
48
+ systemOffline: 'Disconnecting Neural Link, Executing Physical Assembly...',
49
+ accessDenied: 'YoRHa Command Center Access Denied: Invalid API Key or quota exhausted!',
50
+ watchDesc: 'Start full-channel linked monitoring: Coordinated Page/Part/API construction',
51
+ towerConnected: port => `Command: Please point your local proxy target to http://localhost:${port}`,
52
+ disclaimer: 'Match Result Reference Only. Not Final Decision. Each Unit should adjust based on battlefield conditions',
53
+ frameworkNotSupported: template => `[${template}] framework not supported. Welcome to contribute a Pull Request to help`,
54
+ networkInstability: count => `Neural Network instability detected. Attempting to re-establish link... (Retry #${count})`,
55
+ strategicThreshold: (target, current) => `Physical clone count has exceeded ${target} strategic threshold! Current power: ${current}`,
56
+ initComplete: cmd => `Bunker deployment is complete. To expedite your entry into the battlefield, I recommend a manual [Physical Assembly]: Add ${cmd} to your package.json scripts.`,
57
+ isLegendary: (unlockAchievement, current, target) => unlockAchievement ? 'Congratulations, your construction protocol is now part of humanity' : `Current clones: ${current}. ${target - current} to Achievement`,
58
+ },
59
+ operator6O: {
60
+ call2B: 'Calling 2B, all-channel linked monitoring is ready!'
61
+ }
62
+ }
@@ -0,0 +1,62 @@
1
+ module.exports = {
2
+ nineS: {
3
+ dataCamouflageComplete: 'Mock 数据生成成功',
4
+ scanningField: '正在扫描前后端字段差异... 执行语义桥接任务',
5
+ dataCamouflage: fileName => `正在突破目标防火墙... 执行数据伪装程序 [${fileName}]`,
6
+ },
7
+ pod042: {
8
+ extractingUiMetadata: '正在从神经云网络提取 UI 元数据...',
9
+ simulate: '拦截到实弹请求。正在空投标准模拟包: example.json',
10
+ queueEmpty: '队列已空,正在向 Bunker 同步 Menu 路由配置...',
11
+ uploadVisualMetadata: '正在上传视觉元数据至司令部进行语义分析...',
12
+ visualPartCaptured: `侦测到局部视觉样本。正在执行“碎片构筑协议”...`,
13
+ partialConstruction: time => `报告:局部构筑达成。耗时: ${time}s`,
14
+ partialRecommendation: '│ 建议:请手动将上述代码块物理装配至您的目标文件中',
15
+ constructionAborted: virus => `构筑中断。检测到逻辑病毒或连接超时:${virus}`,
16
+ partialConstructionAborted: virus => `[警告] 碎片构筑失败。系统检测到逻辑干扰:${virus}`,
17
+ visualCaptured: fileName => `视觉传感器捕捉完成: [${fileName}]。正在调配地堡资源进行物理构筑...`,
18
+ intercept: fileName => `模块 [${fileName}] 已存在于地堡数据库中。为了防止数据覆盖,构筑协议已跳过`,
19
+ assemblyComplete: (fileName, time) => `构筑协议执行完毕。模块 [${fileName}] 物理装配达成。耗时: ${time}s`,
20
+ },
21
+ pod153: {
22
+ signalLinkFault: virus => `信号链路故障: ${virus}`,
23
+ formatError: '数据格式非标准 JSON,将尝试原始字符对齐',
24
+ autonomousAddressing: `启动‘全频道自动寻址协议 [语义扫描版]’...`,
25
+ signalSynchronized: count => `信号同步完成,${count} 个节点已通电`,
26
+ alignmentFailed: virus => `信号对齐失败。接口数据遭遇强力防火墙:${virus}`,
27
+ inactiveModule: fileName => `发现未通电模块 [${fileName}],请求 9S 执行高精度对账...`,
28
+ capturedRuntimeSignal: fileName => `截获运行时信号 [${fileName}]。执行自动对齐协议...`,
29
+ reconEncryptedData: fileName => `发现加密数据源 [${fileName}]。正在尝试执行语义对齐协议...`,
30
+ unknownModule: fileName => `地堡数据库中未检索到模块 [${fileName}] 的资源文件。请先执行视觉构筑`,
31
+ bridgeProtocolComplete: (count, time) => `语义桥接协议执行完毕。已物理修正 ${count} 处字段偏差。耗时: ${time}s`,
32
+ },
33
+ bunker: {
34
+ exit: '系统信号已丢失',
35
+ envCopy: '.env 存储完毕',
36
+ argDesc: '指定前端框架模板',
37
+ systemStandby: '系统待机中...',
38
+ desc: 'AI驱动的前端CRUD代码生成器',
39
+ configCopy: 'config.js 存储完毕',
40
+ initDesc: '在当前目录初始化地堡构筑环境',
41
+ envCheck: '终端已存在 .env 文件,跳过生成',
42
+ dataSynced: '所有构筑数据已同步至 Bunker 存储节点',
43
+ configCheck: '终端已存在 config.js 文件,跳过生成',
44
+ linkSevered: '连接中断:请检查网络状态或黑盒共鸣情况',
45
+ systemOffline: '正在断开神经云链接,执行数据物理封存...',
46
+ copyTemplateError: virus => `模板构筑失败: ${virus}`,
47
+ star: '如果它能帮您节省时间,请在 GitHub 上给它点个赞 ⭐',
48
+ towerOnline: port => `信号拦截塔已在线 [波段: ${port}]`,
49
+ watchDesc: '开启全频道联动监控:支持 Page/Part/API 协同构筑',
50
+ accessDenied: '司令部拒绝访问:API Key 无效或额度耗尽,请检查!',
51
+ disclaimer: '匹配结果仅供参考,不构成最终决策,各机体需根据实际情况进行调整',
52
+ towerConnected: port => `指令:请将您的代理目标指向 http://localhost:${port}`,
53
+ networkInstability: count => `神经云网络连接不稳,正在尝试重新链接... (第 ${count} 次重试)`,
54
+ frameworkNotSupported: template => `暂不支持 [${template}] 框架。欢迎提交 Pull Request 贡献`,
55
+ strategicThreshold: (target, current) => `物理克隆总数已超越 ${target} 战略阈值!当前战力:${current}`,
56
+ initComplete: cmd => `地堡部署完毕, 为了更快捷地进入战场,建议手动执行 [物理装配]: 将 ${cmd} 加入您的 package.json scripts 中`,
57
+ isLegendary: (unlockAchievement, current, target) => unlockAchievement ? '恭喜您指挥官,您的构筑协议已成为人类荣光的一部分' : `当前构筑总数:${current}。距离 ${target} 勋章还剩 ${target - current} 次`,
58
+ },
59
+ operator6O: {
60
+ call2B: '呼叫 2B,地堡全频道联动监控已就绪!',
61
+ }
62
+ }
@@ -1,6 +1,9 @@
1
- module.exports = ({ config, indexTpl, cleanCode, resourceTpl, contextStringify, generateSmartImports, formatFormItemAndColumns, }) => {
1
+ module.exports = ({ core, config, handlebars, foundation }) => {
2
2
 
3
+ const { contextStringify } = foundation
4
+ const { indexTpl, resourceTpl } = handlebars
3
5
  const { needMock, responseSuccess } = config
6
+ const { cleanCode, generateSmartImports, formatFormItemAndColumns } = core
4
7
 
5
8
  return {
6
9
  index: ({ fileName, pageConfig }) => {
@@ -1,42 +1,37 @@
1
- module.exports = `
1
+ module.exports = fileName => `
2
2
  # Task: Full-Page UI Analysis & Structural Assembly
3
3
  执行全页面视觉特征提取,并按照物理布局顺序输出标准的构筑协议。
4
4
 
5
- ## 1. 核心命名协议 (Naming Convention)
5
+ **模块名: ${fileName}**
6
+
7
+ ## 核心命名协议 (Naming Convention)
6
8
  - **驼峰命名**: 所有变量及函数名必须遵循 camelCase。
7
- - **⚠️ 严禁中文**: 绝对禁止在变量名、键名中使用中文字符。
8
- - **物理屏蔽关键字**: 禁止使用 JS 保留字 (export, delete, const, let, class, default 等)。
9
+ - **严禁中文**: 绝对禁止在变量名、键名中使用中文字符。
10
+ - **屏蔽关键字**: 禁止使用 JS 保留字 (export, delete, const, let, class, default 等)。
9
11
 
10
- ## 2. 零部件构筑规范 (Component Specifications)
12
+ ## 零部件构筑规范 (Component Specifications)
11
13
 
12
- ### 标签页 (Tabs)
14
+ ## 标签页 (tabs)
13
15
  - **基础格式**: [{ label: '文本', key: 'englishName' }]
14
- - **识别条件**: 仅当下部有显著长横线 (Ink Bar) 或呈现包裹感 (Card style) 时判定。
16
+ - **识别条件**: 底部有显著长横线 (Ink Bar) 或呈现包裹感 (Card style) 时判定。
15
17
  - **排除项**: 表格上方的独立按钮必须归类为 [functionButton]。
16
18
 
17
- ### 搜索项 (FormItems)
18
- - **基础格式**: [{ label: '文本', name: 'englishName',type:'' }]
19
- - ⚠️ 属性精简规则:
20
- - 默认输入框: 仅保留 [label, name] 属性。**严禁出现 type 属性**。
19
+ ## 搜索项 (formItems)
20
+ - **基础格式**: [{ label: '文本', name: 'englishName' }]
21
+ - **属性精简规则**:
22
+ - 默认输入框: 仅保留 [label, name] 属性。**严禁出现[type]**。
21
23
  - 非默认组件: 仅当类型为 [auto, date, radio, select, upload, checkbox, textarea, daterange] 时才允许添加 type 属性。
22
- **标准定义 (FormItem)**:
23
- - date: 单日期
24
- - enum: 枚举类型
25
- - daterange: 日期范围
26
- - text: 普通文本(默认)
27
- - 命名规范:
24
+ - **命名规范**:
28
25
  - daterange: name 必须设为 '字段英文名Start,字段英文名End'
29
- - **⚠️注意⚠️**:不要用_分隔字段名。
30
26
 
31
- ### 统计条 (StaticInfo)
32
- - **独立存在**: 位于表格外周的汇总信息。输出格式: { has: true, text: '具体内容' }。
27
+ ## 统计条 (StaticInfo)
28
+ - **独立存在**: 位于表格外周的汇总信息。输出格式: { has: boolean, text: '具体内容' }。
33
29
 
34
- ### 表格主体 (Table)
35
- - ⚠️ **操作锁定**: 严禁在 columns 数组中包含“操作”列。
36
- - **标准项**: {title:'列名', dataIndex:'列名英文名词',type:''}。
37
- - **注意**: type为text时必须省略type属性。
38
- - **配置项**: [pagination, expandable, rowSelection] 均为布尔值false,只有页面明确有对应功能时才为true。
39
- - **标准定义 (Columns)**:
30
+ ## 表格主体 (table)
31
+ - **基础格式(columns)**: [{ title: '文本', dataIndex: 'englishName' }]。
32
+ - **配置项**: [pagination, expandable, rowSelection] 均为布尔值。
33
+ - **行操作 (operation)**: [{ label: '操作名', action: '动词Record', uri: 'BUNKER_API_ANCHOR_动词[模块名]'}]
34
+ - **类型定义 (type)**:
40
35
  - enum: 枚举列
41
36
  - money: 金额列
42
37
  - index: 序号列
@@ -45,23 +40,19 @@ module.exports = `
45
40
  - text: 普通文本(默认)
46
41
  - tag: 标签列(有背景色的文本)
47
42
  - badge: 徽标列(文本前有颜色小圆点)
48
- - **行操作 (operation)**: [{label:'操作名', action:'动词ByRecord',uri:'BUNKER_API_ANCHOR_动词ByRecord'}]。
49
43
 
50
- ### 全局功能按钮 (FunctionButton)
51
- - **格式**: [{btn:'显示文本', action:'操作动词BySelected',uri:'BUNKER_API_ANCHOR_动词BySelected'}]。
52
- - **导出数据**: action 设为 'exportData' 或 'export+模块名'。
53
- - **逻辑锁定**: ⚠️只要页面中出现了非查询、非重置的独立操作按钮,必须识别并存入 [functionButton] 数组。
54
- - **构筑联动**: ⚠️若 [functionButton] 数组不为空,则在下文的 [RenderTree] 中必须包含 "FunctionButtons"。
44
+ ## 全局功能按钮 (functionButton)
45
+ - **基础格式**: [{ btn: '按钮', action: '操作动词[模块名]BySelected', uri: 'BUNKER_API_ANCHOR_动词[模块名]BySelected'}]。
46
+ - **导出数据**: action 设为 'export[模块名]'。
47
+ - **逻辑锁定**: 只要页面中出现了非查询、非重置的独立操作按钮,必须识别并存入 [functionButton] 数组。
48
+ - **构筑联动**: 若 [functionButton] 数组不为空,则在下文的 [RenderTree] 中必须包含 "FunctionButtons"。
55
49
 
56
- ## 3. 布局逻辑编排 (RenderTree)
50
+ ## 布局逻辑编排 (RenderTree)
57
51
  - **定义**: 定义从上至下的物理堆叠顺序。
58
52
  - **白名单**: [MyTable, AlertInfo, MySearchForm, FunctionButtons]
59
- - **注释**: MyTable 是表格主体,AlertInfo 是统计条,MySearchForm 是搜索表单,FunctionButtons 是全局功能按钮。
60
53
 
61
-
62
- ## 4. 字典数组 (OptionList)
63
- - **格式**:[{name:'字段英文名+Options',options:[{label:'', value:''}]}]。
54
+ ## 字典数组 (OptionList)
55
+ - **格式**:[{ name: '字段英文名Options', options:[{ label, value}]}]。
64
56
  - **注释**:label:选项文本,value:文本英文。
65
57
  - **数据源**:根据对应列的内容去重,生成选项数组。
66
-
67
58
  `.trim();