@danceiny/gotry 0.0.1-rc.9 → 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 (507) hide show
  1. package/README.md +172 -219
  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 -56
  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 +947 -110
  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 +50 -44
  42. package/dist/capabilities/session/adapters/ctrip-flight.js +120 -62
  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 +35 -54
  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 +31 -21
  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 +75 -24
  56. package/dist/capabilities/session/static-flight-golden.js +150 -0
  57. package/dist/capabilities/session/transport.js +97 -83
  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 +635 -44
  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 +24 -59
  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 +50 -11
  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 +25 -70
  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 +382 -246
  191. package/dist/scripts/ledger-workflow-crash.js +10 -20
  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 +18 -52
  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 +24 -12
  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 +39 -28
  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 +20 -20
  227. package/dist/scripts/session-attach-poc.js +34 -37
  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 +14 -35
  231. package/dist/scripts/session-link-tests.js +478 -0
  232. package/dist/scripts/session-login.js +27 -46
  233. package/dist/scripts/session-tests.js +796 -96
  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 +690 -246
  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 +226 -101
  253. package/dist/scripts/state-cli.js +550 -199
  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 +29 -93
  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 +48 -74
  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 +2227 -882
  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 +319 -160
  325. package/dist/src/memory-capture.js +180 -32
  326. package/dist/src/memory-decay.js +30 -14
  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 +435 -516
  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 +44 -63
  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 +535 -359
  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 +293 -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 +1948 -198
  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 +223 -25
  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 +354 -88
  506. package/ts/src/wish-pool.ts +79 -0
  507. package/dist/scripts/session-attach-wait.js +0 -41
@@ -0,0 +1,58 @@
1
+ /** OSRM public server client — free route fallback (no API key). */
2
+ import { formatLngLat } from '../types.js';
3
+ const PUBLIC_OSRM = 'https://router.project-osrm.org';
4
+ export class OsrmClient {
5
+ opts;
6
+ constructor(opts) {
7
+ this.opts = opts;
8
+ }
9
+ /**
10
+ * Plan a route. `profile` maps to OSRM profiles: driving | walking | cycling.
11
+ * OSRM has no transit profile — callers must not request transit here.
12
+ */
13
+ async route(origin, destination, profile, signal) {
14
+ const url = new URL(`${this.opts.baseUrl ?? PUBLIC_OSRM}/route/v1/${profile}/${formatLngLat(origin)};${formatLngLat(destination)}`);
15
+ url.searchParams.set('overview', 'full');
16
+ url.searchParams.set('geometries', 'geojson');
17
+ url.searchParams.set('steps', 'true');
18
+ let res;
19
+ try {
20
+ res = await fetch(url, { signal, headers: { Accept: 'application/json' } });
21
+ }
22
+ catch (err) {
23
+ const reason = err instanceof Error ? err.message : String(err);
24
+ throw new Error(`无法访问 OSRM 免费路线服务(${reason})。部分网络环境下该服务不可达,建议在插件配置中设置高德 amapKey(https://console.amap.com/dev/key/app)以获得稳定的路线规划。`);
25
+ }
26
+ if (!res.ok)
27
+ throw new Error(`OSRM HTTP ${res.status}: ${res.statusText}`);
28
+ const body = (await res.json());
29
+ if (body.code !== 'Ok' || !body.routes?.length) {
30
+ throw new Error(`OSRM error: ${body.code ?? 'unknown'} (no route between the given points)`);
31
+ }
32
+ const route = body.routes[0];
33
+ const steps = [];
34
+ for (const leg of route.legs ?? []) {
35
+ for (const s of leg.steps ?? []) {
36
+ const modifier = s.maneuver?.modifier ? ` (${s.maneuver.modifier})` : '';
37
+ steps.push({
38
+ instruction: `${s.maneuver?.instruction ?? 'continue'} ${s.name ?? ''}${modifier}`.trim(),
39
+ distanceM: s.distance ?? 0,
40
+ durationS: s.duration ?? 0,
41
+ });
42
+ }
43
+ }
44
+ const points = typeof route.geometry === 'string'
45
+ ? []
46
+ : (route.geometry.coordinates ?? []).map(([lng, lat]) => [lng, lat]);
47
+ return {
48
+ provider: 'osrm',
49
+ distanceM: route.distance ?? 0,
50
+ durationS: route.duration ?? 0,
51
+ polyline: JSON.stringify(route.geometry),
52
+ points,
53
+ // OSRM 的 `overview=full` 就是完整路线几何,直接复用。
54
+ geometry: points,
55
+ steps,
56
+ };
57
+ }
58
+ }
@@ -0,0 +1,55 @@
1
+ const PUBLIC_PHOTON = 'https://photon.komoot.io';
2
+ export class PhotonClient {
3
+ opts;
4
+ constructor(opts) {
5
+ this.opts = opts;
6
+ }
7
+ async get(path, params, signal) {
8
+ const url = new URL(`${this.opts.baseUrl ?? PUBLIC_PHOTON}${path}`);
9
+ for (const [k, v] of Object.entries(params))
10
+ url.searchParams.set(k, v);
11
+ let res;
12
+ try {
13
+ res = await fetch(url, { signal, headers: { Accept: 'application/json' } });
14
+ }
15
+ catch (err) {
16
+ const reason = err instanceof Error ? err.message : String(err);
17
+ throw new Error(`无法访问 Photon 免费地理编码服务(${reason})。部分网络环境下该服务不可达,建议在插件配置中设置高德 amapKey(https://console.amap.com/dev/key/app)以获得稳定的地理编码。`);
18
+ }
19
+ if (!res.ok)
20
+ throw new Error(`Photon HTTP ${res.status}: ${res.statusText}`);
21
+ return res.json();
22
+ }
23
+ /** Forward geocode. */
24
+ async geocode(query, signal) {
25
+ const body = (await this.get('/api/', { q: query, limit: '1', lang: this.opts.lang ?? 'zh' }, signal));
26
+ const first = body.features?.[0];
27
+ if (!first?.geometry?.coordinates) {
28
+ throw new Error(`免费地理编码未找到该地址:${query}。请尝试提供 "lng,lat" 坐标,或配置高德 amapKey 获得更全的地址库。`);
29
+ }
30
+ const [lng, lat] = first.geometry.coordinates;
31
+ const props = first.properties ?? {};
32
+ return {
33
+ provider: 'photon',
34
+ formatted: props.name ?? query,
35
+ location: [lng, lat],
36
+ city: props.city,
37
+ district: props.state,
38
+ };
39
+ }
40
+ /** Reverse geocode. */
41
+ async reverseGeocode(location, signal) {
42
+ const body = (await this.get('/reverse', { lon: String(location[0]), lat: String(location[1]) }, signal));
43
+ const first = body.features?.[0];
44
+ if (!first)
45
+ throw new Error('Photon reverse geocode returned no result');
46
+ const props = first.properties ?? {};
47
+ return {
48
+ provider: 'photon',
49
+ formatted: [props.name, props.city, props.state].filter(Boolean).join(',') || `${location[0]},${location[1]}`,
50
+ location,
51
+ city: props.city,
52
+ district: props.state,
53
+ };
54
+ }
55
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * dsh-map-tools persisted config file (~/.dsh-map-tools/config.json).
3
+ *
4
+ * Follows the modlens pattern: the plugin's API keys and provider choice live
5
+ * in its own file (shared across profiles, never in the DSH settings
6
+ * document), and the settings card reads/writes it through a loopback route.
7
+ */
8
+ import { mkdirSync, readFileSync, writeFileSync, lstatSync } from 'node:fs';
9
+ import { homedir } from 'node:os';
10
+ import { dirname, join } from 'node:path';
11
+ /** The file the plugin's settings card reads and writes. Overridable for tests. */
12
+ export function configPath() {
13
+ const override = process.env.DSH_MAP_TOOLS_CONFIG;
14
+ return override !== undefined && override !== ''
15
+ ? override
16
+ : join(homedir(), '.dsh-map-tools', 'config.json');
17
+ }
18
+ /**
19
+ * Read the shared config, or a thrown error. Only a missing file reads as
20
+ * empty: an existing-but-unparsable file is somebody's configuration, and a
21
+ * card that treated it as empty would overwrite it on the next save.
22
+ */
23
+ export function readConfig() {
24
+ let raw;
25
+ try {
26
+ raw = readFileSync(configPath(), 'utf8');
27
+ }
28
+ catch (error) {
29
+ if (error?.code === 'ENOENT')
30
+ return {};
31
+ throw new Error(`cannot read ${configPath()}: ${error?.message ?? error}`);
32
+ }
33
+ let parsed;
34
+ try {
35
+ parsed = JSON.parse(raw);
36
+ }
37
+ catch (error) {
38
+ throw new Error(`cannot parse ${configPath()}: ${error?.message ?? error}`);
39
+ }
40
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
41
+ throw new Error(`${configPath()} must hold a JSON object`);
42
+ }
43
+ return parsed;
44
+ }
45
+ /** Deprecated config keys, purged on every save (Baidu provider dropped in 0.3.0). */
46
+ const DEPRECATED_KEYS = ['baiduAk'];
47
+ /** Persist a patch onto the config file, then return the new whole. */
48
+ export function applyConfig(patch) {
49
+ const current = readConfig();
50
+ for (const key of ['provider', 'amapKey', 'timeoutMs', 'maxQps']) {
51
+ if (patch[key] !== undefined) {
52
+ if (key === 'amapKey' && patch.amapKey === '')
53
+ delete current.amapKey;
54
+ else
55
+ current[key] = patch[key];
56
+ }
57
+ }
58
+ // Purge deprecated fields (e.g. baiduAk from the pre-0.3.0 Baidu provider)
59
+ // so dead keys don't linger in the config file.
60
+ for (const key of DEPRECATED_KEYS) {
61
+ if (key in current)
62
+ delete current[key];
63
+ }
64
+ mkdirSync(dirname(configPath()), { recursive: true });
65
+ writeFileSync(configPath(), `${JSON.stringify(current, null, 2)}\n`, { mode: 0o600 });
66
+ return current;
67
+ }
68
+ /** Whether the config file exists (the card can offer "open config file"). */
69
+ export function configFileExists() {
70
+ try {
71
+ lstatSync(configPath());
72
+ return true;
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }
78
+ /** Non-secret summary served to the settings card (keys are never echoed). */
79
+ export function configSummary() {
80
+ const c = readConfig();
81
+ return {
82
+ provider: c.provider,
83
+ timeoutMs: c.timeoutMs,
84
+ maxQps: c.maxQps,
85
+ hasAmapKey: typeof c.amapKey === 'string' && c.amapKey !== '',
86
+ };
87
+ }
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Loopback settings-card route for dsh-map-tools.
3
+ *
4
+ * GET /dsh-map-tools/config → non-secret summary (has-amap-key, …)
5
+ * GET /dsh-map-tools/config?open=true → open the config file in the editor
6
+ * POST /dsh-map-tools/config → apply a provider/key/timeout patch
7
+ *
8
+ * Same-origin loopback only (mirrors dsh's own /api fence and the modlens
9
+ * pattern); the two halves of the card read/write a real file.
10
+ */
11
+ import { spawn } from 'node:child_process';
12
+ import { configSummary, applyConfig, configPath, configFileExists } from './config-file.js';
13
+ /** localhost, ::1, or anything in 127/8 — matching dsh's own /api fence. */
14
+ function isLoopbackHost(hostname) {
15
+ return hostname === 'localhost' || hostname === '::1' || hostname === '127.0.0.1' || /^127\.\d+\.\d+\.\d+$/.test(hostname);
16
+ }
17
+ /** Refuse cross-origin and non-loopback requests (the route answers same-origin loopback only). */
18
+ export function isTrustedRequest(req) {
19
+ const host = req.headers?.host;
20
+ if (typeof host !== 'string' || host === '')
21
+ return false;
22
+ let hostUrl;
23
+ try {
24
+ hostUrl = new URL(`http://${host}`);
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ if (!isLoopbackHost(hostUrl.hostname))
30
+ return false;
31
+ if (req.headers?.['sec-fetch-site'] === 'cross-site')
32
+ return false;
33
+ const origin = req.headers?.origin;
34
+ if (origin === undefined)
35
+ return true;
36
+ try {
37
+ return new URL(origin).host === hostUrl.host;
38
+ }
39
+ catch {
40
+ return false;
41
+ }
42
+ }
43
+ /** Open the config file in the OS default editor. */
44
+ function openConfigFile() {
45
+ const file = configPath();
46
+ const [command, args] = process.platform === 'win32'
47
+ ? ['cmd', ['/c', 'start', '', file]]
48
+ : process.platform === 'darwin'
49
+ ? ['open', [file]]
50
+ : ['xdg-open', [file]];
51
+ const child = spawn(command, args, { detached: true, stdio: 'ignore' });
52
+ child.unref();
53
+ }
54
+ /**
55
+ * Register the settings-card route under the web server, when one exists.
56
+ *
57
+ * @param ctx - plugin context.
58
+ * @param reload - rebuild the tools after the card saves (the file write alone
59
+ * never reaches the registered tool instances; without this the new provider
60
+ * or key only takes effect on the next plugin reload).
61
+ */
62
+ export function installConfigRoute(ctx, reload = () => { }) {
63
+ const fn = ctx.inject;
64
+ fn(['webServer'], (scope) => {
65
+ // register() 的返回值是**唯一的**撤销手段(webserver 的 exact 表里同路径
66
+ // 重复注册会抛 "duplicate route",它不是 effect 自动托管的)。所以必须把它
67
+ // 挂到 effect 上:否则卸载后旧处理器留在表里,而重载时新注册撞重复报错——
68
+ // 那个错误落在 inject 子作用域内被静默吞掉,路由就永远停在上一个版本
69
+ // (现象:热替换后工具是新的、回环路由还是旧的)。
70
+ scope.effect(() => scope.webServer.register({
71
+ kind: 'exact',
72
+ path: '/dsh-map-tools/config',
73
+ handler: async (req, res) => {
74
+ const send = (status, body) => {
75
+ res.writeHead(status, { 'content-type': 'application/json' });
76
+ res.end(JSON.stringify(body));
77
+ };
78
+ if (!isTrustedRequest(req)) {
79
+ send(403, { error: 'request refused: this route answers same-origin loopback only' });
80
+ return;
81
+ }
82
+ if (req.method === 'GET') {
83
+ try {
84
+ const summary = configSummary();
85
+ const wantsOpen = new URL(req.url ?? '/', 'http://localhost').searchParams.has('open');
86
+ if (wantsOpen && !configFileExists()) {
87
+ applyConfig({});
88
+ }
89
+ if (wantsOpen)
90
+ openConfigFile();
91
+ send(200, { ...summary, configPath: configPath() });
92
+ }
93
+ catch (error) {
94
+ send(409, { error: String(error?.message ?? error) });
95
+ }
96
+ return;
97
+ }
98
+ if (req.method !== 'POST') {
99
+ res.writeHead(405).end();
100
+ return;
101
+ }
102
+ try {
103
+ const chunks = [];
104
+ let total = 0;
105
+ for await (const chunk of req) {
106
+ total += chunk.length;
107
+ if (total > 64 * 1024) {
108
+ send(413, { error: 'config payload too large' });
109
+ req.destroy();
110
+ return;
111
+ }
112
+ chunks.push(chunk);
113
+ }
114
+ const patch = JSON.parse(Buffer.concat(chunks).toString('utf8'));
115
+ applyConfig({
116
+ provider: patch.provider,
117
+ amapKey: patch.amapKey,
118
+ timeoutMs: typeof patch.timeoutMs === 'number' ? patch.timeoutMs : undefined,
119
+ });
120
+ send(200, configSummary());
121
+ // Rebuild the tool instances so the saved provider/key/timeout is
122
+ // live immediately (the card tells the user "工具已重建").
123
+ reload();
124
+ }
125
+ catch (error) {
126
+ send(400, { error: String(error?.message ?? error) });
127
+ }
128
+ },
129
+ }));
130
+ });
131
+ }
@@ -0,0 +1,16 @@
1
+ /** Plugin configuration schema. */
2
+ import Schema from '@deepseek-ai/schemastery';
3
+ /** Amap apply URL (shown as a clickable link in the settings card). */
4
+ export const AMAP_APPLY_URL = 'https://console.amap.com/dev/key/app';
5
+ export const Config = Schema.object({
6
+ provider: Schema.union(['amap', 'osm'])
7
+ .default('amap')
8
+ .description('数据源:amap=高德地图(推荐,国内数据最全);osm=免费 OSM 兜底(无需 key,能力有限)'),
9
+ amapKey: Schema.string()
10
+ .role('secret')
11
+ .description(`高德 Web 服务 key。申请:${AMAP_APPLY_URL}(创建应用后选择"Web 服务"类型)`),
12
+ timeoutMs: Schema.number().default(15000).description('单次请求超时(毫秒)'),
13
+ maxQps: Schema.number().default(2).description('高德 API 每秒最大请求数(QPS 上限,默认 2 低于高德常见上限 3,防触发 10021 配额错误)'),
14
+ defaultMode: Schema.union(['driving', 'transit', 'walking', 'bicycling']).default('driving').description('默认路线模式'),
15
+ language: Schema.union(['zh', 'en']).default('zh').description('返回语言'),
16
+ });
@@ -0,0 +1,232 @@
1
+ /**
2
+ * 路线几何的纯函数工具:解码、抽稀、取整。
3
+ *
4
+ * 这些函数是 UI 卡片的输入准备层——它们决定"会话日志里到底存了多少个点"。
5
+ * 全是纯函数(无 I/O、无时钟、无随机),便于单元测试。
6
+ */
7
+ /** 会话日志里一条路线最多保留的几何点数(卡片是示意图,不需要原始精度)。 */
8
+ export const MAX_GEOMETRY_POINTS = 200;
9
+ /** 几何坐标保留的小数位:5 位约 1 米,足够画示意图,又能显著压缩体积。 */
10
+ const COORD_DECIMALS = 5;
11
+ /** 浮点取整到固定小数位(去掉 -0)。 */
12
+ function round(value, decimals) {
13
+ const f = 10 ** decimals;
14
+ const r = Math.round(value * f) / f;
15
+ return Object.is(r, -0) ? 0 : r;
16
+ }
17
+ /** 一个坐标是否是可用的经纬度。 */
18
+ function isValidLngLat(point) {
19
+ return (point !== undefined
20
+ && Number.isFinite(point[0])
21
+ && Number.isFinite(point[1])
22
+ && point[0] >= -180
23
+ && point[0] <= 180
24
+ && point[1] >= -90
25
+ && point[1] <= 90);
26
+ }
27
+ /**
28
+ * 解码高德的紧凑折线串 `"lng,lat;lng,lat;…"`。
29
+ * 非法片段被跳过(上游数据不可信,宁可少画一点也不抛错)。
30
+ * @param text - 高德 `polyline` 字段原文。
31
+ * @returns 解析出的坐标序列(可能为空)。
32
+ */
33
+ export function decodeAmapPolyline(text) {
34
+ if (typeof text !== 'string' || text === '')
35
+ return [];
36
+ const points = [];
37
+ for (const chunk of text.split(';')) {
38
+ const parts = chunk.split(',');
39
+ if (parts.length !== 2)
40
+ continue;
41
+ const lng = Number(parts[0]);
42
+ const lat = Number(parts[1]);
43
+ const point = [lng, lat];
44
+ if (isValidLngLat(point))
45
+ points.push(point);
46
+ }
47
+ return points;
48
+ }
49
+ /** 去掉相邻重复点(按取整后的坐标比较),并丢弃非法点。 */
50
+ export function dedupeGeometry(points) {
51
+ const out = [];
52
+ let lastKey = '';
53
+ for (const point of points) {
54
+ if (!isValidLngLat(point))
55
+ continue;
56
+ const key = `${round(point[0], COORD_DECIMALS)},${round(point[1], COORD_DECIMALS)}`;
57
+ if (key === lastKey)
58
+ continue;
59
+ lastKey = key;
60
+ out.push([round(point[0], COORD_DECIMALS), round(point[1], COORD_DECIMALS)]);
61
+ }
62
+ return out;
63
+ }
64
+ /** 把坐标投到"等距近似"平面(x 按纬度做 cos 收缩),用于距离比较。 */
65
+ function flatten(point, scaleX) {
66
+ return [point[0] * scaleX, point[1]];
67
+ }
68
+ /** 点到线段的垂距(平面近似)。 */
69
+ function perpendicularDistance(point, a, b) {
70
+ const dx = b[0] - a[0];
71
+ const dy = b[1] - a[1];
72
+ if (dx === 0 && dy === 0)
73
+ return Math.hypot(point[0] - a[0], point[1] - a[1]);
74
+ const t = ((point[0] - a[0]) * dx + (point[1] - a[1]) * dy) / (dx * dx + dy * dy);
75
+ const clamped = t < 0 ? 0 : t > 1 ? 1 : t;
76
+ return Math.hypot(point[0] - (a[0] + clamped * dx), point[1] - (a[1] + clamped * dy));
77
+ }
78
+ /**
79
+ * Douglas–Peucker 抽稀(迭代实现,避免长路线的递归深度)。
80
+ * @param flat - 等距近似平面上的点序列。
81
+ * @param tolerance - 垂距阈值(与 `flat` 同单位)。
82
+ * @returns 保留点的下标,升序,必含首尾。
83
+ */
84
+ function douglasPeucker(flat, tolerance) {
85
+ const n = flat.length;
86
+ if (n <= 2)
87
+ return n === 2 ? [0, 1] : [0];
88
+ const keep = new Array(n).fill(false);
89
+ keep[0] = true;
90
+ keep[n - 1] = true;
91
+ const stack = [[0, n - 1]];
92
+ while (stack.length > 0) {
93
+ const range = stack.pop();
94
+ if (range === undefined)
95
+ break;
96
+ const [first, last] = range;
97
+ if (last <= first + 1)
98
+ continue;
99
+ let maxDistance = -1;
100
+ let maxIndex = -1;
101
+ for (let i = first + 1; i < last; i += 1) {
102
+ const distance = perpendicularDistance(flat[i], flat[first], flat[last]);
103
+ if (distance > maxDistance) {
104
+ maxDistance = distance;
105
+ maxIndex = i;
106
+ }
107
+ }
108
+ if (maxIndex >= 0 && maxDistance > tolerance) {
109
+ keep[maxIndex] = true;
110
+ stack.push([first, maxIndex], [maxIndex, last]);
111
+ }
112
+ }
113
+ const indices = [];
114
+ for (let i = 0; i < n; i += 1)
115
+ if (keep[i])
116
+ indices.push(i);
117
+ return indices;
118
+ }
119
+ /** 等间隔抽稀到不超过 `maxPoints` 个点(抽稀兜底,保留首尾)。 */
120
+ function decimate(indices, maxPoints) {
121
+ if (indices.length <= maxPoints)
122
+ return [...indices];
123
+ const out = [];
124
+ const step = (indices.length - 1) / (maxPoints - 1);
125
+ for (let i = 0; i < maxPoints; i += 1) {
126
+ const index = indices[Math.round(i * step)];
127
+ if (index !== undefined && out[out.length - 1] !== index)
128
+ out.push(index);
129
+ }
130
+ const last = indices[indices.length - 1];
131
+ if (last !== undefined && out[out.length - 1] !== last)
132
+ out.push(last);
133
+ return out;
134
+ }
135
+ /**
136
+ * 抽稀一条路线几何,使其点数不超过 `maxPoints`。
137
+ *
138
+ * 阈值从包围盒对角线推导(自适应:长途粗、短途细——40 公里路线约 40 米,
139
+ * 200 米步行路线约 0.2 米),逐步放宽直到达标;若 Douglas–Peucker 仍不达标
140
+ * (例如密集的锯齿路径),再做等间隔兜底。首尾点始终保留,坐标统一取整到
141
+ * 5 位小数。
142
+ *
143
+ * 注意:即使点数没超上限也会跑一遍抽稀——直线上的冗余点同样要丢掉,
144
+ * 因为产物要写进会话日志。
145
+ *
146
+ * @param points - 原始几何点(可为空、可含重复/非法点)。
147
+ * @param maxPoints - 点数上限,默认 {@link MAX_GEOMETRY_POINTS}。
148
+ * @returns 抽稀并取整后的几何(点数 ≤ `maxPoints`)。
149
+ */
150
+ export function simplifyGeometry(points, maxPoints = MAX_GEOMETRY_POINTS) {
151
+ const limit = Math.max(2, Math.floor(maxPoints));
152
+ const clean = dedupeGeometry(points);
153
+ if (clean.length <= 2)
154
+ return clean;
155
+ const lat0 = clean.reduce((sum, point) => sum + point[1], 0) / clean.length;
156
+ const scaleX = Math.max(0.01, Math.cos((lat0 * Math.PI) / 180));
157
+ const flat = clean.map((point) => flatten(point, scaleX));
158
+ let minX = Infinity;
159
+ let minY = Infinity;
160
+ let maxX = -Infinity;
161
+ let maxY = -Infinity;
162
+ for (const [x, y] of flat) {
163
+ if (x < minX)
164
+ minX = x;
165
+ if (x > maxX)
166
+ maxX = x;
167
+ if (y < minY)
168
+ minY = y;
169
+ if (y > maxY)
170
+ maxY = y;
171
+ }
172
+ const diagonal = Math.hypot(maxX - minX, maxY - minY);
173
+ // 初始阈值:对角线千分之一;随后逐次放宽,最多 12 轮(≈4000 倍)。
174
+ let tolerance = Math.max(diagonal / 1000, 1e-7);
175
+ let indices = douglasPeucker(flat, tolerance);
176
+ for (let i = 0; i < 12 && indices.length > limit; i += 1) {
177
+ tolerance *= 2;
178
+ indices = douglasPeucker(flat, tolerance);
179
+ }
180
+ if (indices.length > limit)
181
+ indices = decimate(indices, limit);
182
+ return indices.map((index) => clean[index]).filter(isValidLngLat);
183
+ }
184
+ /**
185
+ * 把几何压成高德风格的紧凑串 `"lng,lat;lng,lat"`(日志体积的一档压缩)。
186
+ * @param points - 已取整的几何点。
187
+ * @returns 紧凑串;空序列返回空串。
188
+ */
189
+ export function encodeGeometry(points) {
190
+ return points.map((point) => `${point[0]},${point[1]}`).join(';');
191
+ }
192
+ /**
193
+ * 把高德的长地址裁成可读的短地名。
194
+ *
195
+ * 高德反查返回的 `formatted_address` 是"省市区街道 + 具体位置"连写(如
196
+ * "北京市丰台区右安门街道北京南站")。把已知的省/市/区/街道前缀依次剥掉、
197
+ * 再去掉尾部括号补充,剩下的就是用户认得的那个名字。
198
+ * 剥完为空则原样返回(宁可长,也不要空)。
199
+ *
200
+ * @param formatted - 高德 `formatted_address`。
201
+ * @param strip - 要剥掉的前缀(省 / 市 / 区 / 街道)。
202
+ * @returns 短地名。
203
+ */
204
+ export function shortPlaceName(formatted, strip) {
205
+ const original = (formatted ?? '').trim();
206
+ const prefixes = strip.filter((part) => typeof part === 'string' && part !== '');
207
+ let text = original;
208
+ // 反复剥直到没得剥:这样与传入顺序无关("朝阳区" 在 "北京市" 之后也能剥掉),
209
+ // 且前缀重复出现时也能剥干净。每个前缀都非空,所以一定会终止。
210
+ for (let changed = true; changed;) {
211
+ changed = false;
212
+ for (const part of prefixes) {
213
+ if (text.startsWith(part)) {
214
+ text = text.slice(part.length);
215
+ changed = true;
216
+ }
217
+ }
218
+ }
219
+ // 去掉尾部的括号补充("…国际机场(2号通道)" → "…国际机场")。
220
+ text = text.replace(/[((][^))]*[))]\s*$/, '').trim();
221
+ return text === '' ? original : text;
222
+ }
223
+ /**
224
+ * 抽稀到最多 `maxPoints` 个点,再编成紧凑串(用于塞进 URL query)。
225
+ * 静态地图不需要 200 个点,太长会把 URL 撑爆。
226
+ * @param points - 路线几何。
227
+ * @param maxPoints - 点数上限。
228
+ * @returns `"lng,lat;…"`。
229
+ */
230
+ export function compactLine(points, maxPoints = 128) {
231
+ return encodeGeometry(simplifyGeometry(points, maxPoints));
232
+ }