@danceiny/gotry 0.0.1-rc.8 → 0.2.0-rc.27

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 (506) hide show
  1. package/README.md +172 -217
  2. package/README.zh-CN.md +222 -0
  3. package/bin/gotry-backend.js +53 -0
  4. package/bin/gotry-booking-copilot.js +53 -0
  5. package/bin/gotry-bootstrap.js +1744 -0
  6. package/bin/gotry-inner.js +733 -83
  7. package/bin/gotry-process-liveness.d.ts +27 -0
  8. package/bin/gotry-process-liveness.js +97 -0
  9. package/bin/gotry-runtime-resolution.d.ts +27 -0
  10. package/bin/gotry-runtime-resolution.js +49 -0
  11. package/bin/gotry.js +1 -1
  12. package/client/client.js +203 -0
  13. package/cordis.gotry-patch.yml +80 -49
  14. package/data/airline-airports.json +39 -0
  15. package/data/stations-12306-verify.json +524 -0
  16. package/dist/capabilities/agent-reach-deep.js +45 -122
  17. package/dist/capabilities/agent-reach.js +101 -146
  18. package/dist/capabilities/anything.js +135 -94
  19. package/dist/capabilities/artifacts.js +370 -0
  20. package/dist/capabilities/channel-health.js +131 -0
  21. package/dist/capabilities/channel-registry.js +256 -0
  22. package/dist/capabilities/doctor.js +546 -0
  23. package/dist/capabilities/effect.js +394 -0
  24. package/dist/capabilities/external-event.js +149 -0
  25. package/dist/capabilities/fact-log.js +55 -0
  26. package/dist/capabilities/flyai-config.js +337 -0
  27. package/dist/capabilities/flyai.js +968 -0
  28. package/dist/capabilities/fx-contract.js +293 -0
  29. package/dist/capabilities/geo-atlas.js +246 -0
  30. package/dist/capabilities/ground-transfer.js +509 -0
  31. package/dist/capabilities/hbcli.js +260 -123
  32. package/dist/capabilities/hotelbyte-transaction.js +194 -0
  33. package/dist/capabilities/incident-log.js +131 -61
  34. package/dist/capabilities/itinerary-artifact.js +190 -0
  35. package/dist/capabilities/itinerary-deck-artifact.js +194 -0
  36. package/dist/capabilities/itinerary-deck-export.js +339 -0
  37. package/dist/capabilities/lavish-local.js +924 -0
  38. package/dist/capabilities/model-override.js +38 -0
  39. package/dist/capabilities/opensky.js +54 -43
  40. package/dist/capabilities/resilience.js +191 -0
  41. package/dist/capabilities/session/action-cache.js +126 -0
  42. package/dist/capabilities/session/adapters/ctrip-flight.js +141 -0
  43. package/dist/capabilities/session/adapters/ctrip-hotel.js +222 -0
  44. package/dist/capabilities/session/adapters/dida-portal.js +274 -0
  45. package/dist/capabilities/session/adapters/meituan-local.js +54 -0
  46. package/dist/capabilities/session/adapters/rail-12306.js +342 -0
  47. package/dist/capabilities/session/benchmark.js +189 -0
  48. package/dist/capabilities/session/bridge-ledger.js +224 -0
  49. package/dist/capabilities/session/extension-bridge.js +636 -0
  50. package/dist/capabilities/session/extension-channel.js +109 -0
  51. package/dist/capabilities/session/extension-distribution.js +230 -0
  52. package/dist/capabilities/session/extract.js +50 -0
  53. package/dist/capabilities/session/golden-score.js +114 -0
  54. package/dist/capabilities/session/health-watch.js +215 -0
  55. package/dist/capabilities/session/read-guard.js +107 -0
  56. package/dist/capabilities/session/static-flight-golden.js +150 -0
  57. package/dist/capabilities/session/transport.js +109 -0
  58. package/dist/capabilities/session/wizard.js +117 -0
  59. package/dist/capabilities/session-consent.js +178 -0
  60. package/dist/capabilities/session-login.js +170 -0
  61. package/dist/capabilities/session-search.js +686 -0
  62. package/dist/capabilities/spawn-bounded.js +203 -0
  63. package/dist/capabilities/sponsor-plugin.js +341 -0
  64. package/dist/capabilities/visa-policy.js +140 -0
  65. package/dist/capabilities/weather.js +243 -138
  66. package/dist/data/session-golden-20.json +25 -0
  67. package/dist/data/sf-golden-manifest.json +103 -0
  68. package/dist/data/sf-static-routes.json +91 -0
  69. package/dist/scripts/action-cache-tests.js +72 -0
  70. package/dist/scripts/agent-planning-turn-deadline-e2e.js +242 -0
  71. package/dist/scripts/agent-planning-turn-deadline-tests.js +185 -0
  72. package/dist/scripts/agent-reach-deep-tests.js +30 -40
  73. package/dist/scripts/agent-reach-error-tests.js +354 -0
  74. package/dist/scripts/agent-reach-tests.js +26 -18
  75. package/dist/scripts/agent-reach-wrapper-tests.js +50 -50
  76. package/dist/scripts/anything-tests.js +116 -60
  77. package/dist/scripts/artifact-client-contract-tests.js +220 -0
  78. package/dist/scripts/artifacts-capability-tests.js +727 -0
  79. package/dist/scripts/async-collect.js +68 -10
  80. package/dist/scripts/benchmark-environment-bridge-e2e.js +741 -0
  81. package/dist/scripts/benchmark-environment-bridge-tests.js +1452 -0
  82. package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +126 -0
  83. package/dist/scripts/booking-copilot-availability-policy-tests.js +265 -0
  84. package/dist/scripts/booking-copilot-bin-proof-tests.js +66 -0
  85. package/dist/scripts/booking-copilot-cleanup-proof-helper.js +76 -0
  86. package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +144 -0
  87. package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +424 -0
  88. package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +2839 -0
  89. package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +309 -0
  90. package/dist/scripts/booking-copilot-dsh-readiness-proof.js +238 -0
  91. package/dist/scripts/booking-copilot-dsh-warmer-proof.js +123 -0
  92. package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +156 -0
  93. package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +70 -0
  94. package/dist/scripts/booking-copilot-intent-proof-tests.js +422 -0
  95. package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +184 -0
  96. package/dist/scripts/booking-copilot-planner-live-probe.js +95 -0
  97. package/dist/scripts/booking-copilot-proof-runtime.js +42 -0
  98. package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +210 -0
  99. package/dist/scripts/booking-copilot-runtime-proof-tests.js +2349 -0
  100. package/dist/scripts/booking-copilot-server-proof-tests.js +784 -0
  101. package/dist/scripts/booking-copilot-startup-proof-tests.js +94 -0
  102. package/dist/scripts/booking-executor-tests.js +80 -0
  103. package/dist/scripts/booking-recovery-chain-tests.js +182 -0
  104. package/dist/scripts/booking-saga-tests.js +125 -0
  105. package/dist/scripts/booking-surface-contract-proof-tests.js +212 -0
  106. package/dist/scripts/bootstrap-tests.js +1479 -0
  107. package/dist/scripts/bridge-events-tests.js +239 -0
  108. package/dist/scripts/bridge-ledger-tests.js +428 -0
  109. package/dist/scripts/build-changelog.js +238 -0
  110. package/dist/scripts/build-metrics-report.js +331 -0
  111. package/dist/scripts/changelog-tests.js +118 -0
  112. package/dist/scripts/channel-probe-tests.js +103 -0
  113. package/dist/scripts/channel-probe.js +169 -0
  114. package/dist/scripts/channel-registry-tests.js +208 -0
  115. package/dist/scripts/companion-tests.js +67 -0
  116. package/dist/scripts/dida-cookie-probe.js +87 -0
  117. package/dist/scripts/dida-runner-stop-tests.js +311 -0
  118. package/dist/scripts/dida-sw-probe.js +114 -0
  119. package/dist/scripts/diff-test.js +17 -12
  120. package/dist/scripts/doctor-tests.js +564 -0
  121. package/dist/scripts/dsh-artifact-e2e.js +279 -0
  122. package/dist/scripts/dsh-artifact-web-e2e.js +675 -0
  123. package/dist/scripts/dsh-http-proxy-sse-proof.js +90 -0
  124. package/dist/scripts/dsh-runtime-closure-tests.js +182 -0
  125. package/dist/scripts/dsh-runtime-closure.js +162 -0
  126. package/dist/scripts/dsh-session-v3-migration-proof.js +109 -0
  127. package/dist/scripts/dsh-subprocess-local-proof.js +150 -0
  128. package/dist/scripts/dsh-target-closure-proof.js +178 -0
  129. package/dist/scripts/effect-tests.js +539 -0
  130. package/dist/scripts/engine-run.js +1 -3
  131. package/dist/scripts/engine-tests.js +16 -10
  132. package/dist/scripts/evaluation-cadence-tests.js +174 -0
  133. package/dist/scripts/evaluation-contract-tests.js +268 -0
  134. package/dist/scripts/extension-distribution-cli.js +39 -0
  135. package/dist/scripts/extension-distribution-tests.js +443 -0
  136. package/dist/scripts/extension-tests.js +988 -0
  137. package/dist/scripts/external-event-tests.js +350 -0
  138. package/dist/scripts/fact-gate-tests.js +869 -0
  139. package/dist/scripts/fixtures/extension-bridge-unref-child.mjs +21 -0
  140. package/dist/scripts/flight-hotel-anchor-363-registered-e2e.js +169 -0
  141. package/dist/scripts/flight-malformed-tests.js +159 -0
  142. package/dist/scripts/flyai-setup-tests.js +228 -0
  143. package/dist/scripts/flyai-setup-tool-tests.js +54 -0
  144. package/dist/scripts/flyai-tests.js +692 -0
  145. package/dist/scripts/flyai-tool-registration-contract-tests.js +91 -0
  146. package/dist/scripts/fx-contract-tests.js +201 -0
  147. package/dist/scripts/g5-guard-tests.js +131 -0
  148. package/dist/scripts/g5-guard.js +189 -0
  149. package/dist/scripts/gen-lunar-anchors.js +106 -0
  150. package/dist/scripts/geo-atlas-tests.js +283 -0
  151. package/dist/scripts/gotry-backend-kernel-tests.js +206 -0
  152. package/dist/scripts/gotry-try-demo-tests.js +79 -0
  153. package/dist/scripts/gotry-try-demo.js +49 -0
  154. package/dist/scripts/ground-transfer-tests.js +956 -0
  155. package/dist/scripts/hbcli-e2e-tests.js +159 -0
  156. package/dist/scripts/hbcli-live-optin-tests.js +96 -0
  157. package/dist/scripts/hbcli-release-contract-tests.js +122 -0
  158. package/dist/scripts/hbcli-tests.js +121 -69
  159. package/dist/scripts/health-watch-cli.js +73 -0
  160. package/dist/scripts/hotel-date-gate-tests.js +496 -0
  161. package/dist/scripts/hotelbyte-reconcile-tests.js +141 -0
  162. package/dist/scripts/hotelbyte-spawn-e2e-tests.js +373 -0
  163. package/dist/scripts/i18n-tests.js +41 -0
  164. package/dist/scripts/incident-tests.js +281 -87
  165. package/dist/scripts/issue-194-job-id-guard-tests.js +106 -0
  166. package/dist/scripts/issue-233-cancel-refund-commission-tests.js +392 -0
  167. package/dist/scripts/issue-271-liveness-tests.js +569 -0
  168. package/dist/scripts/issue-289-model-retry-real-tests.js +296 -0
  169. package/dist/scripts/issue-289-model-retry-tests.js +441 -0
  170. package/dist/scripts/issue-289-web-retry-e2e.js +630 -0
  171. package/dist/scripts/issue-338-home-city-e2e.js +577 -0
  172. package/dist/scripts/issue343-real-entry-e2e.js +160 -0
  173. package/dist/scripts/issue436-persisted-routing-e2e.js +247 -0
  174. package/dist/scripts/itinerary-artifact-tests.js +368 -0
  175. package/dist/scripts/itinerary-deck-artifact-tests.js +416 -0
  176. package/dist/scripts/itinerary-deck-export-tests.js +552 -0
  177. package/dist/scripts/itinerary-deck-tests.js +435 -0
  178. package/dist/scripts/itinerary-html-tests.js +426 -0
  179. package/dist/scripts/journey-tests.js +22 -27
  180. package/dist/scripts/kernel-manifest-evidence.js +109 -0
  181. package/dist/scripts/kernel-manifest-gate.js +126 -0
  182. package/dist/scripts/kernel-manifest-tests.js +212 -0
  183. package/dist/scripts/kernel-manifest-trace-entry.js +7 -0
  184. package/dist/scripts/kernel-manifest-trace-hook.mjs +28 -0
  185. package/dist/scripts/kernel-manifest.js +369 -0
  186. package/dist/scripts/lavish-local-tests.js +1226 -0
  187. package/dist/scripts/lavish-product-tools-tests.js +537 -0
  188. package/dist/scripts/ledger-repair-apply-tests.js +316 -0
  189. package/dist/scripts/ledger-repair-plan-tests.js +375 -0
  190. package/dist/scripts/ledger-tests.js +480 -0
  191. package/dist/scripts/ledger-workflow-crash.js +32 -0
  192. package/dist/scripts/managed-dsh-cleanup-diagnostic-proof.js +184 -0
  193. package/dist/scripts/managed-dsh-close-failure-proof.js +172 -0
  194. package/dist/scripts/managed-dsh-run-port-proof.js +153 -0
  195. package/dist/scripts/managed-dsh-terminal-proof.js +252 -0
  196. package/dist/scripts/map-tools-vendor-package-proof.js +365 -0
  197. package/dist/scripts/memory-capture-tests.js +242 -61
  198. package/dist/scripts/memory-decay-tests.js +49 -0
  199. package/dist/scripts/memory-lifecycle-tests.js +657 -0
  200. package/dist/scripts/memory-lifecycle.js +196 -0
  201. package/dist/scripts/memory-metrics.js +29 -31
  202. package/dist/scripts/memory-value-report.js +631 -0
  203. package/dist/scripts/memory-value-tests.js +328 -0
  204. package/dist/scripts/metrics-report-tests.js +151 -0
  205. package/dist/scripts/model-override-e2e.js +137 -0
  206. package/dist/scripts/nightly-evidence-tests.js +161 -0
  207. package/dist/scripts/nightly-evidence.js +286 -0
  208. package/dist/scripts/nudge-digest.js +43 -42
  209. package/dist/scripts/observability-tests.js +381 -0
  210. package/dist/scripts/onboarding-tests.js +161 -0
  211. package/dist/scripts/opensky-check.js +18 -13
  212. package/dist/scripts/opensky-tests.js +28 -28
  213. package/dist/scripts/persona-surface-guard-tests.js +49 -0
  214. package/dist/scripts/pnpm-dsh-closure-proof.js +17 -0
  215. package/dist/scripts/policy-anchor-359-registered-e2e.js +214 -0
  216. package/dist/scripts/price-drift-tests.js +340 -0
  217. package/dist/scripts/price-drift-watch.js +447 -0
  218. package/dist/scripts/probe-poi-tests.js +53 -45
  219. package/dist/scripts/product-metrics.js +483 -0
  220. package/dist/scripts/publish-preverify.js +110 -0
  221. package/dist/scripts/realtime-pricing-tests.js +76 -0
  222. package/dist/scripts/recall-tests.js +513 -0
  223. package/dist/scripts/replay-async.js +20 -18
  224. package/dist/scripts/replay-real.js +18 -18
  225. package/dist/scripts/replay.js +52 -82
  226. package/dist/scripts/session-attach-diagnose.js +31 -0
  227. package/dist/scripts/session-attach-poc.js +62 -0
  228. package/dist/scripts/session-benchmark.js +180 -0
  229. package/dist/scripts/session-dida-live-e2e.js +199 -0
  230. package/dist/scripts/session-extract-tests.js +60 -0
  231. package/dist/scripts/session-link-tests.js +478 -0
  232. package/dist/scripts/session-login.js +29 -0
  233. package/dist/scripts/session-tests.js +862 -0
  234. package/dist/scripts/session-zones-tests.js +358 -0
  235. package/dist/scripts/sf-live-benchmark.js +367 -0
  236. package/dist/scripts/sf-live-challenge-stop-tests.js +453 -0
  237. package/dist/scripts/sf-live-cli-tests.js +92 -0
  238. package/dist/scripts/sf-live-options.js +46 -0
  239. package/dist/scripts/sf-manifest-tests.js +30 -0
  240. package/dist/scripts/sf-manifest.js +33 -0
  241. package/dist/scripts/sf-soft-score-tests.js +67 -0
  242. package/dist/scripts/sf-summary-tests.js +324 -0
  243. package/dist/scripts/sf-summary.js +525 -0
  244. package/dist/scripts/share-tests.js +432 -0
  245. package/dist/scripts/skeleton-check.js +16 -14
  246. package/dist/scripts/skeleton-integration-test.js +28 -11
  247. package/dist/scripts/skills-contract-tests.js +51 -46
  248. package/dist/scripts/smoke-session-gate-tests.js +21 -0
  249. package/dist/scripts/smoke.js +703 -219
  250. package/dist/scripts/spawn-bounded-abort-tests.js +241 -0
  251. package/dist/scripts/sponsor-reuse-tests.js +262 -0
  252. package/dist/scripts/state-cli-tests.js +261 -0
  253. package/dist/scripts/state-cli.js +585 -0
  254. package/dist/scripts/state-repair-cli.js +66 -0
  255. package/dist/scripts/state-repair-tests.js +140 -0
  256. package/dist/scripts/static-golden-tests.js +165 -0
  257. package/dist/scripts/time-eval-tests.js +210 -192
  258. package/dist/scripts/travel-timeline-tests.js +59 -0
  259. package/dist/scripts/turn-handoff-collect-tests.js +169 -0
  260. package/dist/scripts/turn-handoff-collect.js +161 -0
  261. package/dist/scripts/turn-policy-tests.js +55 -0
  262. package/dist/scripts/typed-contract-canary.js +176 -0
  263. package/dist/scripts/tz-resolver-sanity.js +50 -0
  264. package/dist/scripts/tz-resolver-tests.js +584 -0
  265. package/dist/scripts/unified-tests.js +23 -19
  266. package/dist/scripts/visa-policy-tests.js +62 -0
  267. package/dist/scripts/weather-tests.js +276 -41
  268. package/dist/scripts/wish-channel-gate-tests.js +54 -0
  269. package/dist/scripts/write-gate-tests.js +522 -0
  270. package/dist/scripts/z3-lifecycle-fault-tests.js +188 -0
  271. package/dist/scripts/z3-lifecycle-tests.js +170 -0
  272. package/dist/scripts/z3-race-repeat-tests.js +39 -0
  273. package/dist/scripts/z3-race-tests.js +41 -0
  274. package/dist/src/artifact-gate.js +829 -0
  275. package/dist/src/backend/kernel.js +91 -0
  276. package/dist/src/backend/modules/booking-copilot.js +92 -0
  277. package/dist/src/backend/modules/booking-executor.js +124 -0
  278. package/dist/src/backend/modules/session-search.js +551 -0
  279. package/dist/src/benchmark-agent-conformance.js +578 -0
  280. package/dist/src/benchmark-environment-bridge.js +515 -0
  281. package/dist/src/benchmark-headless-child-diagnostics.js +166 -0
  282. package/dist/src/benchmark-tool-isolation.js +151 -0
  283. package/dist/src/bookable-facts.js +533 -0
  284. package/dist/src/booking-saga.js +97 -0
  285. package/dist/src/booking-surface/availability-policy.js +697 -0
  286. package/dist/src/booking-surface/booking-intent.js +43 -0
  287. package/dist/src/booking-surface/cancel-refund-commission.js +379 -0
  288. package/dist/src/booking-surface/canonical-schema.js +116 -0
  289. package/dist/src/booking-surface/contracts.js +75 -0
  290. package/dist/src/booking-surface/dsh-planner.js +1854 -0
  291. package/dist/src/booking-surface/dsh-plugin.js +378 -0
  292. package/dist/src/booking-surface/dsh-worker.js +98 -0
  293. package/dist/src/booking-surface/error-codes.js +231 -0
  294. package/dist/src/booking-surface/index.js +9 -0
  295. package/dist/src/booking-surface/managed-dsh-cleanup-diagnostic.js +97 -0
  296. package/dist/src/booking-surface/managed-dsh-run-port.js +244 -0
  297. package/dist/src/booking-surface/profile.js +24 -0
  298. package/dist/src/booking-surface/recovery-chain.js +367 -0
  299. package/dist/src/booking-surface/runtime.js +1968 -0
  300. package/dist/src/booking-surface/server.js +674 -0
  301. package/dist/src/booking-surface/startup.js +168 -0
  302. package/dist/src/booking-surface/validation.js +261 -0
  303. package/dist/src/bridge.js +20 -13
  304. package/dist/src/companions.js +86 -0
  305. package/dist/src/contracts.js +21 -43
  306. package/dist/src/dsh-llm.js +97 -111
  307. package/dist/src/engine.js +276 -193
  308. package/dist/src/evaluation-cadence.js +97 -0
  309. package/dist/src/evaluation-contracts.js +283 -0
  310. package/dist/src/flight-pack-adapter.js +54 -0
  311. package/dist/src/flight-pack-contract.js +2 -0
  312. package/dist/src/flyai-setup-tool.js +70 -0
  313. package/dist/src/gotry-backend.js +125 -0
  314. package/dist/src/hotel-date-gate.js +118 -0
  315. package/dist/src/i18n.js +88 -0
  316. package/dist/src/index.js +2305 -731
  317. package/dist/src/itinerary-deck.js +139 -0
  318. package/dist/src/itinerary-doc-shared.js +661 -0
  319. package/dist/src/itinerary-html.js +131 -0
  320. package/dist/src/journey.js +155 -108
  321. package/dist/src/lavish-tools.js +400 -0
  322. package/dist/src/ledger-repair-apply.js +538 -0
  323. package/dist/src/ledger-repair-plan.js +463 -0
  324. package/dist/src/loop.js +358 -162
  325. package/dist/src/memory-capture.js +180 -32
  326. package/dist/src/memory-decay.js +47 -0
  327. package/dist/src/memory-lifecycle.js +1310 -0
  328. package/dist/src/memory-utility.js +27 -40
  329. package/dist/src/mock-llm.js +36 -61
  330. package/dist/src/model.js +81 -36
  331. package/dist/src/realtime-pricing.js +103 -0
  332. package/dist/src/recall/card.js +74 -0
  333. package/dist/src/recall/evaluator.js +140 -0
  334. package/dist/src/recall/integration.js +17 -0
  335. package/dist/src/recall/tick.js +166 -0
  336. package/dist/src/session-link/plan-it-action.js +48 -0
  337. package/dist/src/session-link/session-link.js +248 -0
  338. package/dist/src/session-zones.js +507 -0
  339. package/dist/src/share/adapters.js +51 -0
  340. package/dist/src/share/share-consent.js +76 -0
  341. package/dist/src/share/share-deck.js +58 -0
  342. package/dist/src/share/share-token.js +146 -0
  343. package/dist/src/slot-spec.js +84 -106
  344. package/dist/src/state-ledger.js +767 -0
  345. package/dist/src/state-repair.js +299 -0
  346. package/dist/src/subagent-job-id-guard.js +58 -0
  347. package/dist/src/time-anchor.js +231 -33
  348. package/dist/src/tool-packet.js +20 -8
  349. package/dist/src/travel-slots.js +58 -35
  350. package/dist/src/travel-timeline.js +59 -0
  351. package/dist/src/turn-deadline.js +287 -0
  352. package/dist/src/turn-policy.js +118 -0
  353. package/dist/src/tz-resolver.js +143 -0
  354. package/dist/src/unified.js +538 -360
  355. package/dist/src/wish-pool.js +42 -12
  356. package/dist/src/write-gate.js +495 -0
  357. package/dist/src/z3-shared.js +284 -0
  358. package/extension/README.md +21 -0
  359. package/extension/README.zh-CN.md +21 -0
  360. package/extension/background.js +463 -0
  361. package/extension/content-bridge.js +270 -0
  362. package/extension/content-main.js +111 -0
  363. package/extension/manifest.json +60 -0
  364. package/package.json +407 -14
  365. package/schemas/booking.intent.schema.json +193 -0
  366. package/schemas/booking.surface.schema.json +2622 -0
  367. package/ts/capabilities/agent-reach-deep.ts +114 -0
  368. package/ts/capabilities/agent-reach.ts +198 -0
  369. package/ts/capabilities/anything.ts +255 -0
  370. package/ts/capabilities/artifacts.ts +428 -0
  371. package/ts/capabilities/fact-log.ts +54 -0
  372. package/ts/capabilities/flyai-config.ts +388 -0
  373. package/ts/capabilities/flyai.ts +1274 -0
  374. package/ts/capabilities/hbcli.ts +253 -71
  375. package/ts/capabilities/incident-log.ts +88 -59
  376. package/ts/capabilities/itinerary-artifact.ts +214 -0
  377. package/ts/capabilities/itinerary-deck-artifact.ts +218 -0
  378. package/ts/capabilities/itinerary-deck-export.ts +378 -0
  379. package/ts/capabilities/opensky.ts +121 -0
  380. package/ts/capabilities/session/action-cache.ts +148 -0
  381. package/ts/capabilities/session/adapters/ctrip-flight.ts +181 -0
  382. package/ts/capabilities/session/adapters/ctrip-hotel.ts +238 -0
  383. package/ts/capabilities/session/adapters/dida-portal.ts +338 -0
  384. package/ts/capabilities/session/adapters/meituan-local.ts +70 -0
  385. package/ts/capabilities/session/adapters/rail-12306.ts +392 -0
  386. package/ts/capabilities/session/benchmark.ts +276 -0
  387. package/ts/capabilities/session/bridge-ledger.ts +333 -0
  388. package/ts/capabilities/session/extension-bridge.ts +794 -0
  389. package/ts/capabilities/session/extension-channel.ts +144 -0
  390. package/ts/capabilities/session/extension-distribution.ts +266 -0
  391. package/ts/capabilities/session/extract.ts +54 -0
  392. package/ts/capabilities/session/golden-score.ts +139 -0
  393. package/ts/capabilities/session/health-watch.ts +264 -0
  394. package/ts/capabilities/session/read-guard.ts +141 -0
  395. package/ts/capabilities/session/static-flight-golden.ts +209 -0
  396. package/ts/capabilities/session/transport.ts +146 -0
  397. package/ts/capabilities/session/wizard.ts +140 -0
  398. package/ts/capabilities/session-consent.ts +211 -0
  399. package/ts/capabilities/session-login.ts +208 -0
  400. package/ts/capabilities/session-search.ts +893 -0
  401. package/ts/capabilities/weather.ts +330 -0
  402. package/ts/dsh-runtime/vendor/README.md +68 -0
  403. package/ts/dsh-runtime/vendor/dsh-map-tools/LICENSE +21 -0
  404. package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +405 -0
  405. package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +404 -0
  406. package/ts/dsh-runtime/vendor/dsh-map-tools/client/client.js +1584 -0
  407. package/ts/dsh-runtime/vendor/dsh-map-tools/cordis.patch.yml +5 -0
  408. package/ts/dsh-runtime/vendor/dsh-map-tools/icon.svg +5 -0
  409. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/amap.js +595 -0
  410. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/nominatim.js +63 -0
  411. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/osrm.js +58 -0
  412. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/photon.js +55 -0
  413. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-file.js +87 -0
  414. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-route.js +131 -0
  415. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config.js +16 -0
  416. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/geo.js +232 -0
  417. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/index.js +120 -0
  418. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +40 -0
  419. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/staticmap-route.js +115 -0
  420. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/geocode.js +127 -0
  421. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/poi.js +84 -0
  422. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/routes.js +267 -0
  423. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/amap.d.ts +90 -0
  424. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/nominatim.d.ts +17 -0
  425. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/osrm.d.ts +15 -0
  426. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/photon.d.ts +22 -0
  427. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-file.d.ts +33 -0
  428. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-route.d.ts +23 -0
  429. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config.d.ts +23 -0
  430. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/geo.d.ts +61 -0
  431. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/index.d.ts +18 -0
  432. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +14 -0
  433. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/staticmap-route.d.ts +31 -0
  434. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/geocode.d.ts +11 -0
  435. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/poi.d.ts +9 -0
  436. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/routes.d.ts +75 -0
  437. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/types.d.ts +68 -0
  438. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types.js +16 -0
  439. package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +97 -0
  440. package/ts/package.json +296 -3
  441. package/ts/scripts/async-collect.ts +91 -0
  442. package/ts/scripts/map-tools-vendor-package-proof.ts +404 -0
  443. package/ts/scripts/skeleton-check.ts +1 -1
  444. package/ts/scripts/skeleton-integration-test.ts +23 -1
  445. package/ts/scripts/state-cli.ts +568 -0
  446. package/ts/scripts/turn-handoff-collect.ts +178 -0
  447. package/ts/src/artifact-gate.ts +991 -0
  448. package/ts/src/benchmark-agent-conformance.ts +619 -0
  449. package/ts/src/benchmark-environment-bridge.ts +538 -0
  450. package/ts/src/benchmark-headless-child-diagnostics.ts +184 -0
  451. package/ts/src/benchmark-tool-isolation.ts +166 -0
  452. package/ts/src/bookable-facts.ts +837 -0
  453. package/ts/src/booking-saga.ts +133 -0
  454. package/ts/src/booking-surface/availability-policy.ts +522 -0
  455. package/ts/src/booking-surface/booking-intent.ts +86 -0
  456. package/ts/src/booking-surface/cancel-refund-commission.ts +488 -0
  457. package/ts/src/booking-surface/canonical-schema.js +116 -0
  458. package/ts/src/booking-surface/contracts.ts +475 -0
  459. package/ts/src/booking-surface/dsh-planner.ts +1949 -0
  460. package/ts/src/booking-surface/dsh-plugin.js +378 -0
  461. package/ts/src/booking-surface/dsh-worker.ts +110 -0
  462. package/ts/src/booking-surface/error-codes.ts +241 -0
  463. package/ts/src/booking-surface/index.ts +9 -0
  464. package/ts/src/booking-surface/managed-dsh-cleanup-diagnostic.ts +151 -0
  465. package/ts/src/booking-surface/managed-dsh-run-port.ts +273 -0
  466. package/ts/src/booking-surface/profile.ts +42 -0
  467. package/ts/src/booking-surface/recovery-chain.ts +409 -0
  468. package/ts/src/booking-surface/runtime.ts +1793 -0
  469. package/ts/src/booking-surface/server.ts +733 -0
  470. package/ts/src/booking-surface/startup.ts +201 -0
  471. package/ts/src/booking-surface/validation.ts +217 -0
  472. package/ts/src/companions.ts +113 -0
  473. package/ts/src/contracts.ts +13 -3
  474. package/ts/src/dsh-llm.ts +44 -11
  475. package/ts/src/flyai-setup-tool.ts +77 -0
  476. package/ts/src/index.ts +2107 -224
  477. package/ts/src/itinerary-deck.ts +189 -0
  478. package/ts/src/itinerary-doc-shared.ts +741 -0
  479. package/ts/src/itinerary-html.ts +171 -0
  480. package/ts/src/loop.ts +278 -40
  481. package/ts/src/memory-capture.ts +283 -0
  482. package/ts/src/memory-decay.ts +55 -0
  483. package/ts/src/memory-utility.ts +70 -0
  484. package/ts/src/mock-llm.ts +4 -8
  485. package/ts/src/model.ts +88 -2
  486. package/ts/src/recall/card.ts +106 -0
  487. package/ts/src/recall/evaluator.ts +170 -0
  488. package/ts/src/recall/integration.ts +35 -0
  489. package/ts/src/recall/tick.ts +213 -0
  490. package/ts/src/session-link/plan-it-action.ts +78 -0
  491. package/ts/src/session-link/session-link.ts +275 -0
  492. package/ts/src/share/adapters.ts +93 -0
  493. package/ts/src/share/share-consent.ts +105 -0
  494. package/ts/src/share/share-deck.ts +85 -0
  495. package/ts/src/share/share-token.ts +166 -0
  496. package/ts/src/slot-spec.ts +172 -0
  497. package/ts/src/state-ledger.ts +912 -0
  498. package/ts/src/subagent-job-id-guard.ts +72 -0
  499. package/ts/src/time-anchor.ts +338 -0
  500. package/ts/src/tool-packet.ts +32 -0
  501. package/ts/src/travel-slots.ts +219 -0
  502. package/ts/src/travel-timeline.ts +83 -0
  503. package/ts/src/turn-deadline.ts +366 -0
  504. package/ts/src/turn-policy.ts +154 -0
  505. package/ts/src/unified.ts +360 -89
  506. package/ts/src/wish-pool.ts +79 -0
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Share token 签发/校验(issue #573,Phase C 切片;自检 review 修复见 PR #574)。
3
+ *
4
+ * HMAC-SHA256 over base64url(payload-json),签名为 base64url。
5
+ * Token 形如 `${body}.${sig}`(body = base64url(JSON.stringify(payload)))。
6
+ *
7
+ * 设计要点:
8
+ * - 纯函数 + 时间注入(测试不依赖 wall clock);
9
+ * - payload 绑定 share_id / created_at(ISO)/ ttl_seconds / **target(channel+address)**——
10
+ * 目的地进签名,防止「合法 token 换个收件人重放」(自检 review 发现的绑定缺口);
11
+ * - 格式契约**恰一个点**:`indexOf === lastIndexOf('.')`,多点/尾随垃圾拒绝;
12
+ * - ttl 契约:非负整数、上限 2^31-1 秒(防 expiresMs 溢出 Infinity 永不过期);
13
+ * - 校验使用 timingSafeEqual(先长度比对)防时序侧信道;
14
+ * - secret 默认从 `SHARE_HMAC_SECRET` env 取;缺省且 NODE_ENV=production 时
15
+ * **fail-closed**(绝不静默用仓库里公开的 dev 常量签生产 token)——刻意抛错
16
+ * 保留在签发面(resolve/sign);verify 面把同样的配置错误收敛为 `token_invalid`,
17
+ * 非字符串运行期键(数字/对象/Symbol 等 JS 畸形输入)同样收敛,HMAC 计算
18
+ * 本身也在守卫内——任何调用方/配置输入都无法越出「永不抛错」的校验边界;
19
+ * - 注入时钟本身失效(getTime 非有限值或回调抛错)→ fail-closed `token_invalid`:
20
+ * `NaN > expiresMs` 恒 false,曾把过期 token 静默判成有效——无效时间上
21
+ * 不产生任何接受;
22
+ * - 篡改/过期/格式错三类失败都走 ShareFailureReason 同一闭集。
23
+ */
24
+
25
+ import { createHmac, timingSafeEqual } from 'node:crypto'
26
+
27
+ import type { ShareChannel, ShareFailureReason } from './adapters.ts'
28
+
29
+ export interface ShareTokenTarget {
30
+ channel: ShareChannel
31
+ address: string
32
+ }
33
+
34
+ export interface ShareTokenPayload {
35
+ share_id: string
36
+ created_at: string
37
+ ttl_seconds: number
38
+ /** 目的地绑定:token 只对签发时的 target 有效,换收件人即 token_invalid */
39
+ target: ShareTokenTarget
40
+ }
41
+
42
+ export type ShareTokenVerifyResult =
43
+ | { ok: true; payload: ShareTokenPayload }
44
+ | { ok: false; reason: ShareFailureReason }
45
+
46
+ /** 显式 dev 默认 secret——生产环境必须由 `SHARE_HMAC_SECRET` env 覆盖 */
47
+ export const DEFAULT_DEV_SHARE_SECRET = 'gotry-share-dev-secret-DO-NOT-USE-IN-PROD'
48
+
49
+ /** ttl 上界(秒):2^31-1,防 created_at + ttl*1000 溢出 Number 上限 */
50
+ export const SHARE_TOKEN_TTL_MAX_SECONDS = 2_147_483_647
51
+
52
+ /** 获取运行期 secret:env 优先;production 缺 env 时 fail-closed(dev 常量签生产 token = 任何人可伪造) */
53
+ export function resolveShareSecret(env: NodeJS.ProcessEnv = process.env): string {
54
+ const s = env.SHARE_HMAC_SECRET
55
+ if (typeof s === 'string' && s.length > 0) return s
56
+ if (env.NODE_ENV === 'production') {
57
+ throw new Error('SHARE_HMAC_SECRET 未设置且 NODE_ENV=production:拒绝回落公开的 dev 默认 secret(fail-closed;任何读到仓库的人都能伪造 token)')
58
+ }
59
+ return DEFAULT_DEV_SHARE_SECRET
60
+ }
61
+
62
+ /** 签名:payload → base64url(JSON) + '.' + base64url(HMAC-SHA256(body, secret)) */
63
+ export function signShareToken(payload: ShareTokenPayload, secret: string = resolveShareSecret()): string {
64
+ const body = Buffer.from(JSON.stringify(payload), 'utf-8').toString('base64url')
65
+ const sig = createHmac('sha256', secret).update(body).digest('base64url')
66
+ return `${body}.${sig}`
67
+ }
68
+
69
+ function isTokenTarget(value: unknown): value is ShareTokenTarget {
70
+ if (typeof value !== 'object' || value === null) return false
71
+ const t = value as Record<string, unknown>
72
+ return typeof t.channel === 'string' && t.channel.length > 0
73
+ && typeof t.address === 'string'
74
+ }
75
+
76
+ /** 校验:secret 解析(守卫体)→ 格式(恰一个点)→ HMAC 等值(timingSafeEqual)
77
+ * → payload 形态 → 过期(注入时钟失效 = token_invalid)。**永不抛错**:
78
+ * production 缺 env secret 与失效时钟都是操作面错误,收敛进 token_invalid,
79
+ * 刻意的配置/签发异常只保留在 resolve/sign 侧。 */
80
+ export function verifyShareToken(
81
+ token: string,
82
+ secret?: string,
83
+ now: () => Date = () => new Date(),
84
+ ): ShareTokenVerifyResult {
85
+ // 运行期 secret 解析放进守卫体:production 缺 env 的配置错在验证面 fail-closed
86
+ // 为 token_invalid,不抛错(若静默回落公开 dev 常量,伪造 token 将被放行);
87
+ // 非字符串运行期键(数字/对象/Symbol 等 JS 畸形调用方输入)同样收敛
88
+ // token_invalid——createHmac 对它们会抛 TypeError,绝不让异常越出本函数
89
+ let hmacSecret: string
90
+ try {
91
+ const resolved = secret === undefined ? resolveShareSecret() : secret
92
+ if (typeof resolved !== 'string') return { ok: false, reason: 'token_invalid' }
93
+ hmacSecret = resolved
94
+ } catch {
95
+ return { ok: false, reason: 'token_invalid' }
96
+ }
97
+ if (typeof token !== 'string' || token.length === 0) return { ok: false, reason: 'token_invalid' }
98
+ const dot = token.indexOf('.')
99
+ // 恰一个点:多点(base64url 解码器会静默吞非法字符)与无点都拒绝
100
+ if (dot <= 0 || dot === token.length - 1) return { ok: false, reason: 'token_invalid' }
101
+ if (token.indexOf('.', dot + 1) !== -1) return { ok: false, reason: 'token_invalid' }
102
+ const body = token.slice(0, dot)
103
+ const sig = token.slice(dot + 1)
104
+
105
+ // HMAC 等值比较(先长度,再 timingSafeEqual;Buffer-vs-Buffer);加密计算
106
+ // 本身也在守卫内——任何运行期键异常收敛 token_invalid,绝不外泄异常
107
+ let expected: Buffer
108
+ try {
109
+ expected = createHmac('sha256', hmacSecret).update(body).digest()
110
+ } catch {
111
+ return { ok: false, reason: 'token_invalid' }
112
+ }
113
+ let actual: Buffer
114
+ try {
115
+ actual = Buffer.from(sig, 'base64url')
116
+ } catch {
117
+ return { ok: false, reason: 'token_invalid' }
118
+ }
119
+ if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) {
120
+ return { ok: false, reason: 'token_invalid' }
121
+ }
122
+
123
+ // 解析 payload
124
+ let payload: ShareTokenPayload
125
+ try {
126
+ const json = Buffer.from(body, 'base64url').toString('utf-8')
127
+ payload = JSON.parse(json)
128
+ } catch {
129
+ return { ok: false, reason: 'token_invalid' }
130
+ }
131
+ if (typeof payload !== 'object' || payload === null
132
+ || typeof payload.share_id !== 'string' || payload.share_id.length === 0
133
+ || typeof payload.created_at !== 'string' || payload.created_at.length === 0
134
+ || !isTokenTarget(payload.target)) {
135
+ return { ok: false, reason: 'token_invalid' }
136
+ }
137
+ // ttl:非负整数且不溢出(防 created_at + ttl*1000 = Infinity 永不过期)
138
+ if (typeof payload.ttl_seconds !== 'number'
139
+ || !Number.isInteger(payload.ttl_seconds)
140
+ || payload.ttl_seconds < 0
141
+ || payload.ttl_seconds > SHARE_TOKEN_TTL_MAX_SECONDS) {
142
+ return { ok: false, reason: 'token_invalid' }
143
+ }
144
+
145
+ // 过期检查:注入时钟失效(抛错/非有限值)fail-closed 为 token_invalid——
146
+ // NaN 与 expiresMs 比较恒 false,失效时钟不得让任何 token 通过
147
+ const createdMs = Date.parse(payload.created_at)
148
+ if (!Number.isFinite(createdMs)) return { ok: false, reason: 'token_invalid' }
149
+ const expiresMs = createdMs + payload.ttl_seconds * 1000
150
+ if (!Number.isFinite(expiresMs)) return { ok: false, reason: 'token_invalid' }
151
+ let nowMs: number
152
+ try {
153
+ nowMs = now().getTime()
154
+ } catch {
155
+ return { ok: false, reason: 'token_invalid' }
156
+ }
157
+ if (!Number.isFinite(nowMs)) return { ok: false, reason: 'token_invalid' }
158
+ if (nowMs > expiresMs) return { ok: false, reason: 'token_expired' }
159
+
160
+ return { ok: true, payload }
161
+ }
162
+
163
+ /** target 绑定比对:token payload 的 target 必须与请求的 target 完全一致(通道+地址逐字段) */
164
+ export function tokenTargetMatches(payload: ShareTokenPayload, target: { channel: unknown; address: unknown }): boolean {
165
+ return payload.target.channel === target.channel && payload.target.address === target.address
166
+ }
@@ -0,0 +1,172 @@
1
+ /**
2
+ * 槽位→日期解析层(D-10 切片 A):把 travel_slot_extraction.v1 的逐字时间表达
3
+ * 在代码层换算为绝对日期——「tool-owned dates」的执行面。
4
+ *
5
+ * ADR-12 复审结论(2026-08-27,D-10 赎回触发):设计成立,但解析范围必须**有界**——
6
+ * 只解析锚点卡词表内的表达(今天/明天/后天/大后天/本周X/下周X/下下周X/下个月初|中旬|下旬)
7
+ * 与绝对表达(ISO/点分/中文月日,parseAbsoluteDate)+ 槽位约定后缀「+N」;
8
+ * 词表外(近期/这阵子/next Monday/英文月名…)一律 unresolved 逐字保留,
9
+ * 不做开放式中文相对日期解析(ADR-12 被拒备选:维护黑洞)。
10
+ *
11
+ * 本层是纯函数:不碰求解器、不改入参;工具查询/spec 一致性闸的接线属后续切片。
12
+ */
13
+
14
+ import { parseAbsoluteDate, ymd, type TimeAnchor } from './time-anchor.ts'
15
+ import type { TravelSlotExtraction } from './travel-slots.ts'
16
+
17
+ export type SlotDateKind = 'absolute' | 'card' | 'unresolved'
18
+
19
+ export interface SlotDateResolution {
20
+ /** 用户原话(逐字) */
21
+ raw: string
22
+ /** 换算结果 YYYY-MM-DD;unresolved 时 null */
23
+ date: string | null
24
+ kind: SlotDateKind
25
+ }
26
+
27
+ const WEEKDAY_ZH: Record<string, number> = { 日: 0, 一: 1, 二: 2, 三: 3, 四: 4, 五: 5, 六: 6 }
28
+
29
+ function addDaysYmd(today: string, n: number): string {
30
+ const [y, m, d] = today.split('-').map(Number)
31
+ return ymd(new Date(y, m - 1, d + n))
32
+ }
33
+
34
+ /** 「下周五+3」「8.20+2天」后缀:base + N 天(槽位规则 5/6 的拼接约定) */
35
+ function splitPlusSuffix(expr: string): { base: string; plusDays: number } {
36
+ const m = expr.match(/^(.*?)\+(\d+)天?$/)
37
+ if (m && m[1]) return { base: m[1], plusDays: Number(m[2]) }
38
+ return { base: expr, plusDays: 0 }
39
+ }
40
+
41
+ /** 锚点卡近邻日词表(今天/明天/后天/大后天)→ 相对今天的偏移天数;词表外 null */
42
+ function neighborDayOffset(expr: string): number | null {
43
+ if (expr === '今天') return 0
44
+ if (expr === '明天') return 1
45
+ if (expr === '后天') return 2
46
+ if (expr === '大后天') return 3
47
+ return null
48
+ }
49
+
50
+ /** 锚点卡词表周表达(本周X/下周X/下下周X)→ 相对今天的偏移天数;词表外 null。周一分界,与锚点卡一致 */
51
+ function weekdayOffsetDays(expr: string, today: string): number | null {
52
+ const m = expr.match(/^(本|下|下下)周([日一二三四五六])$/)
53
+ if (!m || !m[2]) return null
54
+ const target = WEEKDAY_ZH[m[2]]
55
+ if (target === undefined) return null
56
+ const [y, mm, d] = today.split('-').map(Number)
57
+ const todayMonOffset = (new Date(y, mm - 1, d).getDay() + 6) % 7
58
+ const targetMonOffset = (target + 6) % 7
59
+ const weekShift = m[1] === '本' ? 0 : m[1] === '下' ? 7 : 14
60
+ return weekShift + targetMonOffset - todayMonOffset
61
+ }
62
+
63
+ /** 锚点卡月分段词表(下个月初/中旬/下旬)→ 该分段首日;词表外 null(保守取首日,宁可早不可晚) */
64
+ function monthFragmentDate(expr: string, today: string): string | null {
65
+ if (!['下个月初', '下个月中旬', '下个月下旬'].includes(expr)) return null
66
+ const [y, m] = today.split('-').map(Number)
67
+ const day = expr === '下个月初' ? 1 : expr === '下个月中旬' ? 11 : 21
68
+ return ymd(new Date(y, m, day))
69
+ }
70
+
71
+ /**
72
+ * 逐字时间表达 → 绝对日期。顺序:绝对表达 → 「+N」后缀拆解 → 锚点卡词表 → unresolved。
73
+ * kind 告知下游证据等级:absolute/card 可直接用于工具查询;unresolved 必须原文透传给人/模型。
74
+ */
75
+ export function resolveSlotDate(expr: string, anchor: TimeAnchor): SlotDateResolution {
76
+ const raw = expr.trim()
77
+ const year = Number(anchor.today.slice(0, 4))
78
+
79
+ const absolute = parseAbsoluteDate(raw, year)
80
+ if (absolute) return { raw, date: absolute, kind: 'absolute' }
81
+
82
+ const { base, plusDays } = splitPlusSuffix(raw)
83
+ const baseAbs = parseAbsoluteDate(base, year)
84
+ if (baseAbs) return { raw, date: addDaysYmd(baseAbs, plusDays), kind: 'absolute' }
85
+
86
+ const month = monthFragmentDate(base, anchor.today)
87
+ if (month) return { raw, date: addDaysYmd(month, plusDays), kind: 'card' }
88
+
89
+ const neighbor = neighborDayOffset(base)
90
+ if (neighbor !== null) return { raw, date: addDaysYmd(anchor.today, neighbor + plusDays), kind: 'card' }
91
+
92
+ const offset = weekdayOffsetDays(base, anchor.today)
93
+ if (offset !== null) return { raw, date: addDaysYmd(anchor.today, offset + plusDays), kind: 'card' }
94
+
95
+ return { raw, date: null, kind: 'unresolved' }
96
+ }
97
+
98
+ /** 各域的日期槽位字段(解析覆盖面:主日期 + 回程/退房) */
99
+ const DATE_FIELDS: Record<string, string[]> = {
100
+ requisition: ['start_date', 'end_date'],
101
+ flight: ['departure_date', 'return_date'],
102
+ hotel: ['check_in_date', 'check_out_date'],
103
+ }
104
+
105
+ export interface ResolvedSlots {
106
+ requisition?: { start_date?: SlotDateResolution; end_date?: SlotDateResolution }
107
+ flight?: { departure_date?: SlotDateResolution; return_date?: SlotDateResolution }
108
+ hotel?: { check_in_date?: SlotDateResolution; check_out_date?: SlotDateResolution }
109
+ /** 词表外表达清单(field = "<domain>.<field>"),逐字保留等下游(人/模型)裁决 */
110
+ unresolved: Array<{ field: string; raw: string }>
111
+ }
112
+
113
+ /** 整张抽取的日期解析(纯函数,不改入参):只处理日期槽位,目的地/偏好等不在此层 */
114
+ export function resolveSlots(ext: TravelSlotExtraction, anchor: TimeAnchor): ResolvedSlots {
115
+ const out: ResolvedSlots = { unresolved: [] }
116
+ for (const domain of ext.domains) {
117
+ const slots = ext.slots[domain] as Record<string, unknown> | undefined
118
+ if (!slots) continue
119
+ for (const field of DATE_FIELDS[domain] ?? []) {
120
+ const value = slots[field]
121
+ if (typeof value !== 'string') continue
122
+ const res = resolveSlotDate(value, anchor)
123
+ const bucket = (out[domain as keyof Omit<ResolvedSlots, 'unresolved'>] ??= {}) as Record<string, SlotDateResolution>
124
+ bucket[field] = res
125
+ if (res.kind === 'unresolved') out.unresolved.push({ field: `${domain}.${field}`, raw: res.raw })
126
+ }
127
+ }
128
+ return out
129
+ }
130
+
131
+ export interface SpecDateMismatch {
132
+ /** spec 侧位置,如 segments[0].date */
133
+ specAt: string
134
+ field: string
135
+ specDate: string
136
+ slotDate: string
137
+ }
138
+
139
+ /**
140
+ * spec ↔ 槽位日期一致性闸(ADR-10 翻译≠造数的执行面):LLM 产出的 JourneySpecTS 日期
141
+ * 与代码层换算的槽位日期逐项比对,分歧即返回 mismatch(供渲染 red-flag/追问),不静默采信。
142
+ *
143
+ * 范围边界(2026-08-28 巡检修正):槽位 v1 只有 trip 级主日期(start/departure/check-in),
144
+ * **只校验恰好一个带日期段的 spec**;多段行程的逐段日期没有槽位真值可比(不比,不造假阳性
145
+ * ——金标准六段行程曾被全段误判分歧,求解被永久拦截)。spec 无日期或槽位 unresolved 不参与。
146
+ */
147
+ export function specDateMismatches(
148
+ spec: { segments?: Array<{ date?: string }> },
149
+ resolved: ResolvedSlots,
150
+ ): SpecDateMismatch[] {
151
+ const mismatches: SpecDateMismatch[] = []
152
+ const primary: Array<{ field: string; res?: SlotDateResolution }> = [
153
+ { field: 'requisition.start_date', res: resolved.requisition?.start_date },
154
+ { field: 'flight.departure_date', res: resolved.flight?.departure_date },
155
+ { field: 'hotel.check_in_date', res: resolved.hotel?.check_in_date },
156
+ ]
157
+ const dated = primary.filter((p): p is { field: string; res: SlotDateResolution } => p.res?.date != null)
158
+ if (dated.length === 0) return mismatches
159
+ const datedSegs = (spec.segments ?? []).filter(s => typeof s.date === 'string' && s.date)
160
+ if (datedSegs.length !== 1) return mismatches // 多段(或零段)无逐段真值,闸不判
161
+ const seg = datedSegs[0]!
162
+ const slotDates = new Set(dated.map(s => s.res.date as string))
163
+ if (!slotDates.has(seg.date as string)) {
164
+ mismatches.push({
165
+ specAt: `segments[${(spec.segments ?? []).indexOf(seg)}].date`,
166
+ field: dated.map(s => s.field).join('|'),
167
+ specDate: seg.date as string,
168
+ slotDate: [...slotDates].join('|'),
169
+ })
170
+ }
171
+ return mismatches
172
+ }