@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,279 @@
1
+ /**
2
+ * dsh artifact view isolated Host contract proof (issue #285).
3
+ *
4
+ * 真实执行:在临时 stateRoot/cwd 下装载 gotry-tools 插件,触发 gotry_artifacts_list
5
+ * + gotry_artifacts_read 的 execute + output.presentationMeta + presentResult,断言
6
+ * DSH 0.2.0-rc.2 的 Host ToolResult contract(SearchPathsResultView /
7
+ * ReadResultView / GenericCallView.locations),并跑一次隔离 select → preview →
8
+ * modify → view-updated 文件读取循环。
9
+ *
10
+ * 本脚本不代替 Web renderer E2E:它证明的是 DSH host 装载 → 真实 execute →
11
+ * 持久化 meta → Host presenter contract。fresh-profile Web custom-card 路径由
12
+ * 显式命令 `npx tsx scripts/dsh-artifact-web-e2e.ts` 另行覆盖;该浏览器命令
13
+ * 不属于跨平台 full suite。
14
+ *
15
+ * 隔离:全临时目录;不写 gotry-state;结束即删。
16
+ */
17
+ import assert from 'node:assert/strict';
18
+ import { mkdtempSync, rmSync, writeFileSync, appendFileSync, mkdirSync } from 'node:fs';
19
+ import { tmpdir } from 'node:os';
20
+ import { join } from 'node:path';
21
+ import { apply } from '../src/index.js';
22
+ function toolResult(tool, args, value) {
23
+ return {
24
+ isError: false,
25
+ content: tool.output.render(args, value),
26
+ meta: tool.output.presentationMeta?.(args, value),
27
+ };
28
+ }
29
+ async function main() {
30
+ // ── 1) 隔离环境 ─────────────────────────────────────────────────────────────
31
+ const home = mkdtempSync(join(tmpdir(), 'gotry-285-home-'));
32
+ const stateRoot = join(home, 'state');
33
+ const cwd = join(home, 'workspace');
34
+ mkdirSync(stateRoot, { recursive: true });
35
+ mkdirSync(cwd, { recursive: true });
36
+ // fixture:一个工作区 md,以及后续追加新内容
37
+ const fixturePath = join(cwd, 'trip-2027.md');
38
+ writeFileSync(fixturePath, [
39
+ '# 行程 2027',
40
+ '',
41
+ 'Day 1: 北京 → 曼谷',
42
+ 'Day 2: 曼谷 → 清迈',
43
+ 'Day 3: 清迈 → 清莱',
44
+ 'Day 4: 清莱 → 曼谷',
45
+ 'Day 5: 曼谷 → 北京',
46
+ ].join('\n'));
47
+ // ── 2) 装载 gotry-tools 插件(同 dsh host 装载路径:apply(ctx, config))─────
48
+ const registered = [];
49
+ const sections = [];
50
+ const variables = {};
51
+ const preExecutes = [];
52
+ const ctx = {
53
+ tools: { register: (t) => registered.push(t) },
54
+ systemPrompt: {
55
+ section: (s) => { sections.push(s); },
56
+ variable: (name, provider) => { variables[name] = provider; },
57
+ },
58
+ on: (event, fn) => {
59
+ if (event === 'tools/pre-execute')
60
+ preExecutes.push(fn);
61
+ return () => undefined;
62
+ },
63
+ };
64
+ apply(ctx, {
65
+ stateRoot,
66
+ timeoutMs: 30_000,
67
+ hbcliBin: 'hbcli-not-on-path',
68
+ sessionAccess: 'off',
69
+ });
70
+ const exec = { agent: { session: { header: { cwd } } } };
71
+ const byName = (n) => {
72
+ const t = registered.find(t => t.name === n);
73
+ if (!t)
74
+ throw new Error(`FAIL: 插件装载后未找到 ${n},已注册: ${registered.map(t => t.name).join(',')}`);
75
+ return t;
76
+ };
77
+ // ── 3) select 阶段:gotry_artifacts_list 真实 execute + presentResult ─────
78
+ const listTool = byName('gotry_artifacts_list');
79
+ const listPayload = await listTool.execute({ limit: 20 }, exec);
80
+ assert.equal(listPayload.ok, true, 'list execute 应 ok');
81
+ assert.ok(Array.isArray(listPayload.artifacts) && listPayload.artifacts.length >= 1, 'list 应发现 fixture md');
82
+ const fixtureEntry = listPayload.artifacts.find(a => a.path?.endsWith('/trip-2027.md'));
83
+ assert.ok(fixtureEntry, `list 应包含 trip-2027.md,实际: ${listPayload.artifacts.map(a => a.path).join(',')}`);
84
+ console.log(`[1/4] SELECT list.execute → ${listPayload.artifacts.length} 项 (含 fixture trip-2027.md)`);
85
+ const listView = listTool.presentResult?.({}, toolResult(listTool, {}, listPayload));
86
+ assert.equal(listView?.card, 'search', 'list card 应为 "search" (SearchPathsResultView)');
87
+ assert.equal(listView?.shape, 'paths', 'list shape 应为 "paths" (SearchPathsResultView)');
88
+ assert.ok(Array.isArray(listView?.paths), 'list paths 应为数组(UI 渲染 deliverables 列表直接绑路径)');
89
+ assert.deepEqual(listView?.paths, listPayload.artifacts.map(a => a.path), 'list paths 数组应与 artifacts 顺序一致');
90
+ assert.equal(listView?.total, listPayload.total, 'list total 应与 execute 一致');
91
+ assert.equal(listView?.truncated, Boolean(listPayload.truncated), 'list truncated 应与 execute 一致');
92
+ const listFallback = listTool.output.render({}, listPayload);
93
+ assert.ok((listFallback[0]?.text ?? '').length > 0, 'list output.render 应带 summary,供无 search 卡能力的 UI fallback');
94
+ console.log(`[1/4] CONTRACT list → SearchPathsResultView{ card:'search', shape:'paths', paths:[${listView.paths.length}], total=${listView.total}, truncated=${listView.truncated} }`);
95
+ // ── 4) preview 阶段:gotry_artifacts_read 真实 execute + presentResult ───
96
+ const readTool = byName('gotry_artifacts_read');
97
+ const readCall = readTool.presentCall?.({ path: 'trip-2027.md' });
98
+ assert.equal(readCall?.kind, 'read', 'read presentCall kind 应为 "read"(editor follow-along)');
99
+ assert.ok(Array.isArray(readCall?.locations), 'read presentCall locations 应为数组');
100
+ assert.equal(readCall?.locations?.[0]?.path, 'trip-2027.md', 'read locations[0].path 应等于目标路径');
101
+ assert.equal(readCall?.locations?.[0]?.line, 1, 'read locations[0].line 应为 1(call 阶段就锁住身份)');
102
+ console.log(`[2/4] PREVIEW read.presentCall → GenericCallView{ kind:'read', locations:[{path:'trip-2027.md',line:1}] }`);
103
+ const read1Payload = await readTool.execute({ path: 'trip-2027.md' }, exec);
104
+ assert.equal(read1Payload.ok, true, 'read 应 ok');
105
+ assert.equal(read1Payload.source, 'cwd', 'read 在 cwd 中应分类为 cwd source');
106
+ assert.equal(read1Payload.totalLines, 7, 'fixture 7 行(标题+空行+5 day+空尾)');
107
+ assert.equal(read1Payload.lines?.[0]?.number, 1, '首行 number 应为 1(file line numbering 保留)');
108
+ assert.ok(read1Payload.lines?.[0]?.text.includes('行程 2027'), '首行应为标题');
109
+ assert.equal(read1Payload.lang, 'markdown', '扩展名映射 lang=markdown');
110
+ console.log(`[2/4] PREVIEW read.execute → { source:'${read1Payload.source}', totalLines:${read1Payload.totalLines}, lines:[${read1Payload.lines?.length}], lang:'${read1Payload.lang}' }`);
111
+ const read1View = readTool.presentResult?.({ path: 'trip-2027.md' }, toolResult(readTool, { path: 'trip-2027.md' }, read1Payload));
112
+ assert.equal(read1View?.card, 'read', 'read card 应为 "read" (ReadResultView)');
113
+ assert.equal(read1View?.path, read1Payload.path, 'read view path 应等于 execute path');
114
+ assert.equal(read1View?.offset, read1Payload.offset, 'read view offset 应保留(call→result 一致)');
115
+ assert.equal(read1View?.lines?.length, read1Payload.lines?.length, 'read view lines 长度应等于 execute lines');
116
+ assert.equal(read1View?.totalLines, read1Payload.totalLines, 'read view totalLines 应等于 execute totalLines');
117
+ assert.equal(read1View?.lang, 'markdown', 'read view lang 应为 markdown');
118
+ const identity = read1View?.content?.[0]?.text ?? '';
119
+ assert.ok(identity.includes('source:'), 'read fallback content[0] 应含 source 身份行');
120
+ assert.ok(identity.includes('cwd'), `read identity 应明示 source=cwd,实际: ${identity}`);
121
+ assert.ok(identity.includes(read1Payload.path ?? ''), 'read identity 应含完整 path(便于 UI 高亮与跳转)');
122
+ assert.ok((read1View?.content?.[1]?.text ?? '').includes('行程 2027'), 'read fallback content[1] 应为正文');
123
+ console.log(`[2/4] CONTRACT read → ReadResultView{ card:'read', path:'${read1View.path}', totalLines:${read1View.totalLines}, identity:'${identity.slice(0, 80)}...' }`);
124
+ // ── 5) modify 阶段:写入新内容到 fixture(模拟 agent/用户在侧栏修产物)──
125
+ appendFileSync(fixturePath, '\nDay 6: 曼谷 → 普吉\nDay 7: 普吉 → 曼谷\nDay 8: 曼谷 → 北京');
126
+ console.log(`[3/4] MODIFY fixture 追加 3 行,模拟产物版本变更`);
127
+ // ── 6) view-updated 阶段:再 read,断言看到新版本 ───────────────────────
128
+ const read2Payload = await readTool.execute({ path: 'trip-2027.md' }, exec);
129
+ assert.equal(read2Payload.ok, true, 'view-updated read 应 ok');
130
+ assert.equal(read2Payload.totalLines, 10, '新版本 totalLines 应为 10(原 7 + 3)');
131
+ assert.ok(read2Payload.lines?.[0]?.text.includes('行程 2027'), 'view-updated 首行仍为标题');
132
+ assert.ok(read2Payload.lines?.some(l => l.text.includes('Day 6')), 'view-updated 应包含新追加 Day 6');
133
+ const read2View = readTool.presentResult?.({ path: 'trip-2027.md' }, toolResult(readTool, { path: 'trip-2027.md' }, read2Payload));
134
+ assert.equal(read2View?.totalLines, 10, 'view-updated ReadResultView totalLines 应等于 10');
135
+ assert.ok((read2View?.content?.[1]?.text ?? '').includes('Day 6'), 'view-updated fallback content 应含 Day 6(UI 重新打开产物拿到最新版本)');
136
+ console.log(`[3/4] VIEW-UPDATED read.execute → { totalLines:${read2Payload.totalLines}, lines:[${read2Payload.lines?.length}] },ReadResultView.content 含 Day 6`);
137
+ // ── 7) 边界:越界路径 / 非白名单扩展名 / 不存在文件 ────────────────────
138
+ const outOfScope = await readTool.execute({ path: '../../../../etc/passwd' }, exec);
139
+ assert.equal(outOfScope.ok, false, '越界路径必须被拒');
140
+ assert.ok(/scope|outside|workspace|越界/i.test(outOfScope.error ?? ''), `越界错误信息应明示 scope,实际: ${outOfScope.error}`);
141
+ console.log(`[4/4] GUARDRAIL 越界路径拒 ok=false,error 含 scope 类字样`);
142
+ const notFound = await readTool.execute({ path: 'never-written.md' }, exec);
143
+ assert.equal(notFound.ok, false, '不存在文件应 ok=false(不静默 ok)');
144
+ assert.ok(/not found|不存在/i.test(notFound.error ?? ''), `不存在错误信息应明示 not found,实际: ${notFound.error}`);
145
+ console.log(`[4/4] GUARDRAIL 不存在文件拒 ok=false,error 含 not-found 类字样`);
146
+ // ── 8) issue #458:registered-plugin list → pagination/search → read → Host 演示 ──
147
+ // >50 混合源(账本 + legacy + cwd)fixture,stable tie-break / dedupe / filtered total /
148
+ // safe args,经 registerGuarded → defineTool 真实 execute + presentResult,证明
149
+ // DSH host 装载的产物工具体表里 #458 的新参数(limit/offset/search)在 host presenter
150
+ // 层面仍然保持 SearchPathsResultView contract(paths/total/truncated)。
151
+ //
152
+ // 注意:不重新 apply() —— 插件装载由外层统一完成,这里直接在外层已注册的工具上
153
+ // 切换 session cwd/stateRoot;fixture 全部写入外层的 stateRoot / workspace,确保
154
+ // 真实 execute 走到的就是同一份 list tool 闭包。
155
+ try {
156
+ const issue458Root = stateRoot;
157
+ const issue458Cwd = cwd;
158
+ // 账本 2:cap-mix-a / cap-mix-b
159
+ const { ensureLedger } = await import('../src/state-ledger.js');
160
+ const ledger = ensureLedger(issue458Root);
161
+ ledger.createWorkflowRun({ id: 'cap-mix-a', goal: '账本权威 a', ticket: { objective: 'mix' }, state: {} });
162
+ ledger.settleWorkflowRun('cap-mix-a', '# mix a\nD1 大理\nD2 洱海\n');
163
+ ledger.createWorkflowRun({ id: 'cap-mix-b', goal: '账本权威 b', ticket: { objective: 'mix' }, state: {} });
164
+ ledger.settleWorkflowRun('cap-mix-b', '# mix b\nD1 西双版纳\nD2 普洱\n');
165
+ // legacy 文件视图 2(无 ledger authority)
166
+ mkdirSync(join(issue458Root, 'gotry-state', 'async'), { recursive: true });
167
+ writeFileSync(join(issue458Root, 'gotry-state', 'async', 'legacy-1.deliverable.md'), '# legacy\n');
168
+ writeFileSync(join(issue458Root, 'gotry-state', 'async', 'legacy-2.deliverable.md'), '# legacy\n');
169
+ // cwd 60 fixture,带 mtime 严格递增 + 1 个 mtime 很老的"老产物"。
170
+ // 注:外层 fixture(trip-2027.md)在 cwd 中,mtime 大约 = 此刻,会落在最新区段;
171
+ // 这里特意让 note-* mtime 起点 = UTC 2026-01-01 00:00:00,小于 trip-2027.md,
172
+ // 排序仍稳定(cwd-file source 同,按 id 词典序作 tie-break)。
173
+ const { utimesSync } = await import('node:fs');
174
+ for (let i = 0; i < 60; i++) {
175
+ const name = `note-${String(i).padStart(3, '0')}.md`;
176
+ const p = join(issue458Cwd, name);
177
+ writeFileSync(p, `# ${name}\nbody\n`);
178
+ utimesSync(p, new Date(Date.UTC(2026, 0, 1, 0, 0, i)), new Date(Date.UTC(2026, 0, 1, 0, 0, i)));
179
+ }
180
+ writeFileSync(join(issue458Cwd, 'special-deliverable.md'), '# special\nbody\n');
181
+ utimesSync(join(issue458Cwd, 'special-deliverable.md'), new Date('2020-01-01T00:00:00Z'), new Date('2020-01-01T00:00:00Z'));
182
+ const hostList = listTool;
183
+ const hostRead = readTool;
184
+ const hostExec = exec;
185
+ // a) 真实分页 — 不带 search,limit=20,offset=0 → page1
186
+ const page1 = await hostList.execute({ limit: 20 }, hostExec);
187
+ assert.equal(page1.ok, true, 'page1 execute 应 ok');
188
+ assert.equal(page1.artifacts?.length, 20, `page1 长度应 20,实际 ${page1.artifacts?.length}`);
189
+ assert.equal(page1.total, 66, `page1 total 应 66(2 账本 + 2 legacy + 60 cwd + 1 老 + 1 trip-2027),实际 ${page1.total}`);
190
+ assert.equal(page1.truncated, true, 'page1 truncated 应 true');
191
+ assert.equal(page1.nextOffset, 20, `page1 nextOffset 应 20,实际 ${page1.nextOffset}`);
192
+ assert.equal(page1.limit, 20, `page1 limit echo 应 20`);
193
+ assert.equal(page1.offset, 0, `page1 offset echo 应 0`);
194
+ const page1View = hostList.presentResult?.({}, toolResult(hostList, {}, page1));
195
+ assert.equal(page1View?.card, 'search', '分页仍应保持 SearchPathsResultView card');
196
+ assert.equal(page1View?.shape, 'paths', '分页仍应保持 SearchPathsResultView shape');
197
+ assert.equal(page1View?.paths?.length, 20, 'presenter paths 长度应等于 page1.artifacts.length');
198
+ assert.equal(page1View?.total, 66, 'presenter total 应等于 execute total');
199
+ assert.equal(page1View?.truncated, true, 'presenter truncated 应等于 execute truncated');
200
+ console.log(`[5/7] #458 page1 → 20 项 / total=66 / truncated=true / SearchPathsResultView contract OK`);
201
+ // b) 翻页 — page2/3/4 拼起来必须唯一覆盖全部 65 条
202
+ const page2 = await hostList.execute({ limit: 20, offset: 20 }, hostExec);
203
+ const page3 = await hostList.execute({ limit: 20, offset: 40 }, hostExec);
204
+ const page4 = await hostList.execute({ limit: 20, offset: 60 }, hostExec);
205
+ const all = new Set();
206
+ for (const p of [page1, page2, page3, page4]) {
207
+ for (const a of p.artifacts ?? [])
208
+ all.add(String(a.path));
209
+ }
210
+ assert.equal(all.size, 66, `page1..page4 拼接后 66 个唯一 path,实际 ${all.size}`);
211
+ assert.equal(page4.artifacts?.length, 6, `page4 应 6 条,实际 ${page4.artifacts?.length}`);
212
+ assert.equal(page4.truncated, false, `page4 已无更多,truncated=false`);
213
+ assert.equal(page4.nextOffset, undefined, `page4 无 nextOffset`);
214
+ assert.equal(page4.offset, 60, `page4 offset echo 应回填请求值 60`);
215
+ console.log(`[5/7] #458 page2/3/4 拼接唯一覆盖 66 条,page4=6 / truncated=false / offset=60 OK`);
216
+ // c) search — 即使 limit=1,也能直接命中老产物
217
+ const direct = await hostList.execute({ limit: 1, search: 'special-deliverable' }, hostExec);
218
+ assert.equal(direct.total, 1, `search='special-deliverable' 应命中 1 条`);
219
+ assert.equal(direct.artifacts?.length, 1);
220
+ assert.equal(direct.truncated, false);
221
+ assert.equal(direct.search, 'special-deliverable', 'search 应回填 trim 后值');
222
+ assert.ok(direct.artifacts?.[0]?.path?.endsWith('/special-deliverable.md'), `应命中老产物 path`);
223
+ const directView = hostList.presentResult?.({ search: 'special-deliverable' }, toolResult(hostList, { search: 'special-deliverable' }, direct));
224
+ assert.equal(directView?.total, 1, 'search presentResult.total 应 = 1');
225
+ assert.equal(directView?.paths?.length, 1, 'search presentResult.paths 应 = 1');
226
+ console.log(`[5/7] #458 search='special-deliverable' → limit=1 直接命中老产物,total=1 / search echo OK`);
227
+ // d) safe args:无效 offset / limit / search 经 execute 透传到能力层应被拒,
228
+ // registered tool 仍以 ok:false 包出(无未捕获 throw 越过 host 边界)。
229
+ // DSH host 的 schema 类型校验在最外层兜底,某些坏参会先由 schema 拒绝 →
230
+ // guardToolExecute 包成 ok:false + summary;另一些(超出 schema 范围但
231
+ // 类型仍合法)则走 capability 层 normalize* 拒绝 → error 字段。两条路径
232
+ // 都必须非 ok=true,且含相应字段名。
233
+ const badOffset = await hostList.execute({ offset: -1 }, hostExec);
234
+ assert.equal(badOffset.ok, false, '负 offset 必须被拒 ok=false');
235
+ assert.ok(/offset/i.test(String(badOffset.error ?? badOffset.summary ?? '')), `错误应含 offset 描述,实际 ${badOffset.error ?? badOffset.summary}`);
236
+ // 字符串 limit:host schema 类型校验兜底(summary 路径)
237
+ const badLimit = await hostList.execute({ limit: '20' }, hostExec);
238
+ assert.equal(badLimit.ok, false, '字符串 limit 必须被拒 ok=false');
239
+ assert.ok(/limit/i.test(String(badLimit.error ?? badLimit.summary ?? '')), `错误应含 limit 描述,实际 ${badLimit.error ?? badLimit.summary}`);
240
+ // 非字符串 search:host schema 同样兜底
241
+ const badSearch = await hostList.execute({ search: 5 }, hostExec);
242
+ assert.equal(badSearch.ok, false, '非字符串 search 必须被拒 ok=false');
243
+ assert.ok(/search/i.test(String(badSearch.error ?? badSearch.summary ?? '')), `错误应含 search 描述,实际 ${badSearch.error ?? badSearch.summary}`);
244
+ // unsafe 整数 offset:能力层 Number.isSafeInteger 边界,registered tool 必须同步拒
245
+ const unsafeOffset = await hostList.execute({ offset: Number.MAX_SAFE_INTEGER + 1 }, hostExec);
246
+ assert.equal(unsafeOffset.ok, false, 'unsafe 整数 offset 必须被拒 ok=false');
247
+ assert.ok(/offset/i.test(String(unsafeOffset.error ?? unsafeOffset.summary ?? '')), `错误应含 offset 描述,实际 ${unsafeOffset.error ?? unsafeOffset.summary}`);
248
+ console.log(`[5/7] #458 safe args:offset=-1 / limit='20' / search=5 / unsafe-integer offset 全部 ok=false,error/summary 含字段名 OK`);
249
+ // e) list→read 实际串联 — 用 search 结果的 path 走 readArtifact,断言 presentResult 仍 ok
250
+ const listViewPath = direct.artifacts[0].path;
251
+ const readByPath = await hostRead.execute({ path: listViewPath }, hostExec);
252
+ assert.equal(readByPath.ok, true, 'list 串联 read 应 ok');
253
+ assert.equal(readByPath.source, 'cwd', '老产物 source 应 cwd');
254
+ assert.equal(readByPath.lang, 'markdown');
255
+ const readView = hostRead.presentResult?.({ path: listViewPath }, toolResult(hostRead, { path: listViewPath }, readByPath));
256
+ assert.equal(readView?.card, 'read', 'list→read 串联 read card 应仍 read');
257
+ assert.equal(readView?.totalLines, readByPath.totalLines);
258
+ console.log(`[5/7] #458 list→read 串联:search 命中的 path 经 readArtifact 返回 OK,ReadResultView contract 保持 OK`);
259
+ // f) 越界 page(请求 offset=9999)→ 空页 + 已知 total + 无 nextOffset
260
+ const beyond = await hostList.execute({ offset: 9999 }, hostExec);
261
+ assert.equal(beyond.ok, true);
262
+ assert.equal(beyond.artifacts?.length, 0, `越界应空页,实际 ${beyond.artifacts?.length}`);
263
+ assert.equal(beyond.total, 66, `越界仍应回填 total=66,实际 ${beyond.total}`);
264
+ assert.equal(beyond.truncated, false, `越界 truncated=false`);
265
+ assert.equal(beyond.nextOffset, undefined, `越界无 nextOffset`);
266
+ assert.equal(beyond.offset, 9999, `越界 offset echo 应回填请求值 9999`);
267
+ const beyondSummary = String(beyond.summary ?? '');
268
+ assert.ok(!/无在册产物/.test(beyondSummary), `越界 summary 不得误报「无在册产物」,实际: ${beyondSummary}`);
269
+ assert.ok(beyondSummary.includes('空页') && beyondSummary.includes('66'), `越界 summary 应明示空页 + known total,实际: ${beyondSummary}`);
270
+ console.log(`[5/7] #458 越界页:empty page + total=66 + 无 nextOffset + summary 明示空页/known total OK`);
271
+ }
272
+ catch (err) {
273
+ throw err;
274
+ }
275
+ // ── 清理 ────────────────────────────────────────────────────────────────
276
+ rmSync(home, { recursive: true, force: true });
277
+ console.log('\nDSH ARTIFACT HOST CONTRACT PROOF: list/read metadata, source identity, view-updated loop, guardrails OK; fresh-profile Web custom-card path covered separately by `npx tsx scripts/dsh-artifact-web-e2e.ts` (not part of the cross-platform full suite)');
278
+ }
279
+ await main();