@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,293 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ # 停用开关:存在 ~/.dsh/argent/PAUSE_POLL 时立即退出(本机 hermes agent 承担
4
+ # FULL 轮询时使用;恢复执行:rm ~/.dsh/argent/PAUSE_POLL)
5
+ if [ -f "$HOME/.dsh/argent/PAUSE_POLL" ]; then
6
+ exit 0
7
+ fi
8
+ # Argent FULL 货件自动化 — 多店铺多记录并行 wrapper(no_agent 模式,路径参数化版)
9
+ # 1) 查询飞书 状态 in (Pending, 运行中) 且 就绪=true 的记录(兼容数组解析;运行中残留可续跑)
10
+ # 2) 按记录 spawn orchestrator(--record-id 定向)——同店不同记录并行(每进程独立 CDP 标签页),
11
+ # 同 record 防重入由 orchestrator 内部 record 级 flock(/tmp/ziniao-<record_id>.lock)保证,
12
+ # 本脚本另用 pgrep 跳过已有存活进程的记录(避免 cron 重叠期重复 spawn 噪音)
13
+ # 日志: ~/.dsh/argent/fulfillment-logs/run-<日期>-<店名>-<record_id>.log
14
+ #
15
+ # argent-dsh 自持路径(脚本与数据均属 argent-dsh,不触碰 hermes 目录):
16
+ # 固化脚本(poll/orchestrator/init): ~/.argent-dsh/scripts/(安装器部署,update 更新)
17
+ # 客户数据(stores.json/fulfillment.env/cdp-port-map.json): ~/.dsh/argent/
18
+ # cron: 系统 crontab(crontab -l 含 poll-fulfillment.sh,由 init-ml.sh 注册)
19
+ # 路径参数化(客户机器无开发机固定路径):
20
+ # orchestrator 解析顺序:${FULFILLMENT_ORCH}(fulfillment.env 可配置)
21
+ # → 脚本同目录 orchestrator.py(= ~/.argent-dsh/scripts/ 部署副本)
22
+ # → ${ARGENT_PROFILE_HOME:-~/.argent-dsh}/scripts/orchestrator.py
23
+ # stores.json 解析顺序:${STORES_JSON}(fulfillment.env 可配置)
24
+ # → ~/.dsh/argent/stores.json(默认,客户数据,update 不覆盖)
25
+ # → ${ARGENT_PROFILE_HOME:-~/.argent-dsh}/scripts/stores.json(旧版兜底)
26
+
27
+ # ── 身份确认 ──
28
+ # cron 任务由 init-ml.sh 注册在系统 crontab,脚本部署在 ~/.argent-dsh/scripts/——天然隔离;
29
+ # 未安装 argent-dsh(ml-seller)的机器不会有本 cron job,此守卫仅作防御性校验。
30
+ PROFILE_NAME="${ARGENT_PROFILE_NAME:-argent-ml-seller}"
31
+ PROFILE_HOME="${ARGENT_PROFILE_HOME:-$HOME/.argent-dsh}"
32
+ if [ ! -d "$PROFILE_HOME" ]; then
33
+ echo "[poll] 未安装 argent-dsh(${PROFILE_HOME}),跳过 FULL 轮询(隔离守卫)" >&2
34
+ exit 0
35
+ fi
36
+
37
+ # ── fulfillment.env 路径解析(env → ~/.dsh/argent/(默认)→ 脚本目录兜底)──
38
+ ENV_FILE="${FULFILLMENT_ENV_FILE:-}"
39
+ for cand in \
40
+ "$ENV_FILE" \
41
+ "$HOME/.dsh/argent/fulfillment.env" \
42
+ "$PROFILE_HOME/scripts/fulfillment.env"; do
43
+ if [ -n "$cand" ] && [ -f "$cand" ]; then
44
+ ENV_FILE="$cand"
45
+ break
46
+ fi
47
+ done
48
+ if [ -f "$ENV_FILE" ]; then
49
+ set -a; source "$ENV_FILE"; set +a
50
+ fi
51
+
52
+ LOG_DIR="$HOME/.dsh/argent/fulfillment-logs"
53
+ mkdir -p "$LOG_DIR"
54
+
55
+ # ── orchestrator 路径解析 ──
56
+ ORCH="${FULFILLMENT_ORCH:-}"
57
+ if [ -z "$ORCH" ]; then
58
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
59
+ for cand in \
60
+ "$SCRIPT_DIR/orchestrator.py" \
61
+ "$PROFILE_HOME/scripts/orchestrator.py"; do
62
+ [ -f "$cand" ] && ORCH="$cand" && break
63
+ done
64
+ fi
65
+ if [ -z "$ORCH" ] || [ ! -f "$ORCH" ]; then
66
+ echo "[poll] 未找到 orchestrator.py,请先运行初始化向导(init-ml.sh)或设置 FULFILLMENT_ORCH" >&2
67
+ exit 1
68
+ fi
69
+
70
+ # ── stores.json 路径解析(env → ~/.dsh/argent/(默认)→ 脚本目录兜底)──
71
+ STORES_JSON="${STORES_JSON:-}"
72
+ for cand in \
73
+ "$STORES_JSON" \
74
+ "$HOME/.dsh/argent/stores.json" \
75
+ "$PROFILE_HOME/scripts/stores.json"; do
76
+ if [ -n "$cand" ] && [ -f "$cand" ]; then
77
+ STORES_JSON="$cand"
78
+ break
79
+ fi
80
+ done
81
+ if [ ! -f "$STORES_JSON" ]; then
82
+ echo "[poll] 未找到本地 stores.json(${HOME}/.dsh/argent/),将尝试实时读取紫鸟环境(ziniao-cli store list)" >&2
83
+ STORES_JSON=""
84
+ fi
85
+ export STORES_JSON
86
+
87
+ # cron 环境 PATH 兜底(2026-09-01 Huangwei Mac mini 实测):cron 最小 PATH 无 ~/node/bin
88
+ # (lark-cli shebang 为 /usr/bin/env node)与 ~/.local/bin(npm 全局 lark-cli 位置)。
89
+ # 追加无害:正常 shell 中这些目录若不存在则被忽略。
90
+ export PATH="$HOME/node/bin:$HOME/.local/bin:$PATH"
91
+
92
+ # 解释器解析(2026-09-22 重启事故:默认值写死 ~/.dsh/argent/venv ⇒ 重启后静默空转)
93
+ pick_py() {
94
+ local c
95
+ # 候选(2026-09-22):ARGENT_PY → DSH_HOME/argent/venv → ~/.dsh/argent/venv → 仓库 .venv → PATH
96
+ for c in "${ARGENT_PY:-}" "${DSH_HOME:-$HOME/.dsh}/argent/venv/bin/python3" \
97
+ "$HOME/.dsh/argent/venv/bin/python3" "${REPO:-}/.venv/bin/python3" \
98
+ "$(command -v python3 2>/dev/null || true)"; do
99
+ [ -n "$c" ] || continue
100
+ [ -x "$c" ] || continue
101
+ "$c" -c 'import openpyxl, yaml' 2>/dev/null || continue # 硬要求:配置/发票生成必需
102
+ "$c" -c 'import PIL, playwright' 2>/dev/null || \
103
+ echo "[$(date '+%F %T')] ⚠️ 解释器 $c 缺 pillow/playwright ⇒ 浏览器流程会失败(修:node install-argent.mjs --venv-only)" >&2
104
+ printf '%s' "$c"; return 0
105
+ done
106
+ return 1
107
+ }
108
+ if ! PY="$(pick_py)"; then
109
+ echo "❌ 找不到可用解释器(需含 openpyxl + yaml):ARGENT_PY / ~/.dsh/argent/venv/bin/python3 / <repo>/.venv / PATH 的 python3" >&2
110
+ echo " 修复: python3 -m venv ~/.dsh/argent/venv && ~/.dsh/argent/venv/bin/pip install openpyxl pyyaml" >&2
111
+ exit 2
112
+ fi
113
+ [ -x "$PY" ] || PY=python3
114
+ # lark-cli 解析:PATH → /opt/homebrew/bin(Intel/标准 brew)→ ~/.local/bin(npm 全局,Huangwei Mac mini 实测位置)
115
+ # 2026-09-01 修复:Mac mini cron 环境 PATH 不含 ~/.local/bin,fallback 到不存在的 /opt/homebrew/bin/lark-cli
116
+ # → 查询静默失败 → poll 空跑(cron.log 0 字节 8/21 起)。三链兜底后仍找不到才报错。
117
+ LARK="$(command -v lark-cli || true)"
118
+ if [ -z "$LARK" ] || [ ! -x "$LARK" ]; then LARK="/opt/homebrew/bin/lark-cli"; fi
119
+ if [ ! -x "$LARK" ]; then LARK="$HOME/.local/bin/lark-cli"; fi
120
+ if [ ! -x "$LARK" ]; then
121
+ echo "[poll] 未找到 lark-cli(已尝试 PATH、/opt/homebrew/bin、$HOME/.local/bin),跳过本轮" >&2
122
+ exit 1
123
+ fi
124
+
125
+ # 2026-09-01 入口日志:每轮 cron 执行必写(0 条 Pending 时静默无输出曾导致无法区分
126
+ # 「cron 没跑」vs「跑了但无记录」——与 poll-invoice 的「开始发票轮询」对齐)。
127
+ echo "[poll] $(date '+%F %T') 开始 FULL 轮询(模式: ${FULL_TABLE_MODE:-legacy})"
128
+
129
+ # ── KB-095:表格模式开关 FULL_TABLE_MODE=lip|legacy ──
130
+ # lip=李培-箱唛工作表直驱(识别层+拾取层在 orchestrator.py --mode lip-poll,映射集中);
131
+ # legacy=现 FULL 任务表(本脚本原查询逻辑,零回归)。模式缺失时按表 token 推断:
132
+ # 存在 FULL_BASE_TOKEN/FULL_TABLE_ID → lip,否则 legacy(存量兼容)。
133
+ TABLE_MODE="${FULL_TABLE_MODE:-}"
134
+ if [ -z "$TABLE_MODE" ]; then
135
+ if [ -n "${FULL_BASE_TOKEN:-}" ] && [ -n "${FULL_TABLE_ID:-}" ]; then
136
+ TABLE_MODE="lip"
137
+ else
138
+ TABLE_MODE="legacy"
139
+ fi
140
+ fi
141
+ export TABLE_MODE
142
+ echo "[poll] $(date '+%F %T') 表格模式: ${TABLE_MODE}"
143
+
144
+ if [ "$TABLE_MODE" = "lip" ]; then
145
+ # ── lip:识别层 + 拾取层委托 orchestrator --mode lip-poll(无浏览器依赖)──
146
+ # 识别层:FULL状态空∧货件号空 → 校验(实时刷新紫鸟授权后)→ 置 待执行/跳过+备注
147
+ # 拾取层:FULL状态=待执行∧就绪=true∧条件齐 → 输出候选(record_id<TAB>店铺名)
148
+ # orchestrator spawn 后自行置 FULL状态=执行中+就绪=false(拾取消费确认位)。
149
+ # stdout 仅候选行;日志/错误走 stderr(已重定向到日志,不污染 RECORDS)。
150
+ LIP_LOG="$LOG_DIR/poll-lip-$(date '+%F').log"
151
+ RECORDS=$( "$PY" "$ORCH" --mode lip-poll 2>>"$LIP_LOG" || true )
152
+ echo "[poll] $(date '+%F %T') lip-poll 拾取候选: $(printf '%s\n' "$RECORDS" | grep -c . || true) 条(日志 ${LIP_LOG})"
153
+ else
154
+ # ── legacy:原 FULL 任务表查询逻辑(零回归)──
155
+
156
+ # 查询 状态 in (Pending, 运行中) 的记录(就绪=true 在解析层过滤;状态字段可能返回数组需兼容)
157
+ # 运行中+就绪=true = 上次中断残留(orchestrator 异常未走失败分支),应继续捡取续跑;
158
+ # 就绪=false 的失败记录仍不捡(解析层排除)。
159
+ OUT=$( "$LARK" base +record-list \
160
+ --base-token "${FEISHU_BASE_TOKEN:-}" \
161
+ --table-id "${FEISHU_TABLE_ID:-}" \
162
+ --filter-json '{"logic":"or","conditions":[["状态","==","Pending"],["状态","==","运行中"]]}' \
163
+ --format json 2>/dev/null || true )
164
+
165
+ # 解析记录(record_id + 店铺名;stores.json 过滤;就绪=true 且 状态 Pending/运行中)
166
+ # 输出: 每行 "record_id<TAB>店铺名"(与 record_id_list 对齐)
167
+ RECORDS=$( printf '%s' "$OUT" | "$PY" -c '
168
+ import json, os, sys
169
+ try:
170
+ d = json.load(sys.stdin)
171
+ fields = d["data"]["fields"]
172
+ rows = d["data"]["data"]
173
+ ids = d["data"]["record_id_list"]
174
+ except Exception:
175
+ sys.exit(0)
176
+ try:
177
+ p = os.environ.get("STORES_JSON") or os.path.expanduser("~/.dsh/argent/stores.json")
178
+ if not os.path.isfile(p):
179
+ p = os.path.expanduser("~/.argent-dsh/scripts/stores.json")
180
+ stores_map = json.load(open(p))
181
+ valid = set(stores_map.keys())
182
+ src = "stores.json"
183
+ except Exception:
184
+ valid = None
185
+ src = None
186
+ if valid is None:
187
+ # 无本地映射缓存 → 实时读取紫鸟环境(ziniao-cli store list,只读数据源)
188
+ # 并保存一份到 argent 自己的路径(~/.dsh/argent/stores.json,初始化语义)
189
+ import subprocess
190
+ try:
191
+ out = subprocess.run(["ziniao-cli", "store", "list"],
192
+ capture_output=True, text=True, timeout=20)
193
+ d = json.loads(out.stdout)
194
+ items = d.get("data", {}).get("items", [])
195
+ ml = [i for i in items if "MercadoLibre" in (i.get("platformName") or "")]
196
+ valid = {i.get("storeName") for i in ml}
197
+ src = "ziniao"
198
+ if valid:
199
+ try:
200
+ target = os.path.expanduser("~/.dsh/argent/stores.json")
201
+ os.makedirs(os.path.dirname(target), exist_ok=True)
202
+ map_data = {i.get("storeName"): {
203
+ "store_id": str(i.get("storeId") or ""),
204
+ "platform": "MercadoLibre", "cdp_port": 0} for i in ml}
205
+ with open(target, "w", encoding="utf-8") as f:
206
+ json.dump(map_data, f, ensure_ascii=False, indent=2)
207
+ except Exception:
208
+ pass
209
+ print("[poll] stores.json 缺失,已实时读取紫鸟环境 %d 个并保存(ziniao-cli store list)" % len(valid),
210
+ file=sys.stderr)
211
+ except Exception:
212
+ valid = None
213
+ src = None
214
+ if valid is None:
215
+ print("[poll] 无法获取店铺映射(本地 stores.json 缺失且 ziniao-cli store list 不可用),跳过本轮", file=sys.stderr)
216
+ sys.exit(0)
217
+ out_lines = []
218
+ for i, row in enumerate(rows):
219
+ f = dict(zip(fields, row))
220
+ if f.get("就绪") is not True:
221
+ continue
222
+ status = f.get("状态")
223
+ statuses = status if isinstance(status, list) else [status]
224
+ if not any(k in str(s) for k in ("Pending", "运行中") for s in statuses if s is not None):
225
+ continue
226
+ rid = str(ids[i]) if i < len(ids) else ""
227
+ # lark-cli 单选字段返回 list(如 [\u00272店-子账号\u0027]),取首元素再与 stores.json key 匹配
228
+ raw_store = f.get("店铺名称")
229
+ store = str(raw_store[0] if isinstance(raw_store, list) and raw_store else raw_store or "").strip()
230
+ if not rid or not store:
231
+ continue
232
+ if valid is not None and store not in valid:
233
+ print(f"[poll] 跳过未配置店铺: {store} (record={rid})", file=sys.stderr)
234
+ continue
235
+ out_lines.append(f"{rid}\t{store}")
236
+ print("\n".join(out_lines))
237
+ ' || true )
238
+ fi
239
+
240
+ # KB-085:按店分组 spawn——同店所有待处理记录合并为一次 orchestrator 调用(单 CDP 连接
241
+ # 多标签页批量模式),根治「同店多记录并发 connect_over_cdp 触发紫鸟实例重启」;
242
+ # 不同店仍可并行(不同窗口不同端口);记录级 flock 防重入由 orchestrator 内部保证,
243
+ # 店级 pgrep 跳过已有存活进程(cron 重叠期不重复 spawn)
244
+ if [ -n "$RECORDS" ]; then
245
+ # 按店聚合:store -> "rid1 rid2 ..."
246
+ # ⚠️ bash 3.2 兼容(macOS 默认 bash 3.2.57 不支持 declare -A 关联数组——KB-085
247
+ # 引入的 declare -A 在 Mac mini 报「declare: -A: invalid option」导致分组失效、
248
+ # 有 Pending 也不 spawn,2026-09-02 实测)。改用「前缀变量」模拟关联数组。
249
+ _store_keys=""
250
+ while IFS=$'\t' read -r rid store; do
251
+ if [ -z "$rid" ]; then
252
+ continue
253
+ fi
254
+ # 变量名用 store 做后缀(特殊字符转义为 _),值追加 rid
255
+ _var="BY_STORE_$(printf '%s' "$store" | tr -c 'A-Za-z0-9' '_')"
256
+ # KB-100:同店多候选按**逗号**追加(对齐 orchestrator --records 逗号协议
257
+ # split(",")——原空格追加在 lip 同店 ≥2 候选时拼成单条非法 record_id 致
258
+ # spawn 失败死循环,2026-09-04 16:10 实测);首元素带前导逗号由 L250 去掉。
259
+ eval "$_var=\"\${$_var:-},$rid\""
260
+ # 记录店名集合(去重)
261
+ case " $_store_keys " in
262
+ *" $store "*) ;;
263
+ *) _store_keys="$_store_keys $store" ;;
264
+ esac
265
+ done <<< "$RECORDS"
266
+ N=0
267
+ for store in $_store_keys; do
268
+ if pgrep -f "orchestrator.py.*--store-name[ =]${store}" >/dev/null 2>&1; then
269
+ echo "[poll] $(date '+%F %T') 店铺 ${store} 已有 orchestrator 进程运行,整店跳过(防重入)"
270
+ continue
271
+ fi
272
+ _var="BY_STORE_$(printf '%s' "$store" | tr -c 'A-Za-z0-9' '_')"
273
+ # KB-100:去掉聚合值前导逗号(首个 rid 前),recs 即为逗号分隔记录串
274
+ eval "recs=\"\${$_var#,}\""
275
+ LOG_FILE="$LOG_DIR/run-$(date '+%F')-${store}-batch.log"
276
+ FULFILLMENT_LOG_FILE="$LOG_FILE" nohup "$PY" "$ORCH" --mode full --allow-write \
277
+ --store-name "$store" --records "$recs" >> "$LOG_FILE" 2>&1 &
278
+ N=$((N + 1))
279
+ echo "[poll] $(date '+%F %T') 店铺 ${store} 批量 spawn(记录: ${recs})"
280
+ done
281
+ _total=0
282
+ for store in $_store_keys; do
283
+ _var="BY_STORE_$(printf '%s' "$store" | tr -c 'A-Za-z0-9' '_')"
284
+ # KB-100:聚合值为逗号分隔(前导逗号已去除的按店 recs 语义),按逗号计数
285
+ # (wc -w 对逗号串只算 1 词;count = 逗号数 + 1,非空值才计)
286
+ eval "_cnt=\"\${$_var#,}\""
287
+ if [ -n "$_cnt" ]; then
288
+ _total=$((_total + $(printf '%s' "$_cnt" | tr ',' '\n' | grep -c . || true)))
289
+ fi
290
+ done
291
+ echo "[poll] $(date '+%F %T') 已按店分组并行启动 ${N} 个 orchestrator(同店单连接批量,记录合计 ${_total})"
292
+ fi
293
+ exit 0
@@ -0,0 +1,74 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ # Argent 发票阶段 B 轮询 — poll-invoice.sh(KB-045)
4
+ # 扫描 FULL任务表:发票状态=待生成 且 FULL状态=已完成 的行 → 阶段 A 生成发票 →
5
+ # 阶段 B 回写飞书发票文件 → 上传鑫中航 → 下载大货标签 → 状态流转(无人值守)。
6
+ # 职责边界:本机(chester Mac)承担发票轮询;Mac mini hermes cron 承担 FULL 轮询
7
+ # (poll-fulfillment.sh)——发票轮询放本机,互不干扰。
8
+ # 防重入:pgrep 跳过已有进程(invoice_runner 单实例串行处理全部待办记录,
9
+ # 无需 record 级并行——发票流程慢(浏览器操作),串行更稳)。
10
+ # 日志:~/.dsh/argent/invoice-logs/run-<日期>-stageA/B.log
11
+
12
+ # 暂停开关(2026-09-10,与 poll-fulfillment.sh 的 PAUSE_POLL 同风格):
13
+ # 存在 ~/.dsh/argent/PAUSE_INVOICE 时立即退出、不做任何事。
14
+ # 用途:**本机是开发/测试机,生产(FULL+发票)跑在 Huangwei 客户机上**;而本机
15
+ # invoice-mapping.json 指向的是正式 Base 的 FULL任务 表 —— 若不暂停,本机会与客户机
16
+ # **抢同一批生产行**(本机 pgrep 只能防本机重入,管不了另一台机器)。
17
+ # 恢复/手工试跑:rm ~/.dsh/argent/PAUSE_INVOICE(或直接手工单独执行 runner)
18
+ if [ -f "$HOME/.dsh/argent/PAUSE_INVOICE" ]; then
19
+ exit 0
20
+ fi
21
+
22
+ PROFILE_HOME="${ARGENT_PROFILE_HOME:-$HOME/.argent-dsh}"
23
+ if [ ! -d "$PROFILE_HOME" ]; then
24
+ echo "[poll-invoice] 未安装 argent-dsh,跳过发票轮询" >&2
25
+ exit 0
26
+ fi
27
+
28
+ # KB-090:launchd 最小 PATH 兜底(同 poll-fulfillment.sh L87-90)——invoice_runner.py
29
+ # 裸 spawn lark-cli,launchd 环境 PATH 无 ~/.local/bin(npm 全局 lark-cli 实测位置)与
30
+ # ~/node/bin(lark-cli shebang /usr/bin/env node)→ ENOENT 静默失败(2026-09-03 cron 同源
31
+ # 事故)。脚本层注入 + runner 层三链解析双保险(防 plist/脚本被重置)。
32
+ export PATH="$HOME/node/bin:$HOME/.local/bin:$PATH"
33
+
34
+ LOG_DIR="$HOME/.dsh/argent/invoice-logs"
35
+ mkdir -p "$LOG_DIR"
36
+
37
+ # 解释器解析(2026-09-22 重启事故:默认值写死 ~/.dsh/argent/venv ⇒ 重启后静默空转)
38
+ pick_py() {
39
+ local c
40
+ # 候选(2026-09-22):ARGENT_PY → DSH_HOME/argent/venv → ~/.dsh/argent/venv → 仓库 .venv → PATH
41
+ for c in "${ARGENT_PY:-}" "${DSH_HOME:-$HOME/.dsh}/argent/venv/bin/python3" \
42
+ "$HOME/.dsh/argent/venv/bin/python3" "${REPO:-}/.venv/bin/python3" \
43
+ "$(command -v python3 2>/dev/null || true)"; do
44
+ [ -n "$c" ] || continue
45
+ [ -x "$c" ] || continue
46
+ "$c" -c 'import openpyxl, yaml' 2>/dev/null || continue # 硬要求:配置/发票生成必需
47
+ "$c" -c 'import PIL, playwright' 2>/dev/null || \
48
+ echo "[$(date '+%F %T')] ⚠️ 解释器 $c 缺 pillow/playwright ⇒ 浏览器流程会失败(修:node install-argent.mjs --venv-only)" >&2
49
+ printf '%s' "$c"; return 0
50
+ done
51
+ return 1
52
+ }
53
+ if ! PY="$(pick_py)"; then
54
+ echo "❌ 找不到可用解释器(需含 openpyxl + yaml):ARGENT_PY / ~/.dsh/argent/venv/bin/python3 / <repo>/.venv / PATH 的 python3" >&2
55
+ echo " 修复: python3 -m venv ~/.dsh/argent/venv && ~/.dsh/argent/venv/bin/pip install openpyxl pyyaml" >&2
56
+ exit 2
57
+ fi
58
+ [ -x "$PY" ] || PY=python3
59
+ RUNNER="$PROFILE_HOME/scripts/invoice_runner.py"
60
+ [ -f "$RUNNER" ] || RUNNER="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/invoice_runner.py"
61
+
62
+ # 防重叠:同一轮内 runner 已在跑则跳过(cron 每 5 分钟,一轮可能 >5 分钟)
63
+ if pgrep -f "invoice_runner.py" >/dev/null 2>&1; then
64
+ echo "[poll-invoice] $(date '+%F %T') invoice_runner 已有进程运行,跳过本轮"
65
+ exit 0
66
+ fi
67
+
68
+ echo "[poll-invoice] $(date '+%F %T') 开始发票轮询"
69
+ # 阶段 A:FULL 已完成 + 发票状态=待生成 → 生成发票 + 回写「发票文件」+ 状态「填写中」
70
+ "$PY" "$RUNNER" --generate >> "$LOG_DIR/run-$(date '+%F')-stageA.log" 2>&1 || true
71
+ # 阶段 B:发票状态=填写中 → 上传鑫中航 + 下载大货标签 + 回写 + 状态流转
72
+ "$PY" "$RUNNER" --stageb >> "$LOG_DIR/run-$(date '+%F')-stageB.log" 2>&1 || true
73
+ echo "[poll-invoice] $(date '+%F %T') 发票轮询完成"
74
+ exit 0