@yorha2b-lab/autodev 6.1.1 → 7.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/README.md +18 -10
- package/README_EN.md +18 -10
- package/bin/bunker.js +20 -3
- package/example/example.json +25 -12
- package/package.json +1 -1
- package/src/awakening/index.js +1 -1
- package/src/dialogues/DE-DE.js +1 -2
- package/src/dialogues/EN-US.js +1 -2
- package/src/dialogues/ES-ES.js +1 -2
- package/src/dialogues/FR-FR.js +1 -2
- package/src/dialogues/ID-ID.js +1 -2
- package/src/dialogues/IT-IT.js +1 -2
- package/src/dialogues/JA-JP.js +1 -2
- package/src/dialogues/KO-KR.js +1 -2
- package/src/dialogues/PT-BR.js +1 -2
- package/src/dialogues/RU-RU.js +1 -2
- package/src/dialogues/TR-TR.js +1 -2
- package/src/dialogues/ZH-CN.js +1 -2
- package/src/dialogues/ZH-TW.js +1 -2
- package/src/gateway/index.js +1 -1
- package/src/headquarters/commander.js +20 -0
- package/src/headquarters/observer.js +9 -18
- package/src/headquarters/quartermaster.js +7 -7
- package/src/labs/scout.js +2 -2
- package/src/labs/tower.js +6 -18
- package/src/logistics/supporter.js +0 -22
- package/src/units/raider.js +13 -7
- package/src/units/reconciler.js +10 -17
- package/src/units/striker.js +13 -7
- package/src/workshop/react/briefings/raider.js +1 -1
- package/src/workshop/react/briefings/striker.js +1 -1
- package/src/workshop/react/briefings/visionType.js +59 -0
- package/src/headquarters/engineer.js +0 -19
package/README.md
CHANGED
|
@@ -14,20 +14,28 @@
|
|
|
14
14
|
|
|
15
15
|

|
|
16
16
|
|
|
17
|
-
## 🌟
|
|
17
|
+
## 🌟 v7.0 地堡架构升级
|
|
18
18
|
|
|
19
|
-
在
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
在 v7.0 时代,AutoDev 进一步升级为 **Mission-Driven 的模块化地堡架构**。
|
|
20
|
+
|
|
21
|
+
所有任务统一进入 `Mission`,由 **Headquarters** 中的 **Commander** 识别任务需求、匹配最合适的 Unit,并交由 Dispatcher 调度执行。
|
|
22
|
+
|
|
23
|
+
Unit 不再绑定固定输入目录,而是通过声明自身的 `capabilities` 主动参与任务匹配,让地堡可以根据任务动态组织作战单位。
|
|
24
|
+
|
|
25
|
+
- 🧠 **任务指挥 (Commander)**:识别任务类型与所需能力,从全部 Units 中选择最合适的执行单位。
|
|
26
|
+
- ⚔️ **作战单位 (Units)**:通过能力声明参与任务匹配,负责具体的页面构筑、语义对齐等任务。
|
|
27
|
+
- 🕵️ **数字考古 (Scout)**:Puppeteer 无头侦察兵,从旧系统捕获页面并生成重构任务。
|
|
28
|
+
- 🗼 **现网防御塔 (Tower)**:代理真实 XHR/Fetch 流量,将现网数据直接送入地堡任务链。
|
|
29
|
+
- 🏛️ **议会 (Council)**:解析 OpenAPI / Swagger 文档,提炼枚举与接口语义,为构筑任务提供协议情报。
|
|
23
30
|
|
|
24
31
|
## ✨ 特性
|
|
25
32
|
|
|
26
|
-
- 🖼️ **全页构筑 (Page)
|
|
27
|
-
- 🧩 **碎片提取 (Part)
|
|
28
|
-
- 🕵️
|
|
29
|
-
-
|
|
30
|
-
-
|
|
33
|
+
- 🖼️ **全页构筑 (Page)**:输入完整页面截图,Commander 自动识别构筑需求并调度对应 Unit,生成包含 Table / Form / Tabs 的完整 CRUD 页面及菜单。
|
|
34
|
+
- 🧩 **碎片提取 (Part)**:输入局部 UI 截图,自动识别为组件构筑任务,生成可直接使用的 UI 配置代码。
|
|
35
|
+
- 🕵️ **数字考古 (Scout)**:通过 Puppeteer 巡检旧系统,浏览器中右键即可捕获当前页面,并将其转换为重构任务。
|
|
36
|
+
- 🗼 **现网数据采集 (Tower)**:代理真实 XHR / Fetch 请求,将运行中的后端响应直接送入任务链,无需手工准备 JSON。
|
|
37
|
+
- 🔌 **语义对齐 (Reconciler)**:分析后端响应与前端资源定义之间的字段差异,自动修正 `resource.js`。
|
|
38
|
+
- 🔧 **智能装配**:自动补全 import、日期格式转换、金额千分位、枚举字典、OSS 上传等实战逻辑。
|
|
31
39
|
|
|
32
40
|
## 🚀 快速开始
|
|
33
41
|
|
package/README_EN.md
CHANGED
|
@@ -14,20 +14,28 @@ AI Vision and Semantic Protocol-based Frontend (React + Ant Design) Code Constru
|
|
|
14
14
|
|
|
15
15
|

|
|
16
16
|
|
|
17
|
-
## 🌟
|
|
17
|
+
## 🌟 v7.0 Bunker Architecture Upgrade
|
|
18
18
|
|
|
19
|
-
In
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
In v7.0, AutoDev evolves into a **Mission-Driven modular bunker architecture**.
|
|
20
|
+
|
|
21
|
+
All tasks are unified as `Mission` objects and routed through **Headquarters**. The **Commander** analyzes mission requirements, identifies the capabilities needed, selects the most suitable Unit, and dispatches it for execution.
|
|
22
|
+
|
|
23
|
+
Units are no longer bound to fixed input directories. Instead, each Unit declares its own `capabilities` and participates dynamically in mission matching, allowing the Bunker to assemble the right team for each task.
|
|
24
|
+
|
|
25
|
+
- 🧠 **Mission Command (Commander)**: Analyzes mission requirements and selects the most suitable Unit from all available capabilities.
|
|
26
|
+
- ⚔️ **Combat Units (Units)**: Declare their capabilities and participate in mission matching, handling tasks such as page reconstruction and semantic alignment.
|
|
27
|
+
- 🕵️ **Digital Archaeology (Scout)**: A Puppeteer-based reconnaissance unit that captures pages from legacy systems and turns them into reconstruction missions.
|
|
28
|
+
- 🗼 **Live Network Defense (Tower)**: Proxies real XHR / Fetch traffic and feeds live backend responses directly into the Bunker mission pipeline.
|
|
29
|
+
- 🏛️ **Council**: Parses OpenAPI / Swagger documentation, extracting enums and API semantics to provide protocol intelligence for construction missions.
|
|
23
30
|
|
|
24
31
|
## ✨ Features
|
|
25
32
|
|
|
26
|
-
- 🖼️ **Full
|
|
27
|
-
- 🧩 **Fragment Extraction (Part)**:
|
|
28
|
-
- 🕵️ **
|
|
29
|
-
-
|
|
30
|
-
-
|
|
33
|
+
- 🖼️ **Full Page Reconstruction (Page)**: Feed a complete page screenshot into the Bunker. The Commander identifies the required capabilities and dispatches the appropriate Unit to generate a complete CRUD page with Table / Form / Tabs and synchronized menus.
|
|
34
|
+
- 🧩 **UI Fragment Extraction (Part)**: Feed a partial UI screenshot and let the Bunker identify it as a component reconstruction mission, generating ready-to-use UI configuration code.
|
|
35
|
+
- 🕵️ **Digital Archaeology (Scout)**: Use Puppeteer to inspect legacy systems. Right-click anywhere in the browser to capture the current page and turn it into a reconstruction mission.
|
|
36
|
+
- 🗼 **Live Data Acquisition (Tower)**: Proxy real XHR / Fetch requests and feed live backend responses directly into the mission pipeline, eliminating the need to prepare response JSON manually.
|
|
37
|
+
- 🔌 **Semantic Alignment (Reconciler)**: Analyze differences between backend responses and frontend resource definitions, then automatically reconcile fields in `resource.js`.
|
|
38
|
+
- 🔧 **Smart Assembly**: Automatically handle imports, date formatting, number formatting, enum dictionaries, OSS uploads, and other practical frontend engineering tasks.
|
|
31
39
|
|
|
32
40
|
## 🚀 Quick Start
|
|
33
41
|
|
package/bin/bunker.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs')
|
|
2
3
|
const path = require('path')
|
|
3
4
|
const chalk = require('chalk')
|
|
4
5
|
const pkg = require('../package.json')
|
|
@@ -20,13 +21,28 @@ program
|
|
|
20
21
|
.command('init')
|
|
21
22
|
.description(dialog.bunker.initDesc)
|
|
22
23
|
.action(() => {
|
|
24
|
+
|
|
25
|
+
const equipments = []
|
|
26
|
+
const root = process.cwd()
|
|
27
|
+
const { template } = program.opts()
|
|
28
|
+
const workshop = path.join(__dirname, `../src/workshop/${template}`)
|
|
29
|
+
const quartermaster = require('../src/headquarters/quartermaster')({ dialog })
|
|
30
|
+
const { hbsDir, hooksDir, utilsDir, componentsDir } = require('../src/logistics/supporter').getConfig()
|
|
31
|
+
|
|
32
|
+
if (!hbsDir) {
|
|
33
|
+
equipments.push(...fs.readdirSync(`${workshop}/kit`).map(file => ({ from: `${workshop}/kit/${file}`, to: `${path.join(root, utilsDir, file)}` })))
|
|
34
|
+
equipments.push(...fs.readdirSync(`${workshop}/extensions`).map(file => ({ from: `${workshop}/extensions/${file}`, to: `${path.join(root, hooksDir, file)}` })))
|
|
35
|
+
equipments.push(...fs.readdirSync(`${workshop}/standardParts`).map(file => ({ from: `${workshop}/standardParts/${file}`, to: `${path.join(root, componentsDir, file)}` })))
|
|
36
|
+
}
|
|
37
|
+
|
|
23
38
|
const outpost = {
|
|
39
|
+
dirs: [`${path.join(root, 'bunker', 'mission')}`],
|
|
24
40
|
files: [
|
|
25
|
-
|
|
26
|
-
{ from:
|
|
41
|
+
...equipments,
|
|
42
|
+
{ from: path.join(__dirname, `../.env.example`), to: `${path.join(root, 'bunker', '.env')}`, exist: 'envCheck', success: 'envCopy' },
|
|
43
|
+
{ from: path.join(__dirname, `../config.js`), to: `${path.join(root, 'bunker', 'config.js')}`, exist: 'configCheck', success: 'configCopy' }
|
|
27
44
|
]
|
|
28
45
|
}
|
|
29
|
-
const quartermaster = require('../src/headquarters/quartermaster')({ root: process.cwd(), dialog })
|
|
30
46
|
Object.entries(outpost).forEach(([type, items]) => items.forEach(quartermaster[type]))
|
|
31
47
|
const bunkerCmd = chalk.yellow(`'bunker': 'bunker boot'`)
|
|
32
48
|
console.log(chalk.cyan(dialog.bunker.initComplete(bunkerCmd)))
|
|
@@ -43,6 +59,7 @@ program
|
|
|
43
59
|
return
|
|
44
60
|
}
|
|
45
61
|
require('../src/headquarters/observer')(bunker)
|
|
62
|
+
result.yorha.operator6O.report(result.dialog.operator6O.call2B)
|
|
46
63
|
process.on('SIGINT', () => {
|
|
47
64
|
result.yorha.commander.report(dialog.bunker.systemOffline, 'gray')
|
|
48
65
|
result.labs?.scout?.close()
|
package/example/example.json
CHANGED
|
@@ -21,11 +21,13 @@
|
|
|
21
21
|
"columns": [
|
|
22
22
|
{
|
|
23
23
|
"title": "职业",
|
|
24
|
-
"dataIndex": "profession"
|
|
24
|
+
"dataIndex": "profession",
|
|
25
|
+
"type": "text"
|
|
25
26
|
},
|
|
26
27
|
{
|
|
27
28
|
"title": "一觉",
|
|
28
|
-
"dataIndex": "firstAwakening"
|
|
29
|
+
"dataIndex": "firstAwakening",
|
|
30
|
+
"type": "text"
|
|
29
31
|
},
|
|
30
32
|
{
|
|
31
33
|
"title": "一觉立绘",
|
|
@@ -34,7 +36,8 @@
|
|
|
34
36
|
},
|
|
35
37
|
{
|
|
36
38
|
"title": "二觉",
|
|
37
|
-
"dataIndex": "secondAwakening"
|
|
39
|
+
"dataIndex": "secondAwakening",
|
|
40
|
+
"type": "text"
|
|
38
41
|
},
|
|
39
42
|
{
|
|
40
43
|
"title": "二觉立绘",
|
|
@@ -43,7 +46,8 @@
|
|
|
43
46
|
},
|
|
44
47
|
{
|
|
45
48
|
"title": "三觉",
|
|
46
|
-
"dataIndex": "thirdAwakening"
|
|
49
|
+
"dataIndex": "thirdAwakening",
|
|
50
|
+
"type": "text"
|
|
47
51
|
},
|
|
48
52
|
{
|
|
49
53
|
"title": "三觉立绘",
|
|
@@ -64,29 +68,38 @@
|
|
|
64
68
|
"title": "登场时间",
|
|
65
69
|
"dataIndex": "releaseDate",
|
|
66
70
|
"type": "date"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"title": "操作",
|
|
74
|
+
"dataIndex": "operation",
|
|
75
|
+
"type": "text"
|
|
67
76
|
}
|
|
68
77
|
],
|
|
69
78
|
"operation": [
|
|
70
79
|
{
|
|
71
80
|
"uri": "BUNKER_API_ANCHOR_view",
|
|
72
81
|
"label": "查看",
|
|
73
|
-
"action": "
|
|
82
|
+
"action": "view"
|
|
74
83
|
},
|
|
75
84
|
{
|
|
76
85
|
"uri": "BUNKER_API_ANCHOR_edit",
|
|
77
86
|
"label": "编辑",
|
|
78
|
-
"action": "
|
|
87
|
+
"action": "edit"
|
|
79
88
|
},
|
|
80
89
|
{
|
|
81
90
|
"uri": "BUNKER_API_ANCHOR_delete",
|
|
82
91
|
"label": "删除",
|
|
83
|
-
"action": "
|
|
92
|
+
"action": "delete"
|
|
84
93
|
}
|
|
85
94
|
],
|
|
86
95
|
"pagination": true,
|
|
87
96
|
"expandable": true,
|
|
88
97
|
"rowSelection": true
|
|
89
98
|
},
|
|
99
|
+
"title": {
|
|
100
|
+
"chinese": "职业觉醒管理",
|
|
101
|
+
"english": "professionAwakeningManagement"
|
|
102
|
+
},
|
|
90
103
|
"formItems": [
|
|
91
104
|
{
|
|
92
105
|
"label": "转职职业",
|
|
@@ -127,7 +140,7 @@
|
|
|
127
140
|
},
|
|
128
141
|
{
|
|
129
142
|
"label": "太刀",
|
|
130
|
-
"value": "
|
|
143
|
+
"value": "longSword"
|
|
131
144
|
},
|
|
132
145
|
{
|
|
133
146
|
"label": "巨剑",
|
|
@@ -157,13 +170,13 @@
|
|
|
157
170
|
"functionButton": [
|
|
158
171
|
{
|
|
159
172
|
"btn": "批量删除",
|
|
160
|
-
"uri": "
|
|
161
|
-
"action": "
|
|
173
|
+
"uri": "BUNKER_API_ANCHOR_deleteProfessions",
|
|
174
|
+
"action": "deleteProfessions"
|
|
162
175
|
},
|
|
163
176
|
{
|
|
164
177
|
"btn": "批量导出",
|
|
165
|
-
"uri": "
|
|
166
|
-
"action": "
|
|
178
|
+
"uri": "BUNKER_API_ANCHOR_exportProfessions",
|
|
179
|
+
"action": "exportProfessions"
|
|
167
180
|
}
|
|
168
181
|
]
|
|
169
182
|
}
|
package/package.json
CHANGED
package/src/awakening/index.js
CHANGED
|
@@ -30,7 +30,7 @@ module.exports = {
|
|
|
30
30
|
if (version) {
|
|
31
31
|
await logistics.presenter.bootSequence(version, local)
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
const llm = require('../gateway')(accessPoint)
|
|
35
35
|
const builder = require(builderPath)(accessPoint)
|
|
36
36
|
const labs = require('../labs')({ llm, ...accessPoint })
|
package/src/dialogues/DE-DE.js
CHANGED
|
@@ -11,7 +11,7 @@ module.exports = {
|
|
|
11
11
|
extractingUiMetadata: 'UI-Metadaten werden aus dem neuronalen Cloud-Netzwerk extrahiert...',
|
|
12
12
|
simulate: 'Echte Anfrage erkannt. Standard-Simulationspaket example.json wird bereitgestellt',
|
|
13
13
|
partialRecommendation: '│ Empfehlung: Den obigen Codeblock manuell in die Zieldatei integrieren',
|
|
14
|
-
capturedPage: pageName => `Seite erfasst [${pageName}] -> In das Verzeichnis
|
|
14
|
+
capturedPage: pageName => `Seite erfasst [${pageName}] -> In das Verzeichnis mission übertragen`,
|
|
15
15
|
visualPartCaptured: 'Lokales visuelles Fragment erkannt. „Fragment-Konstruktionsprotokoll“ wird gestartet',
|
|
16
16
|
uploadVisualMetadata: 'Visuelle Metadaten werden an die Zentrale übertragen. Semantische Analyse wird gestartet...',
|
|
17
17
|
partialConstructionAborted: virus => `[Warnung] Fragment-Konstruktion fehlgeschlagen. Logische Störung erkannt: ${virus}`,
|
|
@@ -24,7 +24,6 @@ module.exports = {
|
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `Signalverbindungsfehler: ${virus}`,
|
|
26
26
|
signalSynchronized: count => `${count} Knoten synchronisiert. Energieversorgung bestätigt`,
|
|
27
|
-
formatError: 'Nicht standardisiertes JSON-Format erkannt. Synchronisation mit Rohdaten wird versucht',
|
|
28
27
|
autonomousAddressing: '„Vollkanal-Autoadressierungsprotokoll [Semantische Analyseversion]“ wird aktiviert...',
|
|
29
28
|
inactiveModule: fileName => `Nicht aktiviertes Modul [${fileName}] erkannt. Hochpräzise Analyse durch 9S angefordert`,
|
|
30
29
|
alignmentFailed: virus => `Signalsynchronisierung fehlgeschlagen. API-Daten durch starke Firewall blockiert: ${virus}`,
|
package/src/dialogues/EN-US.js
CHANGED
|
@@ -11,7 +11,7 @@ module.exports = {
|
|
|
11
11
|
simulate: 'Real-fire request intercepted. Dropping simulation package: example.json',
|
|
12
12
|
uploadVisualMetadata: 'Uploading visual metadata to Command for semantic analysis...',
|
|
13
13
|
partialConstruction: time => `Report: Partial construction achieved. Elapsed: ${time}s`,
|
|
14
|
-
capturedPage: pageName => `Page captured [${pageName}] -> Transmitted to
|
|
14
|
+
capturedPage: pageName => `Page captured [${pageName}] -> Transmitted to mission directory`,
|
|
15
15
|
constructionAborted: virus => `Construction aborted. Logic virus or timeout detected: ${virus}`,
|
|
16
16
|
visualPartCaptured: `Partial visual sample detected. Executing 'Fragment Construction Protocol'...`,
|
|
17
17
|
scoutReady: '[Right-Click Snapshot Ready] Right-click anywhere on the webpage to capture instantly.',
|
|
@@ -24,7 +24,6 @@ module.exports = {
|
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `Signal Link Fault: ${virus}`,
|
|
26
26
|
signalSynchronized: count => `Signal Synchronized: ${count} nodes energized`,
|
|
27
|
-
formatError: 'Data format is not standard JSON, will try to align by character',
|
|
28
27
|
alignmentFailed: virus => `Alignment failed. Encountered powerful API firewall: ${virus}`,
|
|
29
28
|
autonomousAddressing: `Initiating 'Full-Channel Autonomous Addressing Protocol [Semantic Scan]'...`,
|
|
30
29
|
inactiveModule: fileName => `Inactive module: [${fileName}]. Requesting 9S for precise alignment...`,
|
package/src/dialogues/ES-ES.js
CHANGED
|
@@ -10,7 +10,7 @@ module.exports = {
|
|
|
10
10
|
extractingUiMetadata: 'Extrayendo metadatos de UI desde la red neuronal en la nube...',
|
|
11
11
|
partialConstruction: time => `Informe: construcción parcial completada. Tiempo: ${time}s`,
|
|
12
12
|
simulate: 'Solicitud real interceptada. Desplegando paquete simulado estándar: example.json',
|
|
13
|
-
capturedPage: pageName => `Página capturada [${pageName}] -> Transmitida al directorio
|
|
13
|
+
capturedPage: pageName => `Página capturada [${pageName}] -> Transmitida al directorio mission`,
|
|
14
14
|
uploadVisualMetadata: 'Subiendo metadatos visuales al centro de comando para análisis semántico...',
|
|
15
15
|
visualPartCaptured: 'Fragmento visual detectado. Ejecutando protocolo de construcción fragmentada...',
|
|
16
16
|
constructionAborted: virus => `Construcción abortada. Virus lógico o tiempo de conexión agotado: ${virus}`,
|
|
@@ -24,7 +24,6 @@ module.exports = {
|
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `Fallo en enlace de señal: ${virus}`,
|
|
26
26
|
signalSynchronized: count => `Sincronización completada. ${count} nodos activados`,
|
|
27
|
-
formatError: 'Formato JSON no estándar detectado. Intentando alineación de datos originales',
|
|
28
27
|
alignmentFailed: virus => `Fallo de alineación. Los datos de interfaz encontraron un firewall: ${virus}`,
|
|
29
28
|
autonomousAddressing: 'Iniciando protocolo de direccionamiento autónomo multicanal [versión semántica]...',
|
|
30
29
|
inactiveModule: fileName => `Módulo sin energía detectado [${fileName}]. Solicitando análisis de precisión a 9S`,
|
package/src/dialogues/FR-FR.js
CHANGED
|
@@ -10,7 +10,7 @@ module.exports = {
|
|
|
10
10
|
extractingUiMetadata: 'Extraction des métadonnées UI depuis le réseau neuronal cloud...',
|
|
11
11
|
partialConstruction: time => `Rapport : Construction partielle terminée. Durée : ${time}s`,
|
|
12
12
|
simulate: 'Requête réelle détectée. Déploiement du paquet de simulation standard : example.json',
|
|
13
|
-
capturedPage: pageName => `Page capturée [${pageName}] -> Transférée vers le répertoire
|
|
13
|
+
capturedPage: pageName => `Page capturée [${pageName}] -> Transférée vers le répertoire mission`,
|
|
14
14
|
scoutReady: '[Capture par Clic Droit Prête] Effectuez un clic droit n’importe où sur la page web pour capturer.',
|
|
15
15
|
visualPartCaptured: 'Fragment visuel local détecté. Activation du « protocole de construction fragmentaire »...',
|
|
16
16
|
uploadVisualMetadata: 'Transmission des métadonnées visuelles au quartier général. Analyse sémantique en cours...',
|
|
@@ -24,7 +24,6 @@ module.exports = {
|
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `Erreur de liaison du signal : ${virus}`,
|
|
26
26
|
signalSynchronized: count => `${count} nœuds synchronisés. Alimentation confirmée`,
|
|
27
|
-
formatError: 'Format JSON non standard détecté. Tentative de synchronisation avec les données brutes',
|
|
28
27
|
inactiveModule: fileName => `Module non activé détecté [${fileName}]. Analyse haute précision demandée à 9S`,
|
|
29
28
|
autonomousAddressing: 'Activation du « protocole d’adressage automatique multi-canaux [version analyse sémantique] »...',
|
|
30
29
|
alignmentFailed: virus => `Échec de synchronisation du signal. Les données API sont bloquées par un pare-feu puissant : ${virus}`,
|
package/src/dialogues/ID-ID.js
CHANGED
|
@@ -13,7 +13,7 @@ module.exports = {
|
|
|
13
13
|
visualPartCaptured: 'Sampel visual terdeteksi. Menjalankan protokol konstruksi fragmen...',
|
|
14
14
|
uploadVisualMetadata: 'Mengirim metadata visual ke pusat komando untuk analisis semantik...',
|
|
15
15
|
partialRecommendation: '│ Rekomendasi: Pasang blok kode di atas secara manual ke file target',
|
|
16
|
-
capturedPage: pageName => `Halaman ditangkap [${pageName}] -> Ditransmisikan ke direktori
|
|
16
|
+
capturedPage: pageName => `Halaman ditangkap [${pageName}] -> Ditransmisikan ke direktori mission`,
|
|
17
17
|
scoutReady: '[Mode Jepretan Klik-Kanan Siap] Klik kanan di mana saja pada halaman web untuk mengambil gambar.',
|
|
18
18
|
constructionAborted: virus => `Konstruksi dihentikan. Virus logika atau batas waktu koneksi terdeteksi: ${virus}`,
|
|
19
19
|
partialConstructionAborted: virus => `[Peringatan] Konstruksi fragmen gagal. Gangguan logika terdeteksi: ${virus}`,
|
|
@@ -23,7 +23,6 @@ module.exports = {
|
|
|
23
23
|
},
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `Gangguan koneksi sinyal: ${virus}`,
|
|
26
|
-
formatError: 'Format JSON tidak standar. Mencoba penyelarasan data mentah',
|
|
27
26
|
signalSynchronized: count => `Sinkronisasi sinyal selesai. ${count} node telah diaktifkan`,
|
|
28
27
|
alignmentFailed: virus => `Penyelarasan sinyal gagal. Data API menghadapi firewall: ${virus}`,
|
|
29
28
|
autonomousAddressing: 'Memulai protokol pengalamatan otomatis multi-kanal [versi semantik]...',
|
package/src/dialogues/IT-IT.js
CHANGED
|
@@ -12,7 +12,7 @@ module.exports = {
|
|
|
12
12
|
uploadVisualMetadata: 'Invio metadati visivi al comando centrale per analisi semantica...',
|
|
13
13
|
simulate: 'Richiesta reale intercettata. Lancio pacchetto simulato standard: example.json',
|
|
14
14
|
visualPartCaptured: 'Frammento visivo rilevato. Avvio protocollo di costruzione frammentata...',
|
|
15
|
-
capturedPage: pageName => `Pagina catturata [${pageName}] -> Trasferita nella directory
|
|
15
|
+
capturedPage: pageName => `Pagina catturata [${pageName}] -> Trasferita nella directory mission`,
|
|
16
16
|
partialRecommendation: '│ Raccomandazione: integra manualmente il blocco di codice sopra nel file destinazione',
|
|
17
17
|
constructionAborted: virus => `Costruzione interrotta. Rilevato virus logico o timeout di connessione: ${virus}`,
|
|
18
18
|
partialConstructionAborted: virus => `[Avviso] Fallimento costruzione frammentata. Interferenza logica rilevata: ${virus}`,
|
|
@@ -23,7 +23,6 @@ module.exports = {
|
|
|
23
23
|
},
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `Errore collegamento segnale: ${virus}`,
|
|
26
|
-
formatError: 'Formato JSON non standard. Tentativo di allineamento dati originali',
|
|
27
26
|
signalSynchronized: count => `Sincronizzazione completata. ${count} nodi attivati`,
|
|
28
27
|
alignmentFailed: virus => `Allineamento fallito. I dati API hanno incontrato un firewall: ${virus}`,
|
|
29
28
|
autonomousAddressing: 'Avvio protocollo di indirizzamento autonomo multicanale [versione semantica]...',
|
package/src/dialogues/JA-JP.js
CHANGED
|
@@ -15,7 +15,7 @@ module.exports = {
|
|
|
15
15
|
partialConstructionAborted: virus => `[警告] 断片構築失敗。論理干渉を検出:${virus}`,
|
|
16
16
|
simulate: '実弾リクエストを検知。標準シミュレーションパッケージ example.json を投下します',
|
|
17
17
|
constructionAborted: virus => `構築中断。論理ウイルスまたは接続タイムアウトを検出:${virus}`,
|
|
18
|
-
capturedPage: pageName => `ページデータを取得【${pageName}】->
|
|
18
|
+
capturedPage: pageName => `ページデータを取得【${pageName}】-> mission ディレクトリへ送信完了`,
|
|
19
19
|
scoutReady: '【スナップショット準備完了】ウェブページ上の任意の位置で【右クリック】すると即座に撮影されます。',
|
|
20
20
|
visualCaptured: fileName => `視覚センサーによる捕捉完了: [${fileName}]。Bunkerリソースを展開し物理構築を開始します`,
|
|
21
21
|
intercept: fileName => `モジュール [${fileName}] は既にBunkerデータベースに存在。データ上書き防止のため構築プロトコルを中断`,
|
|
@@ -23,7 +23,6 @@ module.exports = {
|
|
|
23
23
|
},
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `シグナルリンク障害: ${virus}`,
|
|
26
|
-
formatError: '非標準JSON形式を検出。原始文字列による同期処理を試行します',
|
|
27
26
|
signalSynchronized: count => `${count}個のノード同期完了。電力供給を確認`,
|
|
28
27
|
autonomousAddressing: '「全チャンネル自動アドレス指定プロトコル [セマンティック解析版]」を起動...',
|
|
29
28
|
inactiveModule: fileName => `未通電モジュール [${fileName}] を検出。9Sによる高精度照合を要求します`,
|
package/src/dialogues/KO-KR.js
CHANGED
|
@@ -15,7 +15,7 @@ module.exports = {
|
|
|
15
15
|
partialRecommendation: '│ 권장: 아래 코드 블록을 대상 파일에 수동으로 통합하십시오',
|
|
16
16
|
partialConstructionAborted: virus => `[경고] 파편 구축 실패. 논리 간섭 감지: ${virus}`,
|
|
17
17
|
constructionAborted: virus => `구축 중단. 논리 바이러스 또는 연결 시간 초과 감지: ${virus}`,
|
|
18
|
-
capturedPage: pageName => `페이지 획득 [${pageName}] ->
|
|
18
|
+
capturedPage: pageName => `페이지 획득 [${pageName}] -> mission 디렉터리로 전송 완료`,
|
|
19
19
|
scoutReady: '[우클릭 스냅샷 모드 준비 완료] 브라우저 페이지 임의의 위치에서 [우클릭] 시 즉시 캡처됩니다.',
|
|
20
20
|
visualCaptured: fileName => `시각 센서 캡처 완료: [${fileName}]. Bunker 자원을 배치하여 물리 구축 시작...`,
|
|
21
21
|
intercept: fileName => `모듈 [${fileName}]은(는) 이미 Bunker 데이터베이스에 존재합니다. 덮어쓰기를 방지하기 위해 구축 프로토콜을 건너뜁니다`,
|
|
@@ -23,7 +23,6 @@ module.exports = {
|
|
|
23
23
|
},
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `신호 연결 오류: ${virus}`,
|
|
26
|
-
formatError: '비표준 JSON 형식 감지. 원본 데이터 정렬 시도',
|
|
27
26
|
signalSynchronized: count => `${count}개의 노드 동기화 완료. 전원 활성화 확인`,
|
|
28
27
|
autonomousAddressing: '「전 채널 자동 주소 지정 프로토콜 [시맨틱 스캔 버전]」 실행...',
|
|
29
28
|
inactiveModule: fileName => `비활성 모듈 [${fileName}] 발견. 9S 고정밀 분석 요청`,
|
package/src/dialogues/PT-BR.js
CHANGED
|
@@ -10,10 +10,10 @@ module.exports = {
|
|
|
10
10
|
extractingUiMetadata: 'Extraindo metadados de UI da rede neural em nuvem...',
|
|
11
11
|
partialConstruction: time => `Relatório: construção parcial concluída. Tempo: ${time}s`,
|
|
12
12
|
simulate: 'Requisição real detectada. Implantando pacote de simulação padrão: example.json',
|
|
13
|
+
capturedPage: pageName => `Página capturada [${pageName}] -> Transmitida para o diretório mission`,
|
|
13
14
|
partialRecommendation: '│ Recomendação: integre manualmente o bloco de código acima no arquivo alvo',
|
|
14
15
|
uploadVisualMetadata: 'Enviando metadados visuais ao comando central. Iniciando análise semântica...',
|
|
15
16
|
visualPartCaptured: 'Fragmento visual detectado. Executando "Protocolo de Construção Fragmentada"...',
|
|
16
|
-
capturedPage: pageName => `Página capturada [${pageName}] -> Transmitida para o diretório screenShot`,
|
|
17
17
|
constructionAborted: virus => `Construção interrompida. Vírus lógico ou tempo limite de conexão detectado: ${virus}`,
|
|
18
18
|
scoutReady: '[Modo de Captura com Clique Direito Pronto] Clique com o botão direito em qualquer lugar da página web.',
|
|
19
19
|
partialConstructionAborted: virus => `[Aviso] Falha na construção fragmentada. Interferência lógica detectada: ${virus}`,
|
|
@@ -24,7 +24,6 @@ module.exports = {
|
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `Falha no link de sinal: ${virus}`,
|
|
26
26
|
signalSynchronized: count => `Sincronização concluída. ${count} nós energizados`,
|
|
27
|
-
formatError: 'Formato JSON fora do padrão detectado. Tentando alinhamento dos dados originais',
|
|
28
27
|
alignmentFailed: virus => `Falha no alinhamento do sinal. Dados da API bloqueados pelo firewall: ${virus}`,
|
|
29
28
|
autonomousAddressing: 'Iniciando "Protocolo de Endereçamento Autônomo de Todos os Canais [Versão Semântica]"...',
|
|
30
29
|
inactiveModule: fileName => `Módulo inativo encontrado [${fileName}]. Solicitando análise de alta precisão pelo 9S`,
|
package/src/dialogues/RU-RU.js
CHANGED
|
@@ -8,8 +8,8 @@ module.exports = {
|
|
|
8
8
|
capturedToast: 'Визуальные разведданные захвачены. Начиная передачу...',
|
|
9
9
|
startScout: 'Активация режима [Тактический снимок правой кнопкой мыши]...',
|
|
10
10
|
extractingUiMetadata: 'Извлечение метаданных UI из нейронной облачной сети...',
|
|
11
|
+
capturedPage: pageName => `Страница захвачена [${pageName}] -> Передано в каталог mission`,
|
|
11
12
|
partialConstruction: time => `Доклад: частичная сборка завершена. Время обработки: ${time}s`,
|
|
12
|
-
capturedPage: pageName => `Страница захвачена [${pageName}] -> Передано в каталог screenShot`,
|
|
13
13
|
uploadVisualMetadata: 'Передача визуальных метаданных в штаб. Запуск семантического анализа...',
|
|
14
14
|
partialRecommendation: '│ Рекомендация: вручную интегрируйте указанный блок кода в целевой файл',
|
|
15
15
|
simulate: 'Обнаружен реальный запрос. Развёртывание стандартного симуляционного пакета: example.json',
|
|
@@ -23,7 +23,6 @@ module.exports = {
|
|
|
23
23
|
},
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `Ошибка сигнального соединения: ${virus}`,
|
|
26
|
-
formatError: 'Обнаружен нестандартный формат JSON. Попытка синхронизации исходных данных',
|
|
27
26
|
signalSynchronized: count => `Синхронизация ${count} узлов завершена. Питание подтверждено`,
|
|
28
27
|
inactiveModule: fileName => `Обнаружен неактивный модуль [${fileName}]. Запрошен высокоточный анализ 9S`,
|
|
29
28
|
autonomousAddressing: 'Запуск «протокола автоматической адресации всех каналов [семантическая версия]»...',
|
package/src/dialogues/TR-TR.js
CHANGED
|
@@ -10,8 +10,8 @@ module.exports = {
|
|
|
10
10
|
partialConstruction: time => `Rapor: Kısmi inşa tamamlandı. Süre: ${time}s`,
|
|
11
11
|
extractingUiMetadata: 'Bulut sinir ağından UI meta verileri çıkarılıyor...',
|
|
12
12
|
visualPartCaptured: 'Görsel parça algılandı. Parçalı inşa protokolü başlatılıyor...',
|
|
13
|
+
capturedPage: pageName => `Sayfa yakalandı [${pageName}] -> mission dizinine aktarıldı`,
|
|
13
14
|
simulate: 'Gerçek istek algılandı. Standart simülasyon paketi bırakılıyor: example.json',
|
|
14
|
-
capturedPage: pageName => `Sayfa yakalandı [${pageName}] -> screenShot dizinine aktarıldı`,
|
|
15
15
|
partialRecommendation: '│ Öneri: Yukarıdaki kod bloğunu hedef dosyaya manuel olarak entegre edin',
|
|
16
16
|
uploadVisualMetadata: 'Görsel meta veriler komuta merkezine gönderiliyor. Semantik analiz başlatılıyor...',
|
|
17
17
|
partialConstructionAborted: virus => `[Uyarı] Parçalı inşa başarısız. Mantıksal engel tespit edildi: ${virus}`,
|
|
@@ -23,7 +23,6 @@ module.exports = {
|
|
|
23
23
|
},
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `Sinyal bağlantı hatası: ${virus}`,
|
|
26
|
-
formatError: 'Standart dışı JSON formatı. Ham veri hizalaması deneniyor',
|
|
27
26
|
signalSynchronized: count => `Sinyal senkronizasyonu tamamlandı. ${count} düğüm aktif edildi`,
|
|
28
27
|
autonomousAddressing: 'Çok kanallı otonom adresleme protokolü [semantik sürüm] başlatılıyor...',
|
|
29
28
|
alignmentFailed: virus => `Sinyal hizalama başarısız. API verileri güvenlik duvarına takıldı: ${virus}`,
|
package/src/dialogues/ZH-CN.js
CHANGED
|
@@ -15,7 +15,7 @@ module.exports = {
|
|
|
15
15
|
partialRecommendation: '│ 建议:请手动将上述代码块物理装配至您的目标文件中',
|
|
16
16
|
scoutReady: '【右键快照模式就绪】在浏览器页面任意位置点击【鼠标右键】即可秒截屏',
|
|
17
17
|
constructionAborted: virus => `构筑中断。检测到逻辑病毒或连接超时:${virus}`,
|
|
18
|
-
capturedPage: pageName => `捕获页面【${pageName}】-> 已投递至
|
|
18
|
+
capturedPage: pageName => `捕获页面【${pageName}】-> 已投递至 mission 目录`,
|
|
19
19
|
partialConstructionAborted: virus => `[警告] 碎片构筑失败。系统检测到逻辑干扰:${virus}`,
|
|
20
20
|
visualCaptured: fileName => `视觉传感器捕捉完成: [${fileName}]。正在调配地堡资源进行物理构筑...`,
|
|
21
21
|
intercept: fileName => `模块 [${fileName}] 已存在于地堡数据库中。为了防止数据覆盖,构筑协议已跳过`,
|
|
@@ -23,7 +23,6 @@ module.exports = {
|
|
|
23
23
|
},
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `信号链路故障: ${virus}`,
|
|
26
|
-
formatError: '数据格式非标准 JSON,将尝试原始字符对齐',
|
|
27
26
|
autonomousAddressing: `启动‘全频道自动寻址协议 [语义扫描版]’...`,
|
|
28
27
|
signalSynchronized: count => `信号同步完成,${count} 个节点已通电`,
|
|
29
28
|
alignmentFailed: virus => `信号对齐失败。接口数据遭遇强力防火墙:${virus}`,
|
package/src/dialogues/ZH-TW.js
CHANGED
|
@@ -15,7 +15,7 @@ module.exports = {
|
|
|
15
15
|
uploadVisualMetadata: '正在上傳視覺中繼資料至司令部,執行語意分析...',
|
|
16
16
|
scoutReady: '【右鍵快照模式就緒】在瀏覽器頁面任意位置點擊【滑鼠右鍵】即可秒截屏',
|
|
17
17
|
constructionAborted: virus => `構築中斷。偵測到邏輯病毒或連線逾時:${virus}`,
|
|
18
|
-
capturedPage: pageName => `擷取頁面【${pageName}】-> 已投遞至
|
|
18
|
+
capturedPage: pageName => `擷取頁面【${pageName}】-> 已投遞至 mission 目錄`,
|
|
19
19
|
partialConstructionAborted: virus => `[警告] 碎片構築失敗。系統偵測到邏輯干擾:${virus}`,
|
|
20
20
|
intercept: fileName => `模組 [${fileName}] 已存在於 Bunker 資料庫中。為避免資料覆蓋,構築協議已跳過`,
|
|
21
21
|
visualCaptured: fileName => `視覺感測器捕捉完成: [${fileName}]。正在調配 Bunker 資源進行物理構築...`,
|
|
@@ -23,7 +23,6 @@ module.exports = {
|
|
|
23
23
|
},
|
|
24
24
|
pod153: {
|
|
25
25
|
signalLinkFault: virus => `訊號鏈路故障: ${virus}`,
|
|
26
|
-
formatError: '資料格式非標準 JSON,將嘗試原始字串對齊',
|
|
27
26
|
autonomousAddressing: '啟動「全頻道自動尋址協議 [語意掃描版]」...',
|
|
28
27
|
signalSynchronized: count => `訊號同步完成,${count} 個節點已通電`,
|
|
29
28
|
alignmentFailed: virus => `訊號對齊失敗。API 資料遭遇強力防火牆:${virus}`,
|
package/src/gateway/index.js
CHANGED
|
@@ -38,7 +38,7 @@ module.exports = ({ yorha, dialog, logistics, briefings }) => {
|
|
|
38
38
|
]
|
|
39
39
|
})
|
|
40
40
|
},
|
|
41
|
-
recognizePage: async ({ prompt, filePath
|
|
41
|
+
recognizePage: async ({ schema, prompt, filePath }) => {
|
|
42
42
|
const compressedBuffer = await sharp(filePath)
|
|
43
43
|
.resize(1280, null, { withoutEnlargement: true })
|
|
44
44
|
.jpeg({ quality: 80 })
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module.exports = bunker => {
|
|
2
|
+
|
|
3
|
+
const acp = bunker.get()
|
|
4
|
+
const dispatcher = require('../headquarters/dispatcher')(acp, 2)
|
|
5
|
+
|
|
6
|
+
dispatcher.onIdle(() => acp.yorha.commander.report(acp.dialog.bunker.systemStandby, 'gray'))
|
|
7
|
+
|
|
8
|
+
return {
|
|
9
|
+
receive: async mission => {
|
|
10
|
+
const result = await acp.llm.recognizePage({ filePath: mission.input, prompt: acp.briefings.visionType })
|
|
11
|
+
const unit = Object.values(acp.units).map(unit => ({ unit, score: unit.meta.capabilities.filter(cap => result.capabilities.includes(cap)).length }))
|
|
12
|
+
.filter(item => item.score > 0)
|
|
13
|
+
.sort((a, b) => b.score - a.score)[0]?.unit
|
|
14
|
+
if (!unit) {
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
dispatcher.add(() => unit.execute({ acp, mission }))
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -1,29 +1,21 @@
|
|
|
1
1
|
module.exports = bunker => {
|
|
2
2
|
|
|
3
|
+
const path = require('path')
|
|
3
4
|
const chokidar = require('chokidar')
|
|
5
|
+
const commander = require('../headquarters/commander')(bunker)
|
|
4
6
|
|
|
5
|
-
const
|
|
6
|
-
const units = Object.values(acp.units)
|
|
7
|
-
const dispatcher = require('../headquarters/dispatcher')(acp, 2)
|
|
7
|
+
const settingWatcher = chokidar.watch('./bunker/config.js', { persistent: true, ignoreInitial: true })
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const options = {
|
|
9
|
+
const missionWatcher = chokidar.watch('./bunker/mission/', {
|
|
12
10
|
persistent: true,
|
|
13
11
|
ignoreInitial: true,
|
|
14
12
|
ignored: /(^|[\/\\])\../,
|
|
15
|
-
awaitWriteFinish: { stabilityThreshold: 500, pollInterval: 100 }
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const settingWatcher = chokidar.watch(['./bunker/config.js'], options)
|
|
19
|
-
const fileWatcher = chokidar.watch(units.map(unit => `./bunker/${unit.station}`), options)
|
|
20
|
-
|
|
21
|
-
acp.yorha.operator6O.report(acp.dialog.operator6O.call2B)
|
|
13
|
+
awaitWriteFinish: { stabilityThreshold: 500, pollInterval: 100 },
|
|
14
|
+
})
|
|
22
15
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
dispatcher.add(() => unit.handle(filePath))
|
|
16
|
+
missionWatcher.on('add', filePath => {
|
|
17
|
+
if (['.png', '.jpg', '.jpeg', '.webp'].includes(path.extname(filePath))) {
|
|
18
|
+
commander.receive({ input: filePath, type: 'file-added' })
|
|
27
19
|
}
|
|
28
20
|
})
|
|
29
21
|
|
|
@@ -32,5 +24,4 @@ module.exports = bunker => {
|
|
|
32
24
|
bunker.reboot()
|
|
33
25
|
}
|
|
34
26
|
})
|
|
35
|
-
|
|
36
27
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
2
|
const chalk = require('chalk')
|
|
4
3
|
|
|
5
|
-
module.exports = ({
|
|
6
|
-
dirs: dir => fs.mkdirSync(
|
|
4
|
+
module.exports = ({ dialog }) => ({
|
|
5
|
+
dirs: dir => fs.mkdirSync(dir, { recursive: true }),
|
|
7
6
|
files: ({ from, to, exist, success }) => {
|
|
8
|
-
|
|
9
|
-
if (fs.existsSync(target)) {
|
|
7
|
+
if (fs.existsSync(to) && !!exist) {
|
|
10
8
|
return console.log(chalk.yellow(dialog.bunker[exist]))
|
|
11
9
|
}
|
|
12
|
-
fs.cpSync(
|
|
13
|
-
|
|
10
|
+
fs.cpSync(from, to, { recursive: true })
|
|
11
|
+
if (!!success) {
|
|
12
|
+
console.log(chalk.green(dialog.bunker[success]))
|
|
13
|
+
}
|
|
14
14
|
}
|
|
15
15
|
})
|
package/src/labs/scout.js
CHANGED
|
@@ -35,7 +35,7 @@ module.exports = ({ yorha, dialog }) => {
|
|
|
35
35
|
pod042.report(dialog.pod042.startScout, 'green')
|
|
36
36
|
|
|
37
37
|
const puppeteer = require('puppeteer')
|
|
38
|
-
const
|
|
38
|
+
const missionDir = path.join(process.cwd(), 'bunker', 'mission')
|
|
39
39
|
const sessionDir = path.join(process.cwd(), 'bunker', '.chrome_session')
|
|
40
40
|
|
|
41
41
|
let isBrowserAlive = false
|
|
@@ -73,7 +73,7 @@ module.exports = ({ yorha, dialog }) => {
|
|
|
73
73
|
await page.exposeFunction('nodeTakeScreenshot', async () => {
|
|
74
74
|
const currentUrl = await page.url()
|
|
75
75
|
const pageName = derivePageNameFromUrl(currentUrl)
|
|
76
|
-
const savePath = path.join(
|
|
76
|
+
const savePath = path.join(missionDir, `${pageName}.png`)
|
|
77
77
|
await page.screenshot({ path: savePath, fullPage: true })
|
|
78
78
|
pod042.report(dialog.pod042.capturedPage(pageName), 'green')
|
|
79
79
|
})
|
package/src/labs/tower.js
CHANGED
|
@@ -12,13 +12,11 @@ module.exports = ({ units, yorha, dialog, logistics }) => {
|
|
|
12
12
|
const hackedRegistry = new Map()
|
|
13
13
|
const proxy = httpProxy.createProxyServer({})
|
|
14
14
|
|
|
15
|
-
// 简单的辅助函数:提取 JSON 的所有 Key 作为“指纹”
|
|
16
15
|
const getJsonFingerprint = obj => {
|
|
17
16
|
if (!obj || typeof obj !== 'object') return ''
|
|
18
17
|
return Object.keys(Array.isArray(obj) ? (obj[0] || {}) : obj).sort().join(',')
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
// 💡 物理监控:劫持响应流
|
|
22
20
|
proxy.on('proxyRes', function (proxyRes, req, res) {
|
|
23
21
|
let body = []
|
|
24
22
|
proxyRes.on('data', chunk => body.push(chunk))
|
|
@@ -28,28 +26,20 @@ module.exports = ({ units, yorha, dialog, logistics }) => {
|
|
|
28
26
|
try {
|
|
29
27
|
const rawBody = encoding === 'gzip' ? zlib.gunzipSync(buffer) : buffer
|
|
30
28
|
const json = JSON.parse(rawBody.toString())
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// 💡 这一步就是地堡的“火控系统”
|
|
35
|
-
if (!isQuerySignal(req, json, coreData)) {
|
|
36
|
-
return // 增删改信号,直接丢弃,保持静默
|
|
29
|
+
const coreData = unwrapSignal(json)
|
|
30
|
+
if (!isQuerySignal(req, json, coreData) || coreData?.length === 0) {
|
|
31
|
+
return
|
|
37
32
|
}
|
|
38
|
-
|
|
39
|
-
const referer = req.headers.referer || ''
|
|
33
|
+
const referer = req.headers.referer || '/'
|
|
40
34
|
const urlPath = new URL(referer).pathname
|
|
41
35
|
const fileName = routeMap?.[urlPath] ?? urlPath.split('/').filter(Boolean).at(-1)
|
|
42
|
-
|
|
43
|
-
const fingerprint = getJsonFingerprint(coreData) // 获取数据指纹
|
|
36
|
+
const fingerprint = getJsonFingerprint(coreData)
|
|
44
37
|
const lastFingerprint = hackedRegistry.get(fileName)
|
|
45
|
-
|
|
46
|
-
// 如果指纹没变,说明字段结构是一样的,无需再次骇入
|
|
47
38
|
if (lastFingerprint === fingerprint) {
|
|
48
39
|
return
|
|
49
40
|
}
|
|
50
|
-
|
|
51
41
|
pod153.report(dialog.pod153.capturedRuntimeSignal(fileName))
|
|
52
|
-
await units.reconciler.
|
|
42
|
+
await units.reconciler.execute({ fileName, data: [coreData[0]] })
|
|
53
43
|
hackedRegistry.set(fileName, fingerprint)
|
|
54
44
|
} catch (e) {
|
|
55
45
|
// 非 JSON 信号,保持静默
|
|
@@ -59,10 +49,8 @@ module.exports = ({ units, yorha, dialog, logistics }) => {
|
|
|
59
49
|
|
|
60
50
|
const server = http.createServer((req, res) => {
|
|
61
51
|
if (!proxyTarget) {
|
|
62
|
-
// 静默模式:如果不配置 proxyTarget,拦截塔只转发不处理(或报错提示)
|
|
63
52
|
return
|
|
64
53
|
}
|
|
65
|
-
// 转发至真实后端
|
|
66
54
|
proxy.web(req, res, { target: proxyTarget, changeOrigin: true })
|
|
67
55
|
})
|
|
68
56
|
|
|
@@ -12,12 +12,6 @@ const getConfig = () => {
|
|
|
12
12
|
return config
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const findUnit = (units, filePath) => {
|
|
16
|
-
const relative = path.relative(path.resolve('bunker'), path.resolve(filePath))
|
|
17
|
-
const root = relative.split(path.sep)[0]
|
|
18
|
-
return units.find(unit => root === unit.station)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
15
|
const getExistingMenus = (dir = 'src/pages') => {
|
|
22
16
|
const pagesDir = path.join(process.cwd(), dir)
|
|
23
17
|
if (!fs.existsSync(pagesDir)) return []
|
|
@@ -26,23 +20,7 @@ const getExistingMenus = (dir = 'src/pages') => {
|
|
|
26
20
|
.map(file => ({ label: file, key: file }))
|
|
27
21
|
}
|
|
28
22
|
|
|
29
|
-
const copyTemplateDir = (template, templateSubDir, targetSubDir) => {
|
|
30
|
-
const targetDir = path.join(process.cwd(), targetSubDir)
|
|
31
|
-
const sourceDir = path.join(__dirname, `../workshop/${template}/${templateSubDir}`)
|
|
32
|
-
if (!fs.existsSync(sourceDir)) return
|
|
33
|
-
fs.mkdirSync(targetDir, { recursive: true })
|
|
34
|
-
fs.readdirSync(sourceDir).forEach(file => {
|
|
35
|
-
const src = path.join(sourceDir, file)
|
|
36
|
-
const dest = path.join(targetDir, file)
|
|
37
|
-
if (!fs.existsSync(dest)) {
|
|
38
|
-
fs.cpSync(src, dest, { recursive: true })
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
}
|
|
42
|
-
|
|
43
23
|
module.exports = {
|
|
44
|
-
findUnit,
|
|
45
24
|
getConfig,
|
|
46
|
-
copyTemplateDir,
|
|
47
25
|
getExistingMenus,
|
|
48
26
|
}
|
package/src/units/raider.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
|
|
3
3
|
module.exports = {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
meta: {
|
|
5
|
+
name: 'raider',
|
|
6
|
+
inputs: ['image'],
|
|
7
|
+
outputs: ['component-config'],
|
|
8
|
+
description: 'extract reusable UI component from visual input',
|
|
9
|
+
capabilities: ['vision', 'component-analysis', 'component-generation'],
|
|
10
|
+
},
|
|
11
|
+
execute: async ({ acp, mission }) => {
|
|
6
12
|
|
|
7
13
|
const chalk = require('chalk')
|
|
8
|
-
const { llm, yorha, dialog, builder, logistics, briefings } =
|
|
14
|
+
const { llm, yorha, dialog, builder, logistics, briefings } = acp
|
|
9
15
|
|
|
10
16
|
const { pod042 } = yorha
|
|
11
17
|
const { raider } = briefings
|
|
@@ -20,7 +26,7 @@ module.exports = {
|
|
|
20
26
|
try {
|
|
21
27
|
pod042.update(spinner, dialog.pod042.extractingUiMetadata)
|
|
22
28
|
|
|
23
|
-
const pageConfig = await recognizePage({ prompt: raider, filePath })
|
|
29
|
+
const pageConfig = await recognizePage({ prompt: raider, filePath: mission.input })
|
|
24
30
|
|
|
25
31
|
const { formItems, dictBlocks, processedColumns } = formatFormItemAndColumns({ pageConfig })
|
|
26
32
|
|
|
@@ -39,15 +45,15 @@ module.exports = {
|
|
|
39
45
|
const endTime = Date.now()
|
|
40
46
|
spinner.stop()
|
|
41
47
|
console.log(chalk.magenta(`\n┌────────────────── [ YoRHa Construction Output ] ─────────────────┐`))
|
|
42
|
-
console.log(chalk.magenta(`│ Source: ${
|
|
48
|
+
console.log(chalk.magenta(`│ Source: ${mission.input}`))
|
|
43
49
|
console.log(chalk.magenta(`│ Protocol: Partial UI Fragment | Status: SUCCESS`))
|
|
44
50
|
console.log(chalk.magenta(`├──────────────────────────────────────────────────────────────────┘`))
|
|
45
51
|
console.log(chalk.white(finalResult))
|
|
46
52
|
pod042.success(spinner, dialog.pod042.partialConstruction((endTime - startTime) / 1000))
|
|
47
53
|
pod042.success(spinner, dialog.pod042.partialRecommendation)
|
|
48
54
|
|
|
49
|
-
if (fs.existsSync(
|
|
50
|
-
fs.unlinkSync(
|
|
55
|
+
if (fs.existsSync(mission.input)) {
|
|
56
|
+
fs.unlinkSync(mission.input)
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
} catch (error) {
|
package/src/units/reconciler.js
CHANGED
|
@@ -2,8 +2,14 @@ const fs = require('fs')
|
|
|
2
2
|
const path = require('path')
|
|
3
3
|
|
|
4
4
|
module.exports = {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
meta: {
|
|
6
|
+
name: 'reconciler',
|
|
7
|
+
inputs: ['response'],
|
|
8
|
+
outputs: ['aligned-resource'],
|
|
9
|
+
capabilities: ['field-alignment', 'resource-update', 'response-analysis'],
|
|
10
|
+
description: 'align backend response fields with frontend resource fields',
|
|
11
|
+
},
|
|
12
|
+
execute: async ({ data, fileName }) => {
|
|
7
13
|
|
|
8
14
|
const chalk = require('chalk')
|
|
9
15
|
const { llm, labs, yorha, dialog, logistics } = require('../awakening').get()
|
|
@@ -11,13 +17,11 @@ module.exports = {
|
|
|
11
17
|
const { nineS, pod153 } = yorha
|
|
12
18
|
const { alignResponseFields } = llm
|
|
13
19
|
const { cleanCode } = logistics.builder
|
|
14
|
-
const { unwrapSignal } = logistics.analyzer
|
|
15
20
|
const { pagesDir } = logistics.supporter.getConfig()
|
|
16
21
|
|
|
17
22
|
const startTime = Date.now()
|
|
18
|
-
const fileName = liveResponse?.fileName ?? path.basename(filePath, path.extname(filePath))
|
|
19
23
|
const resourcePath = path.join(process.cwd(), pagesDir, fileName, 'resource.js')
|
|
20
|
-
const enumParams = (await labs?.council)?.[fileName] ?? ''
|
|
24
|
+
const enumParams = (await labs?.council)?.[fileName] ?? '{}'
|
|
21
25
|
|
|
22
26
|
const spinner = pod153.start(dialog.pod153.reconEncryptedData(fileName))
|
|
23
27
|
|
|
@@ -27,14 +31,8 @@ module.exports = {
|
|
|
27
31
|
return
|
|
28
32
|
}
|
|
29
33
|
|
|
30
|
-
let rawJson = liveResponse ? liveResponse.data : JSON.parse(fs.readFileSync(filePath, 'utf8'))
|
|
31
34
|
let resourceStr = fs.readFileSync(resourcePath, 'utf8')
|
|
32
35
|
|
|
33
|
-
const coreArray = unwrapSignal(rawJson)
|
|
34
|
-
if (!coreArray || coreArray.length === 0) {
|
|
35
|
-
pod153.warning(spinner, dialog.pod153.formatError)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
36
|
nineS.update(spinner, dialog.nineS.scanningField)
|
|
39
37
|
|
|
40
38
|
const extractKeys = str => {
|
|
@@ -47,8 +45,7 @@ module.exports = {
|
|
|
47
45
|
return Array.from(new Set(keys.filter(key => key !== 'index')))
|
|
48
46
|
}
|
|
49
47
|
|
|
50
|
-
const
|
|
51
|
-
const result = await alignResponseFields({ responseStr: JSON.stringify(sampleData), resourceStr: extractKeys(resourceStr).join(',') })
|
|
48
|
+
const result = await alignResponseFields({ responseStr: JSON.stringify(data), resourceStr: extractKeys(resourceStr).join(',') })
|
|
52
49
|
let changeCount = 0
|
|
53
50
|
const resultMapping = {}
|
|
54
51
|
Object.entries(result).forEach(([oldField, newField]) => {
|
|
@@ -87,10 +84,6 @@ module.exports = {
|
|
|
87
84
|
console.log(chalk.magenta(`├───────────────────────────────────────────────────────────┘`))
|
|
88
85
|
}
|
|
89
86
|
|
|
90
|
-
if (fs.existsSync(filePath)) {
|
|
91
|
-
fs.unlinkSync(filePath)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
87
|
} catch (error) {
|
|
95
88
|
pod153.fail(spinner, dialog.pod153.alignmentFailed(error))
|
|
96
89
|
}
|
package/src/units/striker.js
CHANGED
|
@@ -2,10 +2,16 @@ const fs = require('fs')
|
|
|
2
2
|
const path = require('path')
|
|
3
3
|
|
|
4
4
|
module.exports = {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
meta: {
|
|
6
|
+
name: 'striker',
|
|
7
|
+
inputs: ['image'],
|
|
8
|
+
outputs: ['page-config', 'artifacts'],
|
|
9
|
+
description: 'reconstruct full UI from visual input',
|
|
10
|
+
capabilities: ['vision', 'page-analysis', 'page-generation'],
|
|
11
|
+
},
|
|
12
|
+
execute: async ({ acp, mission }) => {
|
|
7
13
|
|
|
8
|
-
const { llm, yorha, dialog, builder, template, logistics, briefings } =
|
|
14
|
+
const { llm, yorha, dialog, builder, template, logistics, briefings } = acp
|
|
9
15
|
|
|
10
16
|
const { striker } = briefings
|
|
11
17
|
const { nineS, pod042 } = yorha
|
|
@@ -16,7 +22,7 @@ module.exports = {
|
|
|
16
22
|
|
|
17
23
|
|
|
18
24
|
const startTime = Date.now()
|
|
19
|
-
let fileName = path.basename(
|
|
25
|
+
let fileName = path.basename(mission.input, path.extname(mission.input))
|
|
20
26
|
let targetDir = path.join(process.cwd(), pagesDir, fileName)
|
|
21
27
|
|
|
22
28
|
const spinner = pod042.start(dialog.pod042.visualCaptured(fileName))
|
|
@@ -33,7 +39,7 @@ module.exports = {
|
|
|
33
39
|
pageConfig = require('../../example/example.json')
|
|
34
40
|
} else {
|
|
35
41
|
pod042.update(spinner, dialog.pod042.uploadVisualMetadata)
|
|
36
|
-
pageConfig = await recognizePage({ prompt: striker, filePath, schema: require(`../workshop/${template}/protocols/striker.json`) })
|
|
42
|
+
pageConfig = await recognizePage({ prompt: striker, filePath: mission.input, schema: require(`../workshop/${template}/protocols/striker.json`) })
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
const { similarity } = await nameSimilarity({ fileName, english: pageConfig.title.english })
|
|
@@ -61,8 +67,8 @@ module.exports = {
|
|
|
61
67
|
const endTime = Date.now()
|
|
62
68
|
pod042.success(spinner, dialog.pod042.assemblyComplete(fileName, (endTime - startTime) / 1000))
|
|
63
69
|
|
|
64
|
-
if (fs.existsSync(
|
|
65
|
-
fs.unlinkSync(
|
|
70
|
+
if (fs.existsSync(mission.input)) {
|
|
71
|
+
fs.unlinkSync(mission.input)
|
|
66
72
|
const cwdUtilsDir = path.join(process.cwd(), utilsDir)
|
|
67
73
|
if (!fs.existsSync(cwdUtilsDir)) fs.mkdirSync(cwdUtilsDir, { recursive: true })
|
|
68
74
|
fs.writeFileSync(path.join(cwdUtilsDir, 'menus.js'), `export const menus = ${contextStringify({ context: logistics.supporter.getExistingMenus(pagesDir), maxLength: 50 })}`)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module.exports = `
|
|
2
|
+
# Mission Classification
|
|
3
|
+
|
|
4
|
+
分析输入图片,判断它属于以下哪一种任务类型:
|
|
5
|
+
|
|
6
|
+
## Full CRUD Page
|
|
7
|
+
|
|
8
|
+
完整的 CRUD 页面。
|
|
9
|
+
|
|
10
|
+
满足以下特征中的大部分:
|
|
11
|
+
- 页面结构完整
|
|
12
|
+
- 包含页面级功能区域
|
|
13
|
+
- 包含查询表单或筛选区域
|
|
14
|
+
- 包含表格主体
|
|
15
|
+
- 包含行操作
|
|
16
|
+
- 包含新增、编辑、删除等功能按钮
|
|
17
|
+
- 可能包含统计区域、导出按钮等页面级功能
|
|
18
|
+
|
|
19
|
+
返回:
|
|
20
|
+
|
|
21
|
+
{
|
|
22
|
+
"capabilities": [
|
|
23
|
+
"vision",
|
|
24
|
+
"page-analysis",
|
|
25
|
+
"page-generation"
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
## Partial CRUD Page
|
|
30
|
+
|
|
31
|
+
局部 CRUD 页面或 UI 碎片。
|
|
32
|
+
|
|
33
|
+
例如:
|
|
34
|
+
- 仅包含表格
|
|
35
|
+
- 仅包含表单
|
|
36
|
+
- 仅包含筛选区域
|
|
37
|
+
- 仅包含某个 CRUD 功能区域
|
|
38
|
+
- 页面结构明显不完整
|
|
39
|
+
|
|
40
|
+
返回:
|
|
41
|
+
|
|
42
|
+
{
|
|
43
|
+
"capabilities": [
|
|
44
|
+
"vision",
|
|
45
|
+
"component-analysis",
|
|
46
|
+
"component-generation"
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
## Result
|
|
51
|
+
|
|
52
|
+
只允许返回 JSON:
|
|
53
|
+
|
|
54
|
+
{
|
|
55
|
+
"capabilities": []
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
不要返回任何额外文字。
|
|
59
|
+
`.trim()
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
|
|
4
|
-
module.exports = ({ units, yorha, dialog, template, logistics }) => {
|
|
5
|
-
|
|
6
|
-
const { copyTemplateDir } = logistics.supporter
|
|
7
|
-
const { hbsDir, hooksDir, utilsDir, componentsDir } = logistics.supporter.getConfig()
|
|
8
|
-
|
|
9
|
-
try {
|
|
10
|
-
Object.values(units).forEach(unit => fs.mkdirSync(path.join(process.cwd(), 'bunker', unit.station), { recursive: true }))
|
|
11
|
-
if (!hbsDir) {
|
|
12
|
-
copyTemplateDir(template, 'kit', utilsDir)
|
|
13
|
-
copyTemplateDir(template, 'extensions', hooksDir)
|
|
14
|
-
copyTemplateDir(template, 'standardParts', componentsDir)
|
|
15
|
-
}
|
|
16
|
-
} catch (error) {
|
|
17
|
-
yorha.commander.report(dialog.bunker.copyTemplateError(error), 'red')
|
|
18
|
-
}
|
|
19
|
-
}
|