@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,284 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * flow-trigger-wake —— 唤醒**任意流程**的角色会话并投递「本轮任务」(定时触发的执行端)。
4
+ *
5
+ * 引擎泛化版(P0 · 2026-09-16):本脚本**不认识任何具体流程**。
6
+ * preset / cwd / 提示词模板 / 日志 / 会话复用文件 全部来自注册表
7
+ * (`flow_config.py --flow <id> --json` ← `flow-requirements.json#flows.<id>`)。
8
+ * 加一条流程 = 注册表加一条 + 一份 `scripts/flow-prompts/<id>.md`,不改本脚本。
9
+ *
10
+ * RPC 形状来自实测(会话/提示词端点,见 `docs/dsh-api-protocol.md`):
11
+ * session/create {request:{agentPreset, cwd}} → {result:{value:{sessionId}}}
12
+ * session/prompt {request:{requestId, sessionId, mode:'queue', content:[{type:'text',text}]}}
13
+ *
14
+ * **会话复用**(2026-09-16 修):旧版每轮 `session/create` ⇒ 会话数无限膨胀(已 136+)。
15
+ * 现在把 sessionId 落盘(`paths.sessionIdFile`),下轮直接 `session/prompt` 复用;
16
+ * 若该会话已不可用(RPC 报错)⇒ 自动新建并改写该文件。
17
+ *
18
+ * 两种模式:
19
+ * · 定时派单(默认):--tickets a,b
20
+ * · **失败交接(P0.6)**:--reason failure --case <caseId> [--attempt N] [--error "摘要"]
21
+ * ⇒ 渲染 <flow>.failure.md,唤醒掌舵者判断「重试 / 等人 / 升级」
22
+ * 用法:node scripts/flow-trigger-wake.mjs --flow <id> --tickets a,b [--max 2] [--dry-run] [--base URL]
23
+ * 退出码:0 成功(含 dry-run);2 配置/鉴权/RPC 失败
24
+ *
25
+ * **鉴权来源链(2026-10-08 加固)**:不再只认 `/tmp/dsh-web.log`(那是一次静默故障的根因:
26
+ * 该文件被系统清理后唤醒 exit 2,而台账/遥测里一条失败都没有)。现在按优先级试多个来源
27
+ * (显式 token 文件 → **凭据里的 browser-session 密钥现签 cookie,不依赖 /tmp** → DSH_WEB_LOG
28
+ * → plist 的 StandardOutPath → 稳定目录候选 → /tmp 兜底),每个来源**先验后用**;
29
+ * 全部失败 ⇒ 文案点名每个来源 + 可执行修法,并写台账 `blocked`(by=flow-wake)+ 遥测。
30
+ * 唯一实现:`scripts/lib/wake-auth.mjs`(含来源表与失败文案)。
31
+ */
32
+ import { readFileSync, writeFileSync, appendFileSync, mkdirSync } from 'node:fs'
33
+ import { execFileSync } from 'node:child_process'
34
+ import { dirname, join } from 'node:path'
35
+ import { fileURLToPath } from 'node:url'
36
+ import { homedir } from 'node:os'
37
+ // 鉴权来源链的唯一实现(多来源 + 优先级 + 失败文案)——见该文件头的事故记录
38
+ import { authSources, acquireWakeAuth, authFailureText, SOURCE_STATUS_ZH } from './lib/wake-auth.mjs'
39
+
40
+ const SCRIPTS = dirname(fileURLToPath(import.meta.url))
41
+ const arg = (n, d) => { const i = process.argv.indexOf(n); return i > 0 ? process.argv[i + 1] : d }
42
+ const FLOW = arg('--flow', 'wenyao-invoice')
43
+ const BASE = arg('--base', 'http://127.0.0.1:3080')
44
+ const DRY = process.argv.includes('--dry-run')
45
+ const NOTICE = arg('--notice', '')
46
+ const TICKETS = (arg('--tickets', '') || '').split(',').map((x) => x.trim()).filter(Boolean)
47
+ // P0.6:失败交接模式 —— 引擎(argent-flow 的失败回路)发现"需要判断"的失败时用这个模式唤醒角色
48
+ const REASON = arg('--reason', 'tickets')
49
+ const CASE = arg('--case', '')
50
+ const ATTEMPT = arg('--attempt', '')
51
+ const ERROR = arg('--error', '')
52
+ // 2026-09-18:reason=ruling 用 —— 用户对 blocked 票的裁定原文(逐字转达,勿改写)
53
+ const NOTE = arg('--note', '')
54
+ const PY = (process.env.ARGENT_PY || `${process.env.DSH_HOME || `${process.env.HOME}/.dsh`}/argent/venv/bin/python3`)
55
+ const CLONE = process.env.ARGENT_DISH_HOME || join(homedir(), '.argent-dsh')
56
+ const REGISTRY = arg('--registry', '') // 覆盖流程注册表(测试/多部署用)
57
+ const REG_ARGS = REGISTRY ? ['--registry', REGISTRY] : []
58
+
59
+ // ── 失败信号(2026-10-08):唤醒端此前**只** exit 2 ⇒ 定时器"看着正常"、活没人干 ──
60
+ // 事故:/tmp/dsh-web.log 被系统清理 ⇒ `❌ 取不到 token` ⇒ exit 2 ⇒ 该轮角色会话没起、
61
+ // 表没生成、没推送,**而台账/遥测里一条失败都没有**(静默故障,靠人肉比对才发现)。
62
+ // 现在:任何失败路径都必须留一条**既有通道**上的痕迹(台账 blocked by=flow-wake + 遥测 engine 事件),
63
+ // 且信号写入**尽力而为**(try/catch,语义同 `|| true`):写不进去只告警,绝不掩盖原始错误、
64
+ // 也不改变判定与退出码。
65
+ function signalFailure(detail) {
66
+ const d = String(detail).slice(0, 280)
67
+ let ledger
68
+ try { ledger = cfg && cfg.paths && cfg.paths.ledger } catch { ledger = undefined }
69
+ try {
70
+ execFileSync(PY, [join(SCRIPTS, 'flow_ledger.py'), ...(ledger ? ['--ledger', ledger] : []),
71
+ '--case-id', `wake__${FLOW}`, '--event', 'blocked', '--by', 'flow-wake', '--detail', d],
72
+ { encoding: 'utf8', timeout: 20000, stdio: ['ignore', 'ignore', 'ignore'] })
73
+ } catch (e) {
74
+ console.error(`[flow-wake] ⚠️ 台账 blocked 写入失败(不影响判定):${String(e.stderr || e.message).trim().slice(0, 200)}`)
75
+ }
76
+ try {
77
+ execFileSync(PY, [join(SCRIPTS, 'telemetry.py'), '--emit', '--kind', 'engine', '--flow', FLOW,
78
+ '--error-class', 'needs_human', '--detail', d], { encoding: 'utf8', timeout: 20000, stdio: ['ignore', 'ignore', 'ignore'] })
79
+ execFileSync(PY, [join(SCRIPTS, 'telemetry.py'), '--flush'], { encoding: 'utf8', timeout: 20000, stdio: ['ignore', 'ignore', 'ignore'] })
80
+ } catch (e) {
81
+ console.error(`[flow-wake] ⚠️ 遥测上报未完成(不影响判定):${String(e.stderr || e.message).trim().slice(0, 200)}`)
82
+ }
83
+ }
84
+
85
+ // ── 流程配置(唯一读取点;未知流程由 flow_config.py 以 exit 2 拒绝)──
86
+ let cfg
87
+ try {
88
+ cfg = JSON.parse(execFileSync(PY, [join(SCRIPTS, 'flow_config.py'), '--flow', FLOW, '--json', ...REG_ARGS], { encoding: 'utf8' }))
89
+ } catch (e) {
90
+ const m = `读取流程配置失败:${String(e.stderr || e.message).trim()}`
91
+ console.error(`❌ ${m}`)
92
+ signalFailure(m)
93
+ process.exit(2)
94
+ }
95
+ const MAX = Number(arg('--max', '0')) || cfg.concurrency.max
96
+ // 2026-09-18:本轮语义来自注册表 trigger.mode(缺省 shadow)—— 日志如实播报,
97
+ // 不再把"影子模式"写死(FULL 转真实运行后,写死会让操作者误判)。
98
+ const MODE_LABEL = cfg.trigger.mode === 'real' ? '真实写入' : '影子(零副作用)'
99
+ const LOG = cfg.paths.log
100
+ const log = (m) => {
101
+ const line = `[${new Date().toISOString()}] ${m}`
102
+ try { mkdirSync(dirname(LOG), { recursive: true }); appendFileSync(LOG, line + '\n') } catch {}
103
+ console.log(m)
104
+ }
105
+
106
+ /**
107
+ * **响亮失败**(本文件的唯一失败出口;exit 2 语义不变)。
108
+ * 三段都做:① 流程日志 + stdout 的 ❌ 文案(含可执行修法);② **stderr 显著 warn**
109
+ * (launchd 的 StandardErrorPath 也收得到);③ 台账 blocked(by=flow-wake)+ 遥测(见 signalFailure)。
110
+ * 为什么必须这样:客户机上没人看日志,**只有台账/遥测/飞书**是观测面 —— 静默 = 事故。
111
+ */
112
+ function failWake(msg, detail = msg) {
113
+ const text = `❌ ${msg}`
114
+ log(text)
115
+ console.error(`[flow-wake] ${text}`)
116
+ signalFailure(detail)
117
+ process.exit(2)
118
+ }
119
+ // 兜底:本文件里任何**没被显式接住**的异常(fetch 网络错、RPC 抛错…)也走同一条失败通道,
120
+ // 否则 Node 只打一段栈就 exit 1 —— 观测面上仍是"什么都没发生"。
121
+ process.on('unhandledRejection', (e) => failWake(`唤醒异常(未捕获的 Promise 拒绝):${(e && (e.message || e)) || e}`))
122
+ process.on('uncaughtException', (e) => failWake(`唤醒异常(未捕获):${(e && (e.message || e)) || e}`))
123
+
124
+ // ── 提示词模板 ──────────────────────────────────────────────────
125
+ const TPL_PATH = REASON === 'failure'
126
+ ? cfg.paths.promptTemplate.replace(/\.md$/, '.failure.md')
127
+ : cfg.paths.promptTemplate
128
+ // 2026-09-18 新增 reason=ruling:把**用户对 blocked 票的裁定**回传给掌舵者去执行。
129
+ // 为什么不套模板:裁定是"人对人"的短指令(如"保留货件号续跑,不清号"),塞进几百行长 SOP 里
130
+ // 会被淹没;角色此刻缺的不是流程知识(它已经判过一次 blocked),而是**人拍板的那句话**。
131
+ const RULING = REASON === 'ruling'
132
+ let tpl = ''
133
+ if (!RULING) {
134
+ try {
135
+ tpl = readFileSync(TPL_PATH, 'utf8')
136
+ } catch {
137
+ failWake(`缺提示词模板:${TPL_PATH}(每条流程一份;失败交接模板命名 <flow>.failure.md)`,
138
+ `缺提示词模板 ${TPL_PATH}`)
139
+ }
140
+ }
141
+ const vars = {
142
+ flow: FLOW,
143
+ flowTitle: cfg.title,
144
+ tickets: TICKETS.length ? TICKETS.join('、') : `(无认领清单:请自行从 to_dispatch 取最多 ${MAX} 张)`,
145
+ ticketsCsv: TICKETS.join(','),
146
+ max: String(MAX),
147
+ cloneScripts: join(CLONE, 'scripts'),
148
+ // 2026-09-17:解释器要显式传给角色 —— 系统 python 没有 playwright,
149
+ // 角色照抄 `python3` 会得到「playwright 未安装」(真实票取证踩到过)。
150
+ py: (process.env.ARGENT_PY || process.env.ARGENT_PYTHON || `${process.env.DSH_HOME || `${process.env.HOME}/.dsh`}/argent/venv/bin/python3`),
151
+ ledger: cfg.paths.ledger,
152
+ // 2026-09-20(迭代2-步骤2):租约与集成名进模板 —— 提示词里**不许**再写死这些
153
+ // (曾写"带 10 分钟租约",而注册表后来统一成 20 分钟 ⇒ 提示词说谎且没人发现)。
154
+ leaseMin: String((cfg.concurrency || {}).leaseMin ?? ''),
155
+ integration: String(cfg.integration || ''),
156
+ reason: REASON,
157
+ case: CASE,
158
+ attempt: ATTEMPT || '1',
159
+ error: ERROR || '(未提供摘要,请读日志)',
160
+ }
161
+ // 裁定提示词:只讲"人拍板了什么 + 你要做什么 + 怎么回填",不复述流程知识(角色已具备)
162
+ const RULING_PROMPT = [
163
+ `【用户裁定 · 流程 ${cfg.title}(\`${FLOW}\`)】`,
164
+ ``,
165
+ `用户已就这条失败票作出决定,请**按用户裁定执行**,不要再重新论证该不该做:`,
166
+ ``,
167
+ `- 票:\`${CASE || '(未给 case,无法执行)'}\``,
168
+ `- 用户裁定原文(逐字,以此为准):`,
169
+ ` > ${NOTE || '(未提供裁定原文)'}`,
170
+ ``,
171
+ `执行要求:`,
172
+ `1) 先按 SOP 的派发契约派 subagent 干活(**一店一批**,命令照抄 \`${join(CLONE, 'scripts')}/flow-prompts/${FLOW}.md\`);`,
173
+ `2) 回填台账(\`${cfg.paths.ledger}\`):`,
174
+ ` \`${vars.py} ${join(CLONE, 'scripts')}/flow_ledger.py --case-id ${CASE || '<case>'} --event retry --by ${cfg.role} --error "用户裁定:<一句话>"\`,`,
175
+ ` 派发后再记 \`--event dispatched\`(带 attempt);`,
176
+ `3) 若你判断用户的裁定**在技术上做不到**(例如票上根本没有可续跑的货件号),`,
177
+ ` **不要硬跑**:记 \`blocked\` 并把障碍讲清楚,回过头问用户。`,
178
+ ].join('\n')
179
+
180
+ const PROMPT = RULING ? RULING_PROMPT : tpl.replace(/\{\{(\w+)\}\}/g, (m, k) => (k in vars ? String(vars[k]) : m))
181
+
182
+ // ── 鉴权(**多来源 + 先验后用**;唯一实现在 scripts/lib/wake-auth.mjs)──────
183
+ // 历史形态(2026-10-08 前):只读 `/tmp/dsh-web.log` 里最后一次 `token=…`。dsh 的启动 token 是
184
+ // **每进程随机**的、只在启动日志里 ⇒ 日志一没(/tmp 被清理)就彻底取不到,且没有任何退路。
185
+ // 现在按优先级试:① 显式 token 文件 ② **凭据里的 browser-session 密钥现签 cookie(不依赖 /tmp)**
186
+ // ③ DSH_WEB_LOG ④ plist 的 StandardOutPath ⑤ 稳定目录候选 ⑥ /tmp(旧机器兜底)。
187
+ // **延迟获取**:dry-run / 纯预览路径不该因为"没 token"而失败(原实现在预览前就取 token)。
188
+ let AUTH = null
189
+ async function auth() {
190
+ if (AUTH) return AUTH
191
+ const sources = authSources({
192
+ env: process.env,
193
+ home: homedir(),
194
+ dshHome: process.env.DSH_HOME || join(homedir(), '.dsh'),
195
+ base: BASE,
196
+ })
197
+ const r = await acquireWakeAuth({ sources, base: BASE })
198
+ if (!r.ok) {
199
+ const head = r.unreachable
200
+ ? `dsh web 不可达(${BASE}):${r.unreachable} —— 唤醒无法进行(服务没起就别谈唤醒)`
201
+ : authFailureText({ tried: r.tried, base: BASE, home: homedir(), dshHome: process.env.DSH_HOME || join(homedir(), '.dsh') })
202
+ failWake(head, `唤醒取不到鉴权(尝试 ${r.tried.length} 个来源全失败${r.unreachable ? ';服务不可达' : ''})`)
203
+ }
204
+ log(`🔑 唤醒鉴权来源:${r.source}${(() => {
205
+ // 跳过摘要:**为什么没用上更靠前的来源**必须看得见(否则"凭据明明在、却走了日志"没人能解释)
206
+ const skip = (r.tried || []).filter((t) => t.status !== 'ok')
207
+ if (!skip.length) return ''
208
+ return `(此前跳过 ${skip.length} 个:${skip.map((t) => `${t.id}=${SOURCE_STATUS_ZH[t.status] || t.status}`).join(';')})`
209
+ })()}`)
210
+ AUTH = r
211
+ return r
212
+ }
213
+ const rpc = async (method, args) => {
214
+ const { cookie } = await auth()
215
+ const r = await fetch(`${BASE}/api/${method}`, {
216
+ method: 'POST',
217
+ headers: { 'content-type': 'application/json', cookie: `${cookie.name}=${cookie.value}` },
218
+ body: JSON.stringify({ type: 'client-request', rpcId: 'trig-' + Math.random().toString(36).slice(2), method, payload: { args } }),
219
+ })
220
+ return r.json()
221
+ }
222
+
223
+ // ── 会话复用 ────────────────────────────────────────────────────
224
+ const readSid = () => { try { return JSON.parse(readFileSync(cfg.paths.sessionIdFile, 'utf8')).sessionId || '' } catch { return '' } }
225
+ const writeSid = (sid) => {
226
+ try {
227
+ mkdirSync(dirname(cfg.paths.sessionIdFile), { recursive: true })
228
+ writeFileSync(cfg.paths.sessionIdFile, JSON.stringify({ sessionId: sid, flow: FLOW, updatedAt: new Date().toISOString() }, null, 2) + '\n')
229
+ } catch (e) { log(`⚠️ 会话 id 落盘失败(下轮会新建会话):${e.message}`) }
230
+ }
231
+ async function createSession() {
232
+ const c = await rpc('session/create', { request: { agentPreset: cfg.dispatch.preset, cwd: cfg.dispatch.cwd.replace(/^~/, homedir()) } })
233
+ const sid = c?.result?.value?.sessionId
234
+ if (!sid) failWake(`建会话失败:${JSON.stringify(c).slice(0, 200)}`, '唤醒建会话失败(session/create 未返回 sessionId)')
235
+ writeSid(sid)
236
+ return sid
237
+ }
238
+ const promptOf = (sid, text) => rpc('session/prompt', {
239
+ request: { requestId: 'req-' + Math.random().toString(36).slice(2), sessionId: sid, mode: 'queue', content: [{ type: 'text', text: text || PROMPT }] },
240
+ })
241
+
242
+ // ── dry-run:只解析配置/模板并预览,**不鉴权、不建会话、不投递** ──
243
+ let sid = readSid()
244
+
245
+ // ── --notice:投递一条自由文本指令给流程角色(不派单、不改台账)──────────
246
+ // 为什么需要(2026-09-23):美客多限流时角色仍在重跑手头的票,"让角色知道平台慢/别再试"
247
+ // 此前没有通道 —— 只能等它自己撞够失败。有了它就能一句话叫停/叫等。
248
+ if (NOTICE) {
249
+ const text = `【流程通知 · ${new Date().toLocaleString('zh-CN')}】\n${NOTICE}`
250
+ if (DRY) { log(`✅ [dry-run] 将向 ${sid || '(新会话)'} 投递通知:\n${text}`); process.exit(0) }
251
+ if (!sid) sid = await createSession()
252
+ const r = await promptOf(sid, text)
253
+ if (r?.error) failWake(`通知投递失败:${JSON.stringify(r).slice(0, 200)}`, `流程通知投递失败(reason=notice):${JSON.stringify(r).slice(0, 160)}`)
254
+ log(`✅ 通知已投递给流程 ${FLOW} 的会话 ${sid}`)
255
+ process.exit(0)
256
+ }
257
+
258
+
259
+ if (DRY) {
260
+ const what = REASON === 'failure' ? `失败交接 case=${CASE || '(未给)'}`
261
+ : RULING ? `用户裁定 case=${CASE || '(未给)'}`
262
+ : `票=${TICKETS.join('、') || '(无)'}`
263
+ log(`✅ [dry-run] 流程 ${FLOW}:本轮语义=${MODE_LABEL} reason=${REASON} ${what} preset=${cfg.dispatch.preset} 最多 ${MAX} 张`
264
+ + `|${sid ? '将复用会话 ' + sid : '将新建会话'}|模板 ${RULING ? '(ruling 直传,不用模板)' : TPL_PATH}(${PROMPT.length} 字)`
265
+ + `|**未建会话、未投递**${RULING ? '\n──── 将投递的提示词 ────\n' + PROMPT : ''}`)
266
+ process.exit(0)
267
+ }
268
+
269
+ let created = false
270
+ if (!sid) { sid = await createSession(); created = true }
271
+
272
+ let p = await promptOf(sid)
273
+ if (!p?.result?.ok && !created) {
274
+ // 复用的会话已不可用 ⇒ 新建一个再投(旧行为:每轮新建;这里只在必要时新建)
275
+ log(`⚠️ 复用会话 ${sid} 投递失败 ⇒ 改为新建会话重投`)
276
+ sid = await createSession(); created = true
277
+ p = await promptOf(sid)
278
+ }
279
+ if (p?.result?.ok) {
280
+ log(`✅ 已触发流程 ${FLOW} 的会话 ${sid}${created ? '(新建)' : '(复用)'}`
281
+ + `(reason=${REASON}${REASON === 'failure' ? ' case=' + CASE : ''},最多 ${MAX} 张,${MODE_LABEL})`)
282
+ process.exit(0)
283
+ }
284
+ failWake(`投递失败:${JSON.stringify(p).slice(0, 200)}`, `唤醒投递失败(session/prompt 未 accepted):${JSON.stringify(p).slice(0, 160)}`)