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.
Files changed (122) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +772 -3
  3. package/engineering/plugins/dsh-engineering-ui/cordis.patch.yml +5 -0
  4. package/engineering/plugins/dsh-engineering-ui/icon.svg +14 -0
  5. package/engineering/plugins/dsh-engineering-ui/lib/client.js +8259 -0
  6. package/engineering/plugins/dsh-engineering-ui/lib/defense-sign.js +1552 -0
  7. package/engineering/plugins/dsh-engineering-ui/lib/index.js +5633 -0
  8. package/engineering/plugins/dsh-engineering-ui/lib/job-wait-guard.js +236 -0
  9. package/engineering/plugins/dsh-engineering-ui/lib/mem-guard.js +331 -0
  10. package/engineering/plugins/dsh-engineering-ui/lib/webots.js +114 -0
  11. package/engineering/plugins/dsh-engineering-ui/locale/en.json +6 -0
  12. package/engineering/plugins/dsh-engineering-ui/locale/zh.json +6 -0
  13. package/engineering/plugins/dsh-engineering-ui/preset-engineering.patch.yml +601 -0
  14. package/engineering/skills/assembly-orchestration/SKILL.md +651 -0
  15. package/engineering/skills/cad-workflow/SKILL.md +132 -0
  16. package/engineering/skills/mode-selection/SKILL.md +660 -0
  17. package/engineering/skills/physics-in-loop/SKILL.md +238 -0
  18. package/engineering/skills/physics-in-loop/references/feadocs.md +142 -0
  19. package/engineering/skills/solidworks-bridge/SKILL.md +445 -0
  20. package/engineering/skills/sw-design/SKILL.md +112 -0
  21. package/engineering/skills/sw-design/references/autocad-workflow.md +81 -0
  22. package/engineering/skills/sw-design/references/gbt-drafting.md +71 -0
  23. package/engineering/skills/sw-to-cad/SKILL.md +121 -0
  24. package/engineering/skills/webots-simulation/SKILL.md +58 -0
  25. package/engineering/tools/LICENSE.Auto-SolidWorks +21 -0
  26. package/engineering/tools/_plugin_paths.py +93 -0
  27. package/engineering/tools/_root.py +330 -0
  28. package/engineering/tools/_store.py +446 -0
  29. package/engineering/tools/ac_bridge.py +459 -0
  30. package/engineering/tools/ac_rules.json +21 -0
  31. package/engineering/tools/ac_validate.py +699 -0
  32. package/engineering/tools/ask_user.py +887 -0
  33. package/engineering/tools/build_arm1.py +46 -0
  34. package/engineering/tools/build_assembly.py +94 -0
  35. package/engineering/tools/build_base.py +57 -0
  36. package/engineering/tools/build_housing.py +70 -0
  37. package/engineering/tools/build_structural.py +43 -0
  38. package/engineering/tools/build_transmission.py +69 -0
  39. package/engineering/tools/cadx.lsp +128 -0
  40. package/engineering/tools/choice_contract.py +61 -0
  41. package/engineering/tools/conn_state.py +1671 -0
  42. package/engineering/tools/defense_gate.py +3374 -0
  43. package/engineering/tools/drawing_input.py +314 -0
  44. package/engineering/tools/env_check.py +467 -0
  45. package/engineering/tools/examples/build_axis.py +142 -0
  46. package/engineering/tools/examples/build_cup.py +56 -0
  47. package/engineering/tools/examples/build_plate.py +58 -0
  48. package/engineering/tools/examples/build_sphere.py +30 -0
  49. package/engineering/tools/examples/build_transition_duct.py +381 -0
  50. package/engineering/tools/gate_integrity.py +401 -0
  51. package/engineering/tools/mode2_flow.py +3589 -0
  52. package/engineering/tools/mode_checker.py +77 -0
  53. package/engineering/tools/mode_gate.py +8013 -0
  54. package/engineering/tools/part_registry.py +4266 -0
  55. package/engineering/tools/physics/__init__.py +50 -0
  56. package/engineering/tools/physics/_compat.py +12 -0
  57. package/engineering/tools/physics/design_state.py +142 -0
  58. package/engineering/tools/physics/domain_validator.py +751 -0
  59. package/engineering/tools/physics/fatigue.py +489 -0
  60. package/engineering/tools/physics/fea_solver.py +1163 -0
  61. package/engineering/tools/physics/feapy_solver.py +314 -0
  62. package/engineering/tools/physics/gb_materials.json +1228 -0
  63. package/engineering/tools/physics/geometry_gate.py +337 -0
  64. package/engineering/tools/physics/load_case.py +951 -0
  65. package/engineering/tools/physics/material_db.py +874 -0
  66. package/engineering/tools/physics/mesh_adapter.py +321 -0
  67. package/engineering/tools/physics/refine_rules.py +272 -0
  68. package/engineering/tools/physics/rules/gb_base_rules.json +377 -0
  69. package/engineering/tools/physics/rules/gb_drafting_rules.json +57 -0
  70. package/engineering/tools/physics/rules/gb_electrical_rules.json +25 -0
  71. package/engineering/tools/physics/rules/gb_fasteners_rules.json +73 -0
  72. package/engineering/tools/physics/rules/gb_housing_rules.json +41 -0
  73. package/engineering/tools/physics/rules/gb_manufacturing_rules.json +25 -0
  74. package/engineering/tools/physics/rules/gb_material_verify_rules.json +72 -0
  75. package/engineering/tools/physics/rules/gb_materials_rules.json +377 -0
  76. package/engineering/tools/physics/rules/gb_safety_rules.json +89 -0
  77. package/engineering/tools/physics/rules/gb_springs_rules.json +41 -0
  78. package/engineering/tools/physics/rules/gb_standards_registry.json +1646 -0
  79. package/engineering/tools/physics/rules/gb_structural_rules.json +201 -0
  80. package/engineering/tools/physics/rules/gb_surface_rules.json +25 -0
  81. package/engineering/tools/physics/rules/gb_transmission_rules.json +233 -0
  82. package/engineering/tools/physics/rules/housing_rules.json +48 -0
  83. package/engineering/tools/physics/rules/manifest.json +54 -0
  84. package/engineering/tools/physics/rules/mold_rules.json +48 -0
  85. package/engineering/tools/physics/rules/structural_rules.json +56 -0
  86. package/engineering/tools/physics/rules/transmission_rules.json +48 -0
  87. package/engineering/tools/physics/simulation_report.py +829 -0
  88. package/engineering/tools/physics_bridge.py +2685 -0
  89. package/engineering/tools/profile-manifest.ps1 +72 -0
  90. package/engineering/tools/run_regression.py +109 -0
  91. package/engineering/tools/settings.py +419 -0
  92. package/engineering/tools/solidworks-modeling.md +519 -0
  93. package/engineering/tools/sw_bridge.py +8215 -0
  94. package/engineering/tools/sw_guard.py +1066 -0
  95. package/engineering/tools/sw_surface.py +87 -0
  96. package/engineering/tools/swapi.py +14766 -0
  97. package/engineering/tools/verify_sync.py +218 -0
  98. package/engineering/tools/visual_check.py +2589 -0
  99. package/engineering/tools/webots_env.py +121 -0
  100. package/engineering/tools/webots_mcp/__init__.py +3 -0
  101. package/engineering/tools/webots_mcp/__main__.py +3 -0
  102. package/engineering/tools/webots_mcp/assembly.py +391 -0
  103. package/engineering/tools/webots_mcp/bootstrap.py +55 -0
  104. package/engineering/tools/webots_mcp/controller_worker.py +124 -0
  105. package/engineering/tools/webots_mcp/evidence.py +288 -0
  106. package/engineering/tools/webots_mcp/fake_worker.py +69 -0
  107. package/engineering/tools/webots_mcp/fault_resources.py +121 -0
  108. package/engineering/tools/webots_mcp/host.py +45 -0
  109. package/engineering/tools/webots_mcp/ledger.py +73 -0
  110. package/engineering/tools/webots_mcp/owned_job.py +70 -0
  111. package/engineering/tools/webots_mcp/physical_gate.py +187 -0
  112. package/engineering/tools/webots_mcp/physics.py +152 -0
  113. package/engineering/tools/webots_mcp/pipeline.py +108 -0
  114. package/engineering/tools/webots_mcp/recipes.py +129 -0
  115. package/engineering/tools/webots_mcp/repair.py +132 -0
  116. package/engineering/tools/webots_mcp/repair_trial.py +375 -0
  117. package/engineering/tools/webots_mcp/runtime.py +311 -0
  118. package/engineering/tools/webots_mcp/server.py +217 -0
  119. package/engineering/tools/webots_mcp/sw_export.py +509 -0
  120. package/engineering/tools/webots_mcp/transport.py +156 -0
  121. package/engineering/tools/workflow_gate.py +6134 -0
  122. 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)