dsh-engineering-ui 0.0.0-stage → 1.5.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/LICENSE +21 -0
- package/README.md +772 -3
- package/engineering/plugins/dsh-engineering-ui/cordis.patch.yml +5 -0
- package/engineering/plugins/dsh-engineering-ui/icon.svg +14 -0
- package/engineering/plugins/dsh-engineering-ui/lib/client.js +8259 -0
- package/engineering/plugins/dsh-engineering-ui/lib/defense-sign.js +1552 -0
- package/engineering/plugins/dsh-engineering-ui/lib/index.js +5633 -0
- package/engineering/plugins/dsh-engineering-ui/lib/job-wait-guard.js +236 -0
- package/engineering/plugins/dsh-engineering-ui/lib/mem-guard.js +331 -0
- package/engineering/plugins/dsh-engineering-ui/lib/webots.js +114 -0
- package/engineering/plugins/dsh-engineering-ui/locale/en.json +6 -0
- package/engineering/plugins/dsh-engineering-ui/locale/zh.json +6 -0
- package/engineering/plugins/dsh-engineering-ui/preset-engineering.patch.yml +601 -0
- package/engineering/skills/assembly-orchestration/SKILL.md +651 -0
- package/engineering/skills/cad-workflow/SKILL.md +132 -0
- package/engineering/skills/mode-selection/SKILL.md +660 -0
- package/engineering/skills/physics-in-loop/SKILL.md +238 -0
- package/engineering/skills/physics-in-loop/references/feadocs.md +142 -0
- package/engineering/skills/solidworks-bridge/SKILL.md +445 -0
- package/engineering/skills/sw-design/SKILL.md +112 -0
- package/engineering/skills/sw-design/references/autocad-workflow.md +81 -0
- package/engineering/skills/sw-design/references/gbt-drafting.md +71 -0
- package/engineering/skills/sw-to-cad/SKILL.md +121 -0
- package/engineering/skills/webots-simulation/SKILL.md +58 -0
- package/engineering/tools/LICENSE.Auto-SolidWorks +21 -0
- package/engineering/tools/_plugin_paths.py +93 -0
- package/engineering/tools/_root.py +330 -0
- package/engineering/tools/_store.py +446 -0
- package/engineering/tools/ac_bridge.py +459 -0
- package/engineering/tools/ac_rules.json +21 -0
- package/engineering/tools/ac_validate.py +699 -0
- package/engineering/tools/ask_user.py +887 -0
- package/engineering/tools/build_arm1.py +46 -0
- package/engineering/tools/build_assembly.py +94 -0
- package/engineering/tools/build_base.py +57 -0
- package/engineering/tools/build_housing.py +70 -0
- package/engineering/tools/build_structural.py +43 -0
- package/engineering/tools/build_transmission.py +69 -0
- package/engineering/tools/cadx.lsp +128 -0
- package/engineering/tools/choice_contract.py +61 -0
- package/engineering/tools/conn_state.py +1671 -0
- package/engineering/tools/defense_gate.py +3374 -0
- package/engineering/tools/drawing_input.py +314 -0
- package/engineering/tools/env_check.py +467 -0
- package/engineering/tools/examples/build_axis.py +142 -0
- package/engineering/tools/examples/build_cup.py +56 -0
- package/engineering/tools/examples/build_plate.py +58 -0
- package/engineering/tools/examples/build_sphere.py +30 -0
- package/engineering/tools/examples/build_transition_duct.py +381 -0
- package/engineering/tools/gate_integrity.py +401 -0
- package/engineering/tools/mode2_flow.py +3589 -0
- package/engineering/tools/mode_checker.py +77 -0
- package/engineering/tools/mode_gate.py +8013 -0
- package/engineering/tools/part_registry.py +4266 -0
- package/engineering/tools/physics/__init__.py +50 -0
- package/engineering/tools/physics/_compat.py +12 -0
- package/engineering/tools/physics/design_state.py +142 -0
- package/engineering/tools/physics/domain_validator.py +751 -0
- package/engineering/tools/physics/fatigue.py +489 -0
- package/engineering/tools/physics/fea_solver.py +1163 -0
- package/engineering/tools/physics/feapy_solver.py +314 -0
- package/engineering/tools/physics/gb_materials.json +1228 -0
- package/engineering/tools/physics/geometry_gate.py +337 -0
- package/engineering/tools/physics/load_case.py +951 -0
- package/engineering/tools/physics/material_db.py +874 -0
- package/engineering/tools/physics/mesh_adapter.py +321 -0
- package/engineering/tools/physics/refine_rules.py +272 -0
- package/engineering/tools/physics/rules/gb_base_rules.json +377 -0
- package/engineering/tools/physics/rules/gb_drafting_rules.json +57 -0
- package/engineering/tools/physics/rules/gb_electrical_rules.json +25 -0
- package/engineering/tools/physics/rules/gb_fasteners_rules.json +73 -0
- package/engineering/tools/physics/rules/gb_housing_rules.json +41 -0
- package/engineering/tools/physics/rules/gb_manufacturing_rules.json +25 -0
- package/engineering/tools/physics/rules/gb_material_verify_rules.json +72 -0
- package/engineering/tools/physics/rules/gb_materials_rules.json +377 -0
- package/engineering/tools/physics/rules/gb_safety_rules.json +89 -0
- package/engineering/tools/physics/rules/gb_springs_rules.json +41 -0
- package/engineering/tools/physics/rules/gb_standards_registry.json +1646 -0
- package/engineering/tools/physics/rules/gb_structural_rules.json +201 -0
- package/engineering/tools/physics/rules/gb_surface_rules.json +25 -0
- package/engineering/tools/physics/rules/gb_transmission_rules.json +233 -0
- package/engineering/tools/physics/rules/housing_rules.json +48 -0
- package/engineering/tools/physics/rules/manifest.json +54 -0
- package/engineering/tools/physics/rules/mold_rules.json +48 -0
- package/engineering/tools/physics/rules/structural_rules.json +56 -0
- package/engineering/tools/physics/rules/transmission_rules.json +48 -0
- package/engineering/tools/physics/simulation_report.py +829 -0
- package/engineering/tools/physics_bridge.py +2685 -0
- package/engineering/tools/profile-manifest.ps1 +72 -0
- package/engineering/tools/run_regression.py +109 -0
- package/engineering/tools/settings.py +419 -0
- package/engineering/tools/solidworks-modeling.md +519 -0
- package/engineering/tools/sw_bridge.py +8215 -0
- package/engineering/tools/sw_guard.py +1066 -0
- package/engineering/tools/sw_surface.py +87 -0
- package/engineering/tools/swapi.py +14766 -0
- package/engineering/tools/verify_sync.py +218 -0
- package/engineering/tools/visual_check.py +2589 -0
- package/engineering/tools/webots_env.py +121 -0
- package/engineering/tools/webots_mcp/__init__.py +3 -0
- package/engineering/tools/webots_mcp/__main__.py +3 -0
- package/engineering/tools/webots_mcp/assembly.py +391 -0
- package/engineering/tools/webots_mcp/bootstrap.py +55 -0
- package/engineering/tools/webots_mcp/controller_worker.py +124 -0
- package/engineering/tools/webots_mcp/evidence.py +288 -0
- package/engineering/tools/webots_mcp/fake_worker.py +69 -0
- package/engineering/tools/webots_mcp/fault_resources.py +121 -0
- package/engineering/tools/webots_mcp/host.py +45 -0
- package/engineering/tools/webots_mcp/ledger.py +73 -0
- package/engineering/tools/webots_mcp/owned_job.py +70 -0
- package/engineering/tools/webots_mcp/physical_gate.py +187 -0
- package/engineering/tools/webots_mcp/physics.py +152 -0
- package/engineering/tools/webots_mcp/pipeline.py +108 -0
- package/engineering/tools/webots_mcp/recipes.py +129 -0
- package/engineering/tools/webots_mcp/repair.py +132 -0
- package/engineering/tools/webots_mcp/repair_trial.py +375 -0
- package/engineering/tools/webots_mcp/runtime.py +311 -0
- package/engineering/tools/webots_mcp/server.py +217 -0
- package/engineering/tools/webots_mcp/sw_export.py +509 -0
- package/engineering/tools/webots_mcp/transport.py +156 -0
- package/engineering/tools/workflow_gate.py +6134 -0
- package/package.json +64 -4
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
r"""校验 DSH 安装副本与仓库是否【完全同步】(逐文件哈希比对)。
|
|
3
|
+
|
|
4
|
+
DryRun 报 "0 synced" 只能说明 sync 脚本没找到要复制的 ——
|
|
5
|
+
但它的 Should-Skip 会跳过若干类型(.bak/_probe_/二进制等)。
|
|
6
|
+
因此这里做一次**独立的全量比对**,把差异逐条列出来,
|
|
7
|
+
证明"关键代码确实一致",而不是只信脚本的自述。
|
|
8
|
+
|
|
9
|
+
比对对象(sync 脚本覆盖的四处落点):
|
|
10
|
+
1. engineering/tools -> ~/.dsh/.agent-presets/engineering/tools
|
|
11
|
+
2. engineering/skills -> ~/.dsh/skills
|
|
12
|
+
3. engineering/docs -> ~/.dsh/.agent-presets/engineering/docs
|
|
13
|
+
4. plugins/dsh-eng-ui -> ~/.dsh/profiles/*/node_modules/dsh-engineering-ui
|
|
14
|
+
5. preset 层根文件 -> ~/.dsh/.agent-presets/engineering/
|
|
15
|
+
"""
|
|
16
|
+
import hashlib
|
|
17
|
+
import os
|
|
18
|
+
import sys
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
22
|
+
except Exception:
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
# ── 【换机修复】不写死作者本机桌面路径 ──────────────────────────────────
|
|
26
|
+
# 旧写法 REPO = r"C:\Users\j1877\Desktop\DSH-SW-and-CAD-main"
|
|
27
|
+
# 换台电脑 / 别人 clone 后必然比对失败(报"仓库不存在"或比到别处)。
|
|
28
|
+
# 现在:argv[1] > 环境变量 DSH_REPO_ROOT > 由本文件位置向上两级推导
|
|
29
|
+
# (tools/ -> engineering/ -> 仓库根)。
|
|
30
|
+
def _find_repo():
|
|
31
|
+
import sys as _sys
|
|
32
|
+
if len(_sys.argv) > 1 and os.path.isdir(_sys.argv[1]):
|
|
33
|
+
return os.path.abspath(_sys.argv[1])
|
|
34
|
+
env = (os.environ.get("DSH_REPO_ROOT") or "").strip()
|
|
35
|
+
if env and os.path.isdir(env):
|
|
36
|
+
return os.path.abspath(env)
|
|
37
|
+
here = os.path.dirname(os.path.abspath(__file__)) # .../engineering/tools
|
|
38
|
+
return os.path.dirname(os.path.dirname(here)) # .../
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
REPO = _find_repo()
|
|
42
|
+
DSH = os.path.expanduser(r"~\.dsh")
|
|
43
|
+
DATA = os.path.join(DSH, ".agent-presets", "engineering")
|
|
44
|
+
|
|
45
|
+
# 与 sync 脚本保持一致的跳过规则
|
|
46
|
+
RUNTIME_NAMES = {
|
|
47
|
+
'mode_state.json', 'workflow_state.json', 'sw_state.json',
|
|
48
|
+
'platform_status.json', 'artifacts_registry.json', 'TASK_FINISHED.json',
|
|
49
|
+
'connection_state.json', 'design_params.json', 'defense_bypass.json',
|
|
50
|
+
'violations.json', 'guard.json', 'runtime.json',
|
|
51
|
+
# -- [换机修复] 本机设置(交付目录 / 各软件路径)按运行时数据处理 --
|
|
52
|
+
'settings.json',
|
|
53
|
+
# -- [2026-10-28] 与 sync 脚本同步扩充的运行时数据 --
|
|
54
|
+
'platform_agents.json', 'part_registry.json', 'custom_materials.json',
|
|
55
|
+
# 插件/AI 写入的现场文件(不属于代码)
|
|
56
|
+
'persona.json', 'sw_guard.log', 'sw_guard.pid', 'sw_monitor.pid',
|
|
57
|
+
# -- [Webots 接入] 与 sync-to-dsh.ps1 同步扩充的运行时数据 --
|
|
58
|
+
# 仿真现场(状态投影 / 作业账本 / 实例锁)绝不跟着代码走:
|
|
59
|
+
# 覆盖 = 丢正在跑的作业与证据;跨机同步更是毫无意义。
|
|
60
|
+
'webots_state.json', 'webots_jobs.sqlite3', 'webots_jobs.sqlite3-wal',
|
|
61
|
+
'webots_jobs.sqlite3-shm', 'webots_instance.lock',
|
|
62
|
+
}
|
|
63
|
+
RUNTIME_DIRS = {'reports', 'heartbeats', 'load_cases', 'physics_runs',
|
|
64
|
+
'mode_logs', '.defense', '__pycache__', 'output',
|
|
65
|
+
# webots_runs/<run_id>/ 是报告与证据落点(model_manifest /
|
|
66
|
+
# conversion_report / experiment_report / logs / evidence),
|
|
67
|
+
# 属于运行现场,不是代码。
|
|
68
|
+
'webots_runs'}
|
|
69
|
+
BIN_EXT = ('.sldprt', '.sldasm', '.slddrw', '.dwg', '.dxf', '.step', '.stp',
|
|
70
|
+
'.igs', '.stl', '.pdf', '.png', '.jpg', '.jpeg', '.zip', '.7z')
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def skip(name, parts):
|
|
74
|
+
# -- 【换机修复·降噪】按任务的运行时快照也算现场数据 ------------------
|
|
75
|
+
# 实测:安装副本里有 artifacts_registry.20261019_202722_88C07F68.json
|
|
76
|
+
# 这类【带时间戳的历史台账快照】,属于会话现场数据,本来就不该
|
|
77
|
+
# 从仓库同步过去,也不该被算成差异(否则每次比对都红一片,
|
|
78
|
+
# 真正的代码差异被淹掉)。
|
|
79
|
+
if name.startswith("artifacts_registry.") and name.endswith(".json"):
|
|
80
|
+
return True
|
|
81
|
+
if name in RUNTIME_NAMES:
|
|
82
|
+
return True
|
|
83
|
+
if '.bak' in name or name.endswith('.pyc') or name.startswith('~$'):
|
|
84
|
+
return True
|
|
85
|
+
if name.startswith('_probe_'):
|
|
86
|
+
return True
|
|
87
|
+
# 调试/一次性脚本(_tmp_ 前缀)与日志/pid 都不属于代码
|
|
88
|
+
if name.startswith('_tmp_'):
|
|
89
|
+
return True
|
|
90
|
+
if name.endswith('.log') or name.endswith('.pid'):
|
|
91
|
+
return True
|
|
92
|
+
if '%' in name:
|
|
93
|
+
return True
|
|
94
|
+
if name.lower().endswith(BIN_EXT):
|
|
95
|
+
return True
|
|
96
|
+
for p in parts:
|
|
97
|
+
if p in RUNTIME_DIRS:
|
|
98
|
+
return True
|
|
99
|
+
if p.startswith('_probe_') or '%' in p:
|
|
100
|
+
return True
|
|
101
|
+
if '.bak' in str(p):
|
|
102
|
+
return True
|
|
103
|
+
return False
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def md5(p):
|
|
107
|
+
h = hashlib.md5()
|
|
108
|
+
with open(p, 'rb') as f:
|
|
109
|
+
for chunk in iter(lambda: f.read(1 << 20), b''):
|
|
110
|
+
h.update(chunk)
|
|
111
|
+
return h.hexdigest()
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def compare(src_root, dst_root, label):
|
|
115
|
+
"""返回 (only_in_src, only_in_dst, differ, same_count)"""
|
|
116
|
+
only_src, only_dst, differ, same = [], [], [], 0
|
|
117
|
+
if not os.path.isdir(src_root):
|
|
118
|
+
return None
|
|
119
|
+
if not os.path.isdir(dst_root):
|
|
120
|
+
return ([], [], [], 0, "目标目录不存在: %s" % dst_root)
|
|
121
|
+
seen = set()
|
|
122
|
+
for dp, dns, fns in os.walk(src_root):
|
|
123
|
+
rel_dir = os.path.relpath(dp, src_root)
|
|
124
|
+
parts_dir = [] if rel_dir == '.' else rel_dir.split(os.sep)
|
|
125
|
+
for fn in fns:
|
|
126
|
+
rel = os.path.join(rel_dir, fn) if rel_dir != '.' else fn
|
|
127
|
+
parts = parts_dir + [fn]
|
|
128
|
+
if skip(fn, parts):
|
|
129
|
+
continue
|
|
130
|
+
seen.add(os.path.normcase(rel))
|
|
131
|
+
s = os.path.join(dp, fn)
|
|
132
|
+
d = os.path.join(dst_root, rel)
|
|
133
|
+
if not os.path.exists(d):
|
|
134
|
+
only_src.append(rel)
|
|
135
|
+
elif md5(s) != md5(d):
|
|
136
|
+
differ.append(rel)
|
|
137
|
+
else:
|
|
138
|
+
same += 1
|
|
139
|
+
for dp, dns, fns in os.walk(dst_root):
|
|
140
|
+
rel_dir = os.path.relpath(dp, dst_root)
|
|
141
|
+
parts_dir = [] if rel_dir == '.' else rel_dir.split(os.sep)
|
|
142
|
+
for fn in fns:
|
|
143
|
+
rel = os.path.join(rel_dir, fn) if rel_dir != '.' else fn
|
|
144
|
+
parts = parts_dir + [fn]
|
|
145
|
+
if skip(fn, parts):
|
|
146
|
+
continue
|
|
147
|
+
if os.path.normcase(rel) not in seen:
|
|
148
|
+
only_dst.append(rel)
|
|
149
|
+
return (only_src, only_dst, differ, same, None)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
PAIRS = [
|
|
153
|
+
(os.path.join(REPO, "engineering", "tools"),
|
|
154
|
+
os.path.join(DATA, "tools"), "tools"),
|
|
155
|
+
(os.path.join(REPO, "engineering", "skills"),
|
|
156
|
+
os.path.join(DSH, "skills"), "skills"),
|
|
157
|
+
(os.path.join(REPO, "engineering", "docs"),
|
|
158
|
+
os.path.join(DATA, "docs"), "docs"),
|
|
159
|
+
(os.path.join(REPO, "engineering", "plugins", "dsh-engineering-ui"),
|
|
160
|
+
os.path.join(DSH, "profiles", "web", "node_modules", "dsh-engineering-ui"),
|
|
161
|
+
"plugin@web"),
|
|
162
|
+
(os.path.join(REPO, "engineering", "plugins", "dsh-engineering-ui"),
|
|
163
|
+
os.path.join(DSH, "profiles", "desktop", "node_modules", "dsh-engineering-ui"),
|
|
164
|
+
"plugin@desktop"),
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
print("=" * 78)
|
|
168
|
+
print("DSH 安装副本 vs 仓库:逐文件哈希比对")
|
|
169
|
+
print("=" * 78)
|
|
170
|
+
total_bad = 0
|
|
171
|
+
for src, dst, label in PAIRS:
|
|
172
|
+
r = compare(src, dst, label)
|
|
173
|
+
if r is None:
|
|
174
|
+
print("\n[%s] 源目录不存在,跳过" % label)
|
|
175
|
+
continue
|
|
176
|
+
if len(r) == 5 and r[4]:
|
|
177
|
+
print("\n[%s] %s" % (label, r[4]))
|
|
178
|
+
total_bad += 1
|
|
179
|
+
continue
|
|
180
|
+
only_src, only_dst, differ, same = r[:4]
|
|
181
|
+
bad = len(only_src) + len(differ)
|
|
182
|
+
total_bad += bad
|
|
183
|
+
print("\n[%s]" % label)
|
|
184
|
+
print(" 一致 = %d" % same)
|
|
185
|
+
print(" 仅仓库有(安装缺) = %d" % len(only_src))
|
|
186
|
+
print(" 内容不同 = %d" % len(differ))
|
|
187
|
+
print(" 仅安装有(多余) = %d" % len(only_dst))
|
|
188
|
+
for x in only_src[:8]:
|
|
189
|
+
print(" [缺] %s" % x)
|
|
190
|
+
for x in differ[:8]:
|
|
191
|
+
print(" [异] %s" % x)
|
|
192
|
+
for x in only_dst[:5]:
|
|
193
|
+
print(" [余] %s" % x)
|
|
194
|
+
|
|
195
|
+
# preset 层根文件
|
|
196
|
+
print("\n[preset 根文件]")
|
|
197
|
+
for fn in ('agent.cordis.yml', 'preset.yml', 'install-plugin.ps1', 'README.md'):
|
|
198
|
+
s = os.path.join(REPO, "engineering", fn)
|
|
199
|
+
d = os.path.join(DATA, fn)
|
|
200
|
+
if not os.path.exists(s):
|
|
201
|
+
continue
|
|
202
|
+
if not os.path.exists(d):
|
|
203
|
+
print(" [缺] %s" % fn)
|
|
204
|
+
total_bad += 1
|
|
205
|
+
elif md5(s) != md5(d):
|
|
206
|
+
print(" [异] %s" % fn)
|
|
207
|
+
total_bad += 1
|
|
208
|
+
else:
|
|
209
|
+
print(" [同] %s" % fn)
|
|
210
|
+
|
|
211
|
+
print()
|
|
212
|
+
print("=" * 78)
|
|
213
|
+
if total_bad == 0:
|
|
214
|
+
print("★ 结论:安装副本与仓库【完全同步】,无差异 ✅")
|
|
215
|
+
else:
|
|
216
|
+
print("★ 结论:仍有 %d 处差异,需要再次同步 ❌" % total_bad)
|
|
217
|
+
print("=" * 78)
|
|
218
|
+
sys.exit(1 if total_bad else 0)
|