@yorha2b-lab/autodev 7.4.6 → 7.5.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yorha2b-lab/autodev",
3
- "version": "7.4.6",
3
+ "version": "7.5.1",
4
4
  "description": "基于 AI 视觉与语义协议的前端 (React+Antd) 代码构筑与旧系统重构引擎",
5
5
  "bin": {
6
6
  "bunker": "bin/bunker.js"
@@ -28,53 +28,71 @@ module.exports = async ({ llm, yorha, dialog, logistics }) => {
28
28
  const enumParamsMap = {}
29
29
 
30
30
  for (const fileName of files) {
31
- const indexPath = path.join(pages, fileName, 'index.js')
32
- const resourcePath = path.join(pages, fileName, 'resource.js')
33
-
34
- if (fs.existsSync(indexPath) && fs.existsSync(resourcePath)) {
35
- let indexCode = fs.readFileSync(indexPath, 'utf-8')
36
-
37
- if (indexCode.includes('BUNKER_API_ANCHOR')) {
38
- const resourceCode = fs.readFileSync(resourcePath, 'utf-8')
39
- const bunkerAnchors = indexCode.match(/BUNKER_API_ANCHOR_\w+/g)?.join('\n') ?? ''
40
-
41
- const returnMatch = indexCode.match(/return\s*\(([\s\S]*?)\)\s*}/)
42
- const returnStatement = returnMatch ? returnMatch[0] : ''
43
-
44
- const moduleSemantics = `${returnStatement}${resourceCode}`.match(/[\u4e00-\u9fa5][\u4e00-\u9fa5A-Za-z0-9?。,、:;!() ]*/g) || []
45
- const pageKeywords = getSemanticKeywords(moduleSemantics)
46
- const candidates = refinedApis
47
- .map(api => ({
48
- ...api,
49
- score: getLocalScore(api, pageKeywords, fileName)
50
- }))
51
- .filter(item => item.score > 0)
52
- .sort((a, b) => b.score - a.score)
53
- .slice(0, 20)
54
-
55
- const finalCandidates = candidates.map(item => `${item.method} ${item.path} ${item.desc}`).join('\n')
56
- const spinner = pod153.start(dialog.pod153.inactiveModule(fileName), 'yellow')
57
- const result = await apiParser({ bunkerAnchors, realApis: finalCandidates })
58
-
59
- if (result) {
60
- let hasQsImport = indexCode.includes(`import qs from 'qs'`)
31
+ const pageDir = path.join(pages, fileName)
32
+ if (!fs.existsSync(pageDir) || !fs.statSync(pageDir).isDirectory()) continue
33
+
34
+ const subFiles = fs.readdirSync(pageDir).filter(f => f.endsWith('.js') || f.endsWith('.jsx'))
35
+ const fileContents = {}
36
+ const allSemantics = []
37
+ const allAnchors = new Set()
38
+
39
+ for (const file of subFiles) {
40
+ const filePath = path.join(pageDir, file)
41
+ const code = fs.readFileSync(filePath, 'utf-8')
42
+ fileContents[filePath] = code
43
+
44
+ const anchors = code.match(/BUNKER_API_ANCHOR_\w+/g) || []
45
+ anchors.forEach(a => allAnchors.add(a))
46
+
47
+ const chinese = code.match(/[\u4e00-\u9fa5][\u4e00-\u9fa5A-Za-z0-9?。,、:;!() ]*/g) || []
48
+ allSemantics.push(...chinese)
49
+ }
50
+
51
+ if (allAnchors.size > 0) {
52
+ const bunkerAnchors = Array.from(allAnchors).join('\n')
53
+ const pageKeywords = getSemanticKeywords(allSemantics)
54
+
55
+ const candidates = refinedApis.map(api => ({ ...api, score: getLocalScore(api, pageKeywords, fileName) }))
56
+ .filter(item => item.score > 0)
57
+ .sort((a, b) => b.score - a.score)
58
+ .slice(0, 20)
59
+
60
+ const finalCandidates = candidates.map(item => `${item.method} ${item.path} ${item.desc}`).join('\n')
61
+ const spinner = pod153.start(dialog.pod153.inactiveModule(fileName), 'yellow')
62
+ const result = await apiParser({ bunkerAnchors, realApis: finalCandidates })
63
+
64
+ if (result) {
65
+ for (const [filePath, rawCode] of Object.entries(fileContents)) {
66
+ let code = rawCode
67
+ let isModified = false
68
+ let hasQsImport = code.includes(`import qs from 'qs'`)
69
+
61
70
  Object.entries(result).forEach(([anchor, { uri, method }]) => {
62
- const cleanPath = uri.startsWith('/') ? uri : `/${uri}`
63
- let finalUri = cleanPath.startsWith('/api') ? cleanPath : `/api${cleanPath}`
64
- finalUri = finalUri.replace(/\{(\w+)\}/g, (_, key) => '${params.' + key + '}')
65
- const quotationMark = finalUri.includes('${params.') ? '\`' : "'"
66
- if (method?.toUpperCase() === 'GET') {
67
- indexCode = indexCode.replaceAll(anchor, `request(\`${finalUri}?\${qs.stringify(params)}\`)`)
68
- if (!hasQsImport) {
69
- indexCode = `import qs from 'qs'\n${indexCode}`
70
- hasQsImport = true
71
+ if (code.includes(anchor)) {
72
+ isModified = true
73
+ const cleanPath = uri.startsWith('/') ? uri : `/${uri}`
74
+ let finalUri = cleanPath.startsWith('/api') ? cleanPath : `/api${cleanPath}`
75
+ finalUri = finalUri.replace(/\{(\w+)\}/g, (_, key) => '${params.' + key + '}')
76
+ const quotationMark = finalUri.includes('${params.') ? '`' : "'"
77
+ if (method?.toUpperCase() === 'GET') {
78
+ code = code.replaceAll(anchor, `request(\`${finalUri}?\${qs.stringify(params)}\`)`)
79
+ if (!hasQsImport) {
80
+ code = `import qs from 'qs'\n${code}`
81
+ hasQsImport = true
82
+ }
83
+ } else {
84
+ code = code.replaceAll(anchor, `request(${quotationMark}${finalUri}${quotationMark}, { method: '${method?.toUpperCase()}', body: params })`)
71
85
  }
72
- } else {
73
- indexCode = indexCode.replaceAll(anchor, `request(${quotationMark}${finalUri}${quotationMark}, { method: '${method?.toUpperCase()}', body: params })`)
74
86
  }
75
87
  })
88
+ if (isModified) {
89
+ fs.writeFileSync(filePath, code)
90
+ }
91
+ }
76
92
 
77
- const { uri: pagesApi, method: pagesMethod } = result?.['BUNKER_API_ANCHOR_pages']
93
+ const pagesConfig = result?.['BUNKER_API_ANCHOR_pages']
94
+ if (pagesConfig) {
95
+ const { uri: pagesApi, method: pagesMethod } = pagesConfig
78
96
  const definitions = (apiData.paths[pagesApi]?.[pagesMethod] ?? apiData.paths[pagesApi]?.[pagesMethod?.toLowerCase()])?.parameters?.flatMap(item => Object.values(item.schema ?? {})?.flatMap(def => def?.split('/')?.at(-1))) || []
79
97
  const parameters = apiData.definitions?.[definitions[0]]?.properties ?? {}
80
98
  const enumParams = Object.entries(parameters)?.filter(([_, value]) => value.hasOwnProperty('enum')) || []
@@ -82,16 +100,12 @@ module.exports = async ({ llm, yorha, dialog, logistics }) => {
82
100
  maxLength: 100,
83
101
  context: Object.fromEntries(enumParams.map(([key, value]) => [`${key}Options`, value.enum?.map(opt => ({ label: opt, value: opt }))])),
84
102
  })
85
-
86
- fs.writeFileSync(indexPath, indexCode)
87
- pod153.success(spinner, dialog.pod153.signalSynchronized(Object.keys(result).length))
88
- // 💡 战术免责补丁:采用橙黄色高亮,提醒指挥官保持警惕
89
- commander.report(dialog.bunker.disclaimer, 'yellow')
90
103
  }
104
+ pod153.success(spinner, dialog.pod153.signalSynchronized(Object.keys(result).length))
105
+ commander.report(dialog.bunker.disclaimer, 'yellow')
91
106
  }
92
107
  }
93
108
  }
94
-
95
109
  return enumParamsMap
96
110
  } catch (e) {
97
111
  pod153.report(dialog.pod153.signalLinkFault(e.message), 'red')
@@ -61,7 +61,7 @@ const bootSequence = async (version, local) => {
61
61
 
62
62
  for (const line of lines) {
63
63
  console.log(line)
64
- await sleep(line.includes('AutoDev') ? 300 : 80)
64
+ await sleep(line.includes('Bunker') ? 300 : 80)
65
65
  }
66
66
  }
67
67