@whyshu/argent-engine 0.0.0-stage → 0.6.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 (305) hide show
  1. package/MANIFEST.json +307 -0
  2. package/engine/VERSION +1 -0
  3. package/engine/agents/catalog.json +454 -0
  4. package/engine/configs/_aliases.proposed.json +651 -0
  5. package/engine/configs/_migration-plan.proposed.json +899 -0
  6. package/engine/configs/account.json +272 -0
  7. package/engine/configs/advanced.json +205 -0
  8. package/engine/configs/host.json +149 -0
  9. package/engine/configs/hr.json +27 -0
  10. package/engine/configs/notify.json +264 -0
  11. package/engine/core/cli/argent.mjs +277 -0
  12. package/engine/core/contracts/argent.contracts.json +1065 -0
  13. package/engine/core/contracts/verbs.schema.json +2539 -0
  14. package/engine/core/lib/argent-datadir.mjs +223 -0
  15. package/engine/core/lib/audit.mjs +187 -0
  16. package/engine/core/lib/claim.mjs +258 -0
  17. package/engine/core/lib/config-catalog.mjs +1172 -0
  18. package/engine/core/lib/doctor-customer.mjs +577 -0
  19. package/engine/core/lib/flow-list.mjs +138 -0
  20. package/engine/core/lib/flow-registry.mjs +48 -0
  21. package/engine/core/lib/init.mjs +247 -0
  22. package/engine/core/lib/ledger.mjs +124 -0
  23. package/engine/core/lib/license-activate.mjs +813 -0
  24. package/engine/core/lib/license-device.mjs +314 -0
  25. package/engine/core/lib/license-file.mjs +349 -0
  26. package/engine/core/lib/license-guard.mjs +123 -0
  27. package/engine/core/lib/license-ops.mjs +1645 -0
  28. package/engine/core/lib/license-verdict.mjs +133 -0
  29. package/engine/core/lib/license.mjs +577 -0
  30. package/engine/core/lib/notify/dedup.mjs +101 -0
  31. package/engine/core/lib/notify/feishu.mjs +38 -0
  32. package/engine/core/lib/notify/index.mjs +95 -0
  33. package/engine/core/lib/notify/verb.mjs +327 -0
  34. package/engine/core/lib/notify/webhook.mjs +135 -0
  35. package/engine/core/lib/notify/wecom.mjs +36 -0
  36. package/engine/core/lib/python.mjs +145 -0
  37. package/engine/core/lib/sop.mjs +116 -0
  38. package/engine/core/lib/versions.mjs +205 -0
  39. package/engine/core/mcp/client.mjs +67 -0
  40. package/engine/core/mcp/http.mjs +138 -0
  41. package/engine/core/mcp/server.mjs +702 -0
  42. package/engine/scripts/_engine_rules_probe.py +15 -0
  43. package/engine/scripts/analyze-full-day.py +568 -0
  44. package/engine/scripts/archive/feishu-bridge.js +246 -0
  45. package/engine/scripts/argent-agents.mjs +527 -0
  46. package/engine/scripts/argent-capabilities.mjs +776 -0
  47. package/engine/scripts/argent-catalog.mjs +186 -0
  48. package/engine/scripts/argent-datadir.py +62 -0
  49. package/engine/scripts/argent-doctor.mjs +624 -0
  50. package/engine/scripts/argent-env-write.mjs +302 -0
  51. package/engine/scripts/argent-schedule.mjs +620 -0
  52. package/engine/scripts/argent-setup-check.mjs +369 -0
  53. package/engine/scripts/argent-upgrade.mjs +1046 -0
  54. package/engine/scripts/base-bootstrap.sh +575 -0
  55. package/engine/scripts/billing-mode-daily.sh +12 -0
  56. package/engine/scripts/build-engine-package.mjs +123 -0
  57. package/engine/scripts/capability-packs.lock.json +484 -0
  58. package/engine/scripts/capability_pack.py +1242 -0
  59. package/engine/scripts/check-1.0-criteria.mjs +355 -0
  60. package/engine/scripts/check-agent-catalog.mjs +141 -0
  61. package/engine/scripts/check-billing-mode.sh +377 -0
  62. package/engine/scripts/check-child-sessions.mjs +83 -0
  63. package/engine/scripts/check-config-catalog.mjs +677 -0
  64. package/engine/scripts/check-docs-drift.mjs +522 -0
  65. package/engine/scripts/check-dsh-web-expose.sh +98 -0
  66. package/engine/scripts/check-judgment-drift.mjs +403 -0
  67. package/engine/scripts/check-license.mjs +199 -0
  68. package/engine/scripts/check-model-auth.py +443 -0
  69. package/engine/scripts/check-pack-closure.mjs +661 -0
  70. package/engine/scripts/check-portable-symbols.mjs +116 -0
  71. package/engine/scripts/check-preset-landing.mjs +124 -0
  72. package/engine/scripts/check-production-home.mjs +602 -0
  73. package/engine/scripts/check-role-mapping.mjs +461 -0
  74. package/engine/scripts/check-sample-redaction.mjs +320 -0
  75. package/engine/scripts/check-skill-classification.mjs +188 -0
  76. package/engine/scripts/check-sop-consistency.mjs +431 -0
  77. package/engine/scripts/check-test-env-safety.mjs +627 -0
  78. package/engine/scripts/check-version-consistency.mjs +452 -0
  79. package/engine/scripts/ci-run.sh +558 -0
  80. package/engine/scripts/config-explain.mjs +278 -0
  81. package/engine/scripts/configure-provider.rb +29 -0
  82. package/engine/scripts/customer-config-migrate.mjs +179 -0
  83. package/engine/scripts/customer-preflight.py +892 -0
  84. package/engine/scripts/customer-readiness.sh +134 -0
  85. package/engine/scripts/daily-report-inbox.py +242 -0
  86. package/engine/scripts/daily-report-reconcile.mjs +312 -0
  87. package/engine/scripts/daily-report.mjs +1310 -0
  88. package/engine/scripts/daily-report.sh +46 -0
  89. package/engine/scripts/data/lip-product-dict.json +306 -0
  90. package/engine/scripts/deliver-customer.mjs +932 -0
  91. package/engine/scripts/delivery-faces.txt +31 -0
  92. package/engine/scripts/desktop-trial.sh +146 -0
  93. package/engine/scripts/dev-window.sh +260 -0
  94. package/engine/scripts/drill-clean-machine.sh +315 -0
  95. package/engine/scripts/dsh-api-client.mjs +215 -0
  96. package/engine/scripts/dsh-backup-scope.sh +83 -0
  97. package/engine/scripts/dsh-offline-pack.mjs +77 -0
  98. package/engine/scripts/dsh-overlay-pin.sh +87 -0
  99. package/engine/scripts/dsh-plane.mjs +153 -0
  100. package/engine/scripts/dsh-portforward.py +223 -0
  101. package/engine/scripts/dsh-preflight.mjs +179 -0
  102. package/engine/scripts/dsh-release-watch-daily.sh +19 -0
  103. package/engine/scripts/dsh-release-watch.mjs +458 -0
  104. package/engine/scripts/dsh-remote-check.sh +99 -0
  105. package/engine/scripts/dsh-restart.sh +179 -0
  106. package/engine/scripts/dsh-restore.sh +111 -0
  107. package/engine/scripts/dsh-scope-rewire.mjs +803 -0
  108. package/engine/scripts/dsh-snapshot.mjs +116 -0
  109. package/engine/scripts/dsh-upgrade-readiness.mjs +165 -0
  110. package/engine/scripts/dsh-upgrade.mjs +612 -0
  111. package/engine/scripts/dsh-url.sh +86 -0
  112. package/engine/scripts/dsh-web-launch.mjs +155 -0
  113. package/engine/scripts/ensure-store-windows.py +509 -0
  114. package/engine/scripts/entitlements.py +458 -0
  115. package/engine/scripts/env_probe.py +411 -0
  116. package/engine/scripts/feishu-card.mjs +252 -0
  117. package/engine/scripts/fix-skill-frontmatter.py +209 -0
  118. package/engine/scripts/flow-auto-retry.py +454 -0
  119. package/engine/scripts/flow-requirements.json +720 -0
  120. package/engine/scripts/flow-scaffold.py +275 -0
  121. package/engine/scripts/flow-timers-plist.sh +86 -0
  122. package/engine/scripts/flow-timers.sh +182 -0
  123. package/engine/scripts/flow-trigger-wake.mjs +284 -0
  124. package/engine/scripts/flow-trigger.sh +571 -0
  125. package/engine/scripts/flow_billing.py +354 -0
  126. package/engine/scripts/flow_capability_stats.py +314 -0
  127. package/engine/scripts/flow_case.py +194 -0
  128. package/engine/scripts/flow_claim.py +497 -0
  129. package/engine/scripts/flow_config.py +1024 -0
  130. package/engine/scripts/flow_failure.py +588 -0
  131. package/engine/scripts/flow_learn.py +105 -0
  132. package/engine/scripts/flow_ledger.py +235 -0
  133. package/engine/scripts/flow_policy.py +238 -0
  134. package/engine/scripts/flow_preflight.py +339 -0
  135. package/engine/scripts/flow_registry.py +341 -0
  136. package/engine/scripts/flow_retry.py +304 -0
  137. package/engine/scripts/flow_return_to_ops.py +191 -0
  138. package/engine/scripts/flow_source.py +315 -0
  139. package/engine/scripts/flow_sources/__init__.py +53 -0
  140. package/engine/scripts/flow_sources/cases_json.py +106 -0
  141. package/engine/scripts/flow_sources/common.py +428 -0
  142. package/engine/scripts/flow_sources/feishu_base.py +273 -0
  143. package/engine/scripts/flow_stale.py +185 -0
  144. package/engine/scripts/flow_status_reconcile.py +344 -0
  145. package/engine/scripts/flow_triage.py +849 -0
  146. package/engine/scripts/flow_write_verify.py +496 -0
  147. package/engine/scripts/fulfillment.js +586 -0
  148. package/engine/scripts/gen-agent-bundles.mjs +276 -0
  149. package/engine/scripts/gen-preset-rows.mjs +259 -0
  150. package/engine/scripts/init-ml.sh +2275 -0
  151. package/engine/scripts/install-internal-role.sh +190 -0
  152. package/engine/scripts/install-license.mjs +641 -0
  153. package/engine/scripts/install-one-shot.mjs +665 -0
  154. package/engine/scripts/integration_contract.py +220 -0
  155. package/engine/scripts/integrations/wenyao/adapter.py +98 -0
  156. package/engine/scripts/integrations/xzh/adapter.py +75 -0
  157. package/engine/scripts/invoice-mapping.example.json +40 -0
  158. package/engine/scripts/invoice-table.sh +194 -0
  159. package/engine/scripts/invoice_carrier_notice.py +279 -0
  160. package/engine/scripts/invoice_fail_closeout.py +297 -0
  161. package/engine/scripts/invoice_lip_runner.py +1508 -0
  162. package/engine/scripts/invoice_lip_runner.py.bak-20260922-1710-freready +1090 -0
  163. package/engine/scripts/invoice_ready_audit.py +191 -0
  164. package/engine/scripts/invoice_runner.py +675 -0
  165. package/engine/scripts/invoice_stageb.py +516 -0
  166. package/engine/scripts/launchd/com.whyshu.argent-bridge.plist.example +42 -0
  167. package/engine/scripts/launchd/com.whyshu.fulfillment-poll.plist.example +29 -0
  168. package/engine/scripts/lease.py +377 -0
  169. package/engine/scripts/lib/agent-install.mjs +649 -0
  170. package/engine/scripts/lib/argent-datadir.mjs +16 -0
  171. package/engine/scripts/lib/argent_datadir.py +262 -0
  172. package/engine/scripts/lib/argent_filelock.py +507 -0
  173. package/engine/scripts/lib/bootcheck-wiring.mjs +510 -0
  174. package/engine/scripts/lib/cdp_ports.py +197 -0
  175. package/engine/scripts/lib/customer-env.mjs +102 -0
  176. package/engine/scripts/lib/daily-report-core.mjs +517 -0
  177. package/engine/scripts/lib/dep-declaration.mjs +81 -0
  178. package/engine/scripts/lib/deps-migrate.mjs +310 -0
  179. package/engine/scripts/lib/dsh-host-resolve.mjs +109 -0
  180. package/engine/scripts/lib/dsh-scope.mjs +500 -0
  181. package/engine/scripts/lib/dsh-snapshot-path.mjs +35 -0
  182. package/engine/scripts/lib/dsh-versions.mjs +96 -0
  183. package/engine/scripts/lib/dsh-web-probe.mjs +214 -0
  184. package/engine/scripts/lib/is-direct-run.mjs +61 -0
  185. package/engine/scripts/lib/patch-compose.mjs +241 -0
  186. package/engine/scripts/lib/patch-target.mjs +35 -0
  187. package/engine/scripts/lib/plugin-lifecycle.mjs +128 -0
  188. package/engine/scripts/lib/plugin-packages.mjs +332 -0
  189. package/engine/scripts/lib/preset-compat.mjs +127 -0
  190. package/engine/scripts/lib/preset-install.mjs +575 -0
  191. package/engine/scripts/lib/preset-mechanism.mjs +56 -0
  192. package/engine/scripts/lib/preset-sync.mjs +59 -0
  193. package/engine/scripts/lib/profile-retire.mjs +97 -0
  194. package/engine/scripts/lib/python-runtime.mjs +190 -0
  195. package/engine/scripts/lib/registry.mjs +72 -0
  196. package/engine/scripts/lib/repo-root.sh +56 -0
  197. package/engine/scripts/lib/schedule-mechanism.mjs +659 -0
  198. package/engine/scripts/lib/schedule-probe.mjs +835 -0
  199. package/engine/scripts/lib/scope-pointer.mjs +164 -0
  200. package/engine/scripts/lib/settings-panels.mjs +816 -0
  201. package/engine/scripts/lib/stdio_utf8.py +86 -0
  202. package/engine/scripts/lib/wake-auth.mjs +392 -0
  203. package/engine/scripts/lib/webdriver_ipc.py +264 -0
  204. package/engine/scripts/lib/zstd-frames.mjs +104 -0
  205. package/engine/scripts/license-e2e-drill.mjs +426 -0
  206. package/engine/scripts/license-gate.mjs +245 -0
  207. package/engine/scripts/lip_backlog.py +171 -0
  208. package/engine/scripts/lip_table.py +185 -0
  209. package/engine/scripts/local-usage.mjs +214 -0
  210. package/engine/scripts/migrate-providers.mjs +127 -0
  211. package/engine/scripts/migrate-skills.sh +65 -0
  212. package/engine/scripts/ml-oauth-setup.mjs +550 -0
  213. package/engine/scripts/ml-store-ids.json +26 -0
  214. package/engine/scripts/ml_artifact_attribution.py +333 -0
  215. package/engine/scripts/ml_capacity_probe.py +1158 -0
  216. package/engine/scripts/ml_hub_status.py +1556 -0
  217. package/engine/scripts/ml_schema_check.py +115 -0
  218. package/engine/scripts/ml_store_ids.py +139 -0
  219. package/engine/scripts/npm-publish-argent.mjs +499 -0
  220. package/engine/scripts/npm-publish-argent.sh +20 -0
  221. package/engine/scripts/orchestrator.py +13811 -0
  222. package/engine/scripts/pack-plugins.mjs +140 -0
  223. package/engine/scripts/patches/dsh-llm-deepseek--transport-diagnostics.patch +297 -0
  224. package/engine/scripts/patches/dsh-session--append-message-shape.patch +15 -0
  225. package/engine/scripts/patches/dsh-session--tool-result-block-017.patch +28 -0
  226. package/engine/scripts/patches/dsh-session-format-v0-to-v1--permission-preset-origin.patch +11 -0
  227. package/engine/scripts/patches/dsh-session-format-v3-to-v4--turn-outside-replace.patch +20 -0
  228. package/engine/scripts/patches/dsh-session-persistence-jsonl--worker-bundled-migrators.patch +39 -0
  229. package/engine/scripts/patches/dsh-tools--render-return-shape.patch +50 -0
  230. package/engine/scripts/patches/verify-bundled-migrators.mjs +79 -0
  231. package/engine/scripts/patches/verify-hardening.mjs +167 -0
  232. package/engine/scripts/patches/verify-session-migration.mjs +149 -0
  233. package/engine/scripts/patches/verify-transport-diagnostics.mjs +227 -0
  234. package/engine/scripts/plan-role-rename.mjs +125 -0
  235. package/engine/scripts/plugin-bootcheck.mjs +451 -0
  236. package/engine/scripts/plugin-composition.json +15 -0
  237. package/engine/scripts/poc-mcp-host.mjs +455 -0
  238. package/engine/scripts/poll-fulfillment.sh +293 -0
  239. package/engine/scripts/poll-invoice.sh +74 -0
  240. package/engine/scripts/profile-doctor.mjs +686 -0
  241. package/engine/scripts/provider-select.sh +70 -0
  242. package/engine/scripts/provider-switch.sh +146 -0
  243. package/engine/scripts/provider-sync-target.check.mjs +64 -0
  244. package/engine/scripts/python-runtime.sh +78 -0
  245. package/engine/scripts/query_runner.py +310 -0
  246. package/engine/scripts/release-argent.sh +574 -0
  247. package/engine/scripts/repair-unresolved-tools.mjs +178 -0
  248. package/engine/scripts/run-tests.sh +256 -0
  249. package/engine/scripts/self-sign-license.mjs +179 -0
  250. package/engine/scripts/session-health-scan.mjs +63 -0
  251. package/engine/scripts/session-repair-tool-result-content.mjs +181 -0
  252. package/engine/scripts/setup.sh +22 -0
  253. package/engine/scripts/skill-install.mjs +629 -0
  254. package/engine/scripts/sku_translate.py +148 -0
  255. package/engine/scripts/sync-plugins.sh +90 -0
  256. package/engine/scripts/sync-presets.sh +27 -0
  257. package/engine/scripts/sync-scripts.sh +445 -0
  258. package/engine/scripts/telemetry.py +873 -0
  259. package/engine/scripts/ui-copy-count.mjs +220 -0
  260. package/engine/scripts/usage-anchor.sh +136 -0
  261. package/engine/scripts/usage_report.py +531 -0
  262. package/engine/scripts/validate-preset-schema.mjs +208 -0
  263. package/engine/scripts/vertical-init.mjs +323 -0
  264. package/engine/scripts/vertical-lint.mjs +482 -0
  265. package/engine/scripts/wenyao-browser.sh +73 -0
  266. package/engine/scripts/wenyao-fixture-export.py +116 -0
  267. package/engine/scripts/wenyao-invoice-writeback.mjs +540 -0
  268. package/engine/scripts/wenyao-login.sh +34 -0
  269. package/engine/scripts/wenyao-template-map.json +292 -0
  270. package/engine/scripts/wenyao_attach.py +131 -0
  271. package/engine/scripts/wenyao_download_template.py +144 -0
  272. package/engine/scripts/wenyao_fill_template.py +568 -0
  273. package/engine/scripts/wenyao_login.py +145 -0
  274. package/engine/scripts/wenyao_portal.py +633 -0
  275. package/engine/scripts/wenyao_recon.py +230 -0
  276. package/engine/scripts/wenyao_run.py +503 -0
  277. package/engine/scripts/wenyao_shadow_diff.py +160 -0
  278. package/engine/scripts/wenyao_skill_contract.py +156 -0
  279. package/engine/scripts/wenyao_template_fetch.py +175 -0
  280. package/engine/scripts/win/dsh-web-autostart.ps1 +372 -0
  281. package/engine/scripts/ziniao-auth-probe.sh +268 -0
  282. package/engine/scripts/ziniao-keepalive.sh +216 -0
  283. package/engine/scripts/ziniao-post-upgrade-check.sh +120 -0
  284. package/engine/scripts/ziniao-windows.sh +153 -0
  285. package/engine/version.mjs +1 -0
  286. package/engine/verticals/README.md +103 -0
  287. package/engine/verticals/_engine-words.baseline.txt +237 -0
  288. package/engine/verticals/_engine-words.json +19 -0
  289. package/engine/verticals/mercadolibre/README.md +43 -0
  290. package/engine/verticals/mercadolibre/config.json +709 -0
  291. package/engine/verticals/mercadolibre/flows.json +706 -0
  292. package/engine/verticals/mercadolibre/manifest.json +538 -0
  293. package/engine/verticals/mercadolibre/migrate-machine-state.mjs +138 -0
  294. package/engine/verticals/mercadolibre/preflight.py +143 -0
  295. package/engine/verticals/mercadolibre/prompts/daily-report.failure.md +69 -0
  296. package/engine/verticals/mercadolibre/prompts/daily-report.md +47 -0
  297. package/engine/verticals/mercadolibre/prompts/daily-report.scheduled.md +79 -0
  298. package/engine/verticals/mercadolibre/prompts/full.failure.md +125 -0
  299. package/engine/verticals/mercadolibre/prompts/full.md +91 -0
  300. package/engine/verticals/mercadolibre/prompts/wenyao-invoice.failure.md +88 -0
  301. package/engine/verticals/mercadolibre/prompts/wenyao-invoice.md +64 -0
  302. package/engine/verticals/mercadolibre/prompts/xzh-invoice.failure.md +91 -0
  303. package/engine/verticals/mercadolibre/prompts/xzh-invoice.md +46 -0
  304. package/package.json +21 -4
  305. package/README.md +0 -3
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * session 全面体检(dry-run):用当前 dsh 的 adoptSessionEvent 逐事件校验,
4
+ * **不 fail-fast**,列出全部不合格事件 + 上下文。用于评估一个会话的"修复面"。
5
+ * 用法:node scripts/session-health-scan.mjs <解压后的session.jsonl>
6
+ */
7
+ import { readFileSync } from 'node:fs'
8
+ import { requireDshScope } from './lib/dsh-scope.mjs'
9
+
10
+ // 0.6.0 F1 修复批(2026-10-14):体检**必须**在真宿主树上跑 ⇒ 拿不到 scope 就响亮失败
11
+ // (⛔ 不用 passthrough 假路径继续 —— 旧写法在 npx 宿主上会 import 一个不存在的树)。
12
+ let SCOPE
13
+ try { SCOPE = requireDshScope({ what: '会话体检(session-health-scan)' }) }
14
+ catch (e) { console.error(` ❌ ${e.message}`); process.exit(1) }
15
+ const { adoptSessionEvent, foldSurface } = await import(`${SCOPE}/dsh-session/lib/index.js`)
16
+
17
+ const file = process.argv[2]
18
+ if (!file) { console.error('用法: node scripts/session-health-scan.mjs <session.jsonl>'); process.exit(1) }
19
+
20
+ const lines = readFileSync(file, 'utf8').split('\n').filter((l) => l.trim())
21
+ const parsed = lines.map((l) => JSON.parse(l))
22
+ // 存储态日志第一行是 header(无 type),事件本身**不带 seq**(位置即序号)。
23
+ // foldSurface 要求 seq 连续 ⇒ 这里去掉 header 行、按行号补 seq(2026-09-29 修:
24
+ // 原实现直接把 parsed 喂给 foldSurface,一律报 "seq undefined is not contiguous")。
25
+ // header 行的形态实测是 `{type:'session', version:N, id, createdAt}`(**type 是字符串**,
26
+ // 且**没有 seq**)——别用"type 不是字符串"来认它(2026-09-29 实测踩过)。
27
+ const header = parsed[0] && (parsed[0].type === 'session' || typeof parsed[0].seq !== 'number') ? parsed[0] : null
28
+ const events = (header ? parsed.slice(1) : parsed).map((ev, i) => (
29
+ typeof ev.seq === 'number' ? ev : { ...ev, seq: i }
30
+ ))
31
+ if (header) console.log(`header: version=${header.version ?? '?'} id=${String(header.id || '').slice(0, 24)}`)
32
+ console.log(`总事件: ${events.length}`)
33
+
34
+ const bad = []
35
+ for (const [i, ev] of events.entries()) {
36
+ try {
37
+ adoptSessionEvent(structuredClone(ev))
38
+ } catch (e) {
39
+ bad.push({ idx: i, seq: ev.seq, type: ev.type, err: e.message.slice(0, 160) })
40
+ }
41
+ }
42
+
43
+ console.log(`\n=== 不合格事件: ${bad.length} 个 ===`)
44
+ for (const b of bad.slice(0, 40)) {
45
+ console.log(` idx=${b.idx} seq=${b.seq} type=${b.type}`)
46
+ console.log(` → ${b.err}`)
47
+ }
48
+ if (bad.length > 40) console.log(` …还有 ${bad.length - 40} 个`)
49
+
50
+ // 再跑 foldSurface(引用完整性)
51
+ try {
52
+ foldSurface(events.map((e) => structuredClone(e)))
53
+ console.log('\n✅ foldSurface(surface 折叠)通过')
54
+ } catch (e) {
55
+ console.log(`\n❌ foldSurface 失败: ${e.message.slice(0, 200)}`)
56
+ }
57
+
58
+ // 统计问题类型
59
+ import { createHash } from 'node:crypto'
60
+ const byType = {}
61
+ for (const b of bad) { const k = `${b.type}: ${b.err.slice(0, 60)}`; byType[k] = (byType[k] || 0) + 1 }
62
+ console.log('\n=== 问题分类 ===')
63
+ for (const [k, v] of Object.entries(byType).sort((a, b) => b[1] - a[1])) console.log(` ${v}× ${k}`)
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * 会话修复器:把 tool/result 事件里 content 为**非数组**的 tool-result block 改写成
4
+ * ContentBlock 数组(`[{type:'text',text}]`),让被毒化的会话重新可加载。
5
+ *
6
+ * ## 为什么需要它(2026-09-18 事故)
7
+ * 插件工具的 `output.render` 返回裸字符串 ⇒ dsh-tools 把 render 返回值**直接**当作
8
+ * tool-result 的 content ⇒ 会话日志里落一条 `content:"…"`。运行中的会话不会立刻发现
9
+ * (surface 折叠只读内容),但**从磁盘加载时会跑 schema 校验**:
10
+ * `dsh-session` → `assertMessageEventShape()` → "message must contain one tool-result block"
11
+ * ⇒ 该会话**打不开**(Failed to load history: … is corrupt)。
12
+ * **surface replace 救不了它** —— 校验针对**事件本身**,不是 surface 视图(2026-09-18 实测踩过)。
13
+ *
14
+ * ## 安全设计(改这段代码前务必读完)
15
+ * ① 会话日志是**多帧 zstd**,dsh **逐帧校验**、且**首帧是 header 行、必须恰好一行**
16
+ * ⇒ **绝不整体重压成单帧**;只重写"包含目标事件的那一帧",其余帧字节**原样保留**。
17
+ * ② 帧边界 = 扫描 zstd magic + 逐切片试解压(压缩数据里偶发假 magic,解不出来的自动并入前一帧)。
18
+ * ③ 只改目标 block 的 content;该行以外的所有行保持**原字节**(逐行比对验收)。
19
+ * ④ 写盘前用 **dsh 自己的校验器**终验:`adoptSessionEvent()`(逐事件 schema)+ `foldSurface()`(surface 折叠)。
20
+ * ⑤ 先写 `.tmp` 校验通过再 `rename` 原子替换;调用方负责先备份(默认 dry-run,不加 `--apply` 不落盘)。
21
+ * ⑥ **改之前先确认目标会话没有被运行中的服务打开**(否则会与服务写入竞争)。
22
+ *
23
+ * ## 用法
24
+ * # 扫描所有会话,只报告(默认 dry-run)
25
+ * node scripts/session-repair-tool-result-content.mjs --scan
26
+ * # 扫描并修复(原子替换,建议先停掉/别打开这些会话)
27
+ * node scripts/session-repair-tool-result-content.mjs --scan --apply
28
+ * # 只处理指定会话(id 或 session 文件路径)
29
+ * node scripts/session-repair-tool-result-content.mjs --session session-06732069-... [--apply]
30
+ */
31
+ import { readFileSync, writeFileSync, renameSync, existsSync, readdirSync, statSync } from 'node:fs'
32
+ import { zstdCompressSync } from 'node:zlib'
33
+ import { FRAME_COMPRESS_OPTS, decodeSessionLines, splitFrames as splitFramesImpl } from './lib/zstd-frames.mjs'
34
+ import { join } from 'node:path'
35
+ import { homedir } from 'node:os'
36
+ import { requireDshScope } from './lib/dsh-scope.mjs'
37
+
38
+ const argv = process.argv.slice(2)
39
+ const APPLY = argv.includes('--apply')
40
+ const SCAN = argv.includes('--scan') || !argv.includes('--session')
41
+ const sessionArg = (() => { const i = argv.indexOf('--session'); return i === -1 ? null : argv[i + 1] })()
42
+ // 0.6.0 F1 修复批(2026-10-14):**必须**有 scope 才能干活 ⇒ 拿不到就响亮失败(⛔ 不用假路径继续)。
43
+ // 旧写法 `const SCOPE = resolveDshScope()` 在 npx 宿主上会拿到一个**不存在**的路径 ⇒ 下面那条
44
+ // 动态 import 报 ERR_MODULE_NOT_FOUND(看着像"dsh 坏了",其实是探错树)。
45
+ let SCOPE
46
+ try { SCOPE = requireDshScope({ what: '会话修复(session-repair-tool-result-content)' }) }
47
+ catch (e) { console.error(` ❌ ${e.message}`); process.exit(1) }
48
+ const DSH_HOME = process.env.DSH_HOME || join(homedir(), '.dsh')
49
+
50
+ const { adoptSessionEvent, foldSurface } = await import(`${SCOPE}/dsh-session/lib/index.js`)
51
+
52
+ const MAGIC = Buffer.from([0x28, 0xb5, 0x2f, 0xfd])
53
+ // 与 dsh 写帧参数一致(常量也放共享库里,避免本地副本再次漂移)
54
+ const CHECKSUM = FRAME_COMPRESS_OPTS
55
+
56
+ let pass = 0, fail = 0
57
+ const ok = (c, n) => { c ? (pass++, console.log(` ✅ ${n}`)) : (fail++, console.log(` ❌ ${n}`)) }
58
+
59
+ // 切帧/解码实现见 lib/zstd-frames.mjs(与升级门禁共用一份;本文件此前是它的唯一副本)
60
+ const splitFrames = (buf) => splitFramesImpl(buf)
61
+ const decodeLines = (buf) => {
62
+ const { frames, lines } = decodeSessionLines(buf)
63
+ return { frames, lines }
64
+ }
65
+
66
+ /** 用 dsh 自己的校验器验收(逐事件 schema + surface 折叠)。 */
67
+ function validateWithDsh(lines) {
68
+ const events = lines.map((l) => JSON.parse(l.raw))
69
+ for (const [i, ev] of events.entries()) {
70
+ if (ev.seq !== i) throw new Error(`事件下标 ${i} 与 seq ${ev.seq} 不一致`)
71
+ adoptSessionEvent(structuredClone(ev))
72
+ }
73
+ const fold = foldSurface(events.map((e) => structuredClone(e)))
74
+ const bad = fold.nodes.filter((q) => {
75
+ const ev = events[q]
76
+ return ev.type === 'tool/result' && !Array.isArray(ev.data.message.content[0].content)
77
+ })
78
+ return { events: events.length, surfaceNodes: fold.nodes.length, badSurfaceContent: bad.length }
79
+ }
80
+
81
+ /** 找出全部非法 tool-result(content 非数组)。 */
82
+ function findPoison(lines) {
83
+ const hits = []
84
+ for (const line of lines) {
85
+ if (!line.raw.includes('"tool/result"')) continue
86
+ let ev
87
+ try { ev = JSON.parse(line.raw) } catch { continue }
88
+ if (ev.type !== 'tool/result') continue
89
+ const block = ev.data?.message?.content?.[0]
90
+ if (block?.type !== 'tool-result' || Array.isArray(block.content)) continue
91
+ hits.push({ line, ev, block })
92
+ }
93
+ return hits
94
+ }
95
+
96
+ function repairFile(path) {
97
+ console.log('='.repeat(74))
98
+ console.log(path)
99
+ const buf = readFileSync(path)
100
+ const { frames, lines } = decodeLines(buf)
101
+ const hits = findPoison(lines)
102
+ const health = validateWithDsh(lines)
103
+ console.log(` 帧 ${frames.length} 个|事件行 ${lines.length}|非法 tool-result ${hits.length} 条`)
104
+ if (hits.length === 0) {
105
+ ok(health.badSurfaceContent === 0 && health.events === lines.length,
106
+ `dsh 校验通过,无需修复(事件 ${health.events}|surface 节点 ${health.surfaceNodes}|非数组 content ${health.badSurfaceContent})`)
107
+ return { repaired: 0 }
108
+ }
109
+
110
+ const touchedFrames = new Set()
111
+ for (const { line, ev, block } of hits) {
112
+ const wasKind = Array.isArray(block.content) ? 'array' : typeof block.content
113
+ const text = typeof block.content === 'string' ? block.content : JSON.stringify(block.content)
114
+ block.content = [{ type: 'text', text }]
115
+ line.raw = JSON.stringify(ev)
116
+ touchedFrames.add(line.frame)
117
+ console.log(` 🔧 seq ${ev.seq}(turn ${ev.data.turn} step ${ev.data.step}):content ${wasKind} → ContentBlock[](帧 ${line.frame})`)
118
+ }
119
+
120
+ const rebuilt = new Map()
121
+ for (const f of touchedFrames) {
122
+ const raws = lines.filter((l) => l.frame === f).map((l) => l.raw)
123
+ rebuilt.set(f, zstdCompressSync(Buffer.from(raws.join('\n') + '\n', 'utf8'), CHECKSUM))
124
+ }
125
+ const out = Buffer.concat(frames.map((fr, i) => rebuilt.get(i) ?? buf.subarray(fr.start, fr.end)))
126
+
127
+ // 验收:结构 + dsh 校验器 + 未改动行逐字节一致
128
+ const redecoded = decodeLines(out)
129
+ const verdict = validateWithDsh(redecoded.lines)
130
+ const fixedSeqs = new Set(hits.map((h) => h.ev.seq))
131
+ const differ = redecoded.lines.map((l, i) => i).filter((i) => {
132
+ const seq = JSON.parse(lines[i].raw).seq
133
+ return !fixedSeqs.has(seq) && lines[i].raw !== redecoded.lines[i].raw
134
+ })
135
+ ok(verdict.badSurfaceContent === 0, `dsh 校验器通过(事件 ${verdict.events}|surface 节点 ${verdict.surfaceNodes}|surface 上非数组 content ${verdict.badSurfaceContent})`)
136
+ ok(differ.length === 0, `除目标行外逐字节一致${differ.length ? `(差异行 ${differ.slice(0, 5)})` : ''}`)
137
+ if (verdict.badSurfaceContent > 0 || differ.length > 0) { fail++; console.log(' ❌ 验收未通过,不写盘'); return { repaired: 0 } }
138
+
139
+ const tmp = `${path}.repair.tmp`
140
+ writeFileSync(tmp, out)
141
+ if (APPLY) { renameSync(tmp, path); console.log(` ✅ 已原子替换(${buf.length} → ${out.length} 字节)`) }
142
+ else console.log(` (dry-run:已写出 ${tmp},未替换原文件;加 --apply 生效)`)
143
+ return { repaired: hits.length }
144
+ }
145
+
146
+ /** 收集目标文件。 */
147
+ let files = []
148
+ if (sessionArg) {
149
+ if (existsSync(sessionArg)) files = [sessionArg]
150
+ else {
151
+ const root = join(DSH_HOME, 'sessions')
152
+ for (const ws of readdirSync(root)) {
153
+ const p = join(root, ws, sessionArg, 'session.v3.jsonl.zstd')
154
+ if (existsSync(p)) files.push(p)
155
+ }
156
+ if (files.length === 0) { console.error(`❌ 找不到会话 ${sessionArg}`); process.exit(1) }
157
+ }
158
+ } else if (SCAN) {
159
+ const root = join(DSH_HOME, 'sessions')
160
+ for (const ws of readdirSync(root)) {
161
+ const wsDir = join(root, ws)
162
+ if (!statSync(wsDir).isDirectory()) continue
163
+ for (const id of readdirSync(wsDir)) {
164
+ const p = join(wsDir, id, 'session.v3.jsonl.zstd')
165
+ if (existsSync(p)) files.push(p)
166
+ }
167
+ }
168
+ }
169
+
170
+ console.log(`扫描 ${files.length} 个会话文件${APPLY ? '(--apply:会写盘)' : '(dry-run:只报告,不改文件)'}\n`)
171
+ let total = 0
172
+ for (const f of files) {
173
+ try { total += repairFile(f).repaired } catch (err) { console.log(` ❌ ${f}: ${err.message}`); fail++ }
174
+ }
175
+
176
+ console.log('\n' + '='.repeat(74))
177
+ console.log(`合计需要修复的 tool-result:${total} 条|校验通过 ${pass} / 失败 ${fail}`)
178
+ if (fail > 0) process.exit(1)
179
+ if (total === 0) console.log('✅ 没有发现被毒化的会话')
180
+ else if (!APPLY) console.log('✅ dry-run 完成;确认无误后加 --apply 落盘(记得先备份)')
181
+ else console.log('✅ 修复完成:这些会话现在可以正常加载了')
@@ -0,0 +1,22 @@
1
+ #!/bin/bash
2
+ # ============================================================
3
+ # setup.sh — ML 卖家角色初始化(薄封装)
4
+ # 核心逻辑已迁移到 init-ml.sh(同目录),本脚本保持向后兼容:
5
+ # 老用户执行 setup.sh 等效于执行 init-ml.sh
6
+ #
7
+ # 用法:
8
+ # setup.sh 完整初始化(等价 init-ml.sh)
9
+ # setup.sh --refresh-stores 仅刷新店铺选项
10
+ # setup.sh --reconfig 强制重新配置
11
+ # ============================================================
12
+ set -euo pipefail
13
+
14
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
+ INIT_ML="$SCRIPT_DIR/init-ml.sh"
16
+
17
+ if [ ! -f "$INIT_ML" ]; then
18
+ echo "✗ 未找到 init-ml.sh(${INIT_ML}),请确认脚本完整分发" >&2
19
+ exit 1
20
+ fi
21
+
22
+ exec bash "$INIT_ML" "$@"