@danceiny/gotry 0.0.1-rc.9 → 0.2.0-rc.28
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.
- package/README.md +172 -219
- package/README.zh-CN.md +222 -0
- package/bin/gotry-backend.js +53 -0
- package/bin/gotry-booking-copilot.js +53 -0
- package/bin/gotry-bootstrap.js +1788 -0
- package/bin/gotry-inner.js +733 -83
- package/bin/gotry-process-liveness.d.ts +27 -0
- package/bin/gotry-process-liveness.js +97 -0
- package/bin/gotry-runtime-resolution.d.ts +27 -0
- package/bin/gotry-runtime-resolution.js +49 -0
- package/bin/gotry.js +1 -1
- package/client/client.js +203 -0
- package/cordis.gotry-patch.yml +80 -56
- package/data/airline-airports.json +39 -0
- package/data/stations-12306-verify.json +524 -0
- package/dist/capabilities/agent-reach-deep.js +45 -122
- package/dist/capabilities/agent-reach.js +101 -146
- package/dist/capabilities/anything.js +161 -94
- package/dist/capabilities/artifacts.js +370 -0
- package/dist/capabilities/channel-health.js +131 -0
- package/dist/capabilities/channel-registry.js +256 -0
- package/dist/capabilities/doctor.js +553 -0
- package/dist/capabilities/effect.js +394 -0
- package/dist/capabilities/external-event.js +149 -0
- package/dist/capabilities/fact-log.js +55 -0
- package/dist/capabilities/flyai-config.js +337 -0
- package/dist/capabilities/flyai.js +947 -110
- package/dist/capabilities/fx-contract.js +293 -0
- package/dist/capabilities/geo-atlas.js +246 -0
- package/dist/capabilities/ground-transfer.js +676 -0
- package/dist/capabilities/hbcli.js +260 -123
- package/dist/capabilities/hotelbyte-transaction.js +194 -0
- package/dist/capabilities/incident-log.js +131 -61
- package/dist/capabilities/itinerary-artifact.js +190 -0
- package/dist/capabilities/itinerary-deck-artifact.js +194 -0
- package/dist/capabilities/itinerary-deck-export.js +339 -0
- package/dist/capabilities/lavish-local.js +924 -0
- package/dist/capabilities/model-override.js +38 -0
- package/dist/capabilities/opensky.js +54 -43
- package/dist/capabilities/provider-detail-sanitize.js +64 -0
- package/dist/capabilities/resilience.js +191 -0
- package/dist/capabilities/route-provider-conformance.js +341 -0
- package/dist/capabilities/session/action-cache.js +50 -44
- package/dist/capabilities/session/adapters/ctrip-flight.js +120 -62
- package/dist/capabilities/session/adapters/ctrip-hotel.js +222 -0
- package/dist/capabilities/session/adapters/dida-portal.js +274 -0
- package/dist/capabilities/session/adapters/meituan-local.js +35 -54
- package/dist/capabilities/session/adapters/rail-12306.js +342 -0
- package/dist/capabilities/session/benchmark.js +189 -0
- package/dist/capabilities/session/bridge-ledger.js +224 -0
- package/dist/capabilities/session/extension-bridge.js +636 -0
- package/dist/capabilities/session/extension-channel.js +109 -0
- package/dist/capabilities/session/extension-distribution.js +230 -0
- package/dist/capabilities/session/extract.js +31 -21
- package/dist/capabilities/session/golden-score.js +114 -0
- package/dist/capabilities/session/health-watch.js +215 -0
- package/dist/capabilities/session/read-guard.js +75 -24
- package/dist/capabilities/session/static-flight-golden.js +150 -0
- package/dist/capabilities/session/transport.js +97 -83
- package/dist/capabilities/session/wizard.js +117 -0
- package/dist/capabilities/session-consent.js +178 -0
- package/dist/capabilities/session-login.js +170 -0
- package/dist/capabilities/session-search.js +635 -44
- package/dist/capabilities/spawn-bounded.js +203 -0
- package/dist/capabilities/sponsor-plugin.js +341 -0
- package/dist/capabilities/visa-policy.js +140 -0
- package/dist/capabilities/weather.js +243 -138
- package/dist/data/session-golden-20.json +25 -0
- package/dist/data/sf-golden-manifest.json +103 -0
- package/dist/data/sf-static-routes.json +91 -0
- package/dist/scripts/action-cache-tests.js +24 -59
- package/dist/scripts/agent-planning-turn-deadline-e2e.js +242 -0
- package/dist/scripts/agent-planning-turn-deadline-tests.js +185 -0
- package/dist/scripts/agent-reach-deep-tests.js +30 -40
- package/dist/scripts/agent-reach-error-tests.js +354 -0
- package/dist/scripts/agent-reach-tests.js +26 -18
- package/dist/scripts/agent-reach-wrapper-tests.js +50 -50
- package/dist/scripts/anything-path-measure-tests.js +133 -0
- package/dist/scripts/anything-path-measure.js +150 -0
- package/dist/scripts/anything-tests.js +250 -60
- package/dist/scripts/artifact-client-contract-tests.js +220 -0
- package/dist/scripts/artifacts-capability-tests.js +727 -0
- package/dist/scripts/async-collect.js +50 -11
- package/dist/scripts/benchmark-environment-bridge-e2e.js +741 -0
- package/dist/scripts/benchmark-environment-bridge-tests.js +1452 -0
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +126 -0
- package/dist/scripts/booking-copilot-availability-policy-tests.js +265 -0
- package/dist/scripts/booking-copilot-bin-proof-tests.js +66 -0
- package/dist/scripts/booking-copilot-cleanup-proof-helper.js +76 -0
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +144 -0
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +424 -0
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +2839 -0
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +309 -0
- package/dist/scripts/booking-copilot-dsh-readiness-proof.js +238 -0
- package/dist/scripts/booking-copilot-dsh-warmer-proof.js +126 -0
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +156 -0
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +70 -0
- package/dist/scripts/booking-copilot-intent-proof-tests.js +422 -0
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +184 -0
- package/dist/scripts/booking-copilot-planner-live-probe.js +95 -0
- package/dist/scripts/booking-copilot-proof-runtime.js +42 -0
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +210 -0
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +2349 -0
- package/dist/scripts/booking-copilot-server-proof-tests.js +784 -0
- package/dist/scripts/booking-copilot-startup-proof-tests.js +94 -0
- package/dist/scripts/booking-executor-tests.js +80 -0
- package/dist/scripts/booking-recovery-chain-tests.js +182 -0
- package/dist/scripts/booking-saga-tests.js +125 -0
- package/dist/scripts/booking-surface-contract-proof-tests.js +212 -0
- package/dist/scripts/bootstrap-tests.js +1549 -0
- package/dist/scripts/bridge-events-tests.js +239 -0
- package/dist/scripts/bridge-ledger-tests.js +428 -0
- package/dist/scripts/build-changelog.js +238 -0
- package/dist/scripts/build-metrics-report.js +331 -0
- package/dist/scripts/changelog-tests.js +118 -0
- package/dist/scripts/channel-probe-tests.js +103 -0
- package/dist/scripts/channel-probe.js +169 -0
- package/dist/scripts/channel-registry-tests.js +208 -0
- package/dist/scripts/city-scenario-tier-tests.js +234 -0
- package/dist/scripts/companion-tests.js +25 -70
- package/dist/scripts/dida-cookie-probe.js +87 -0
- package/dist/scripts/dida-runner-stop-tests.js +311 -0
- package/dist/scripts/dida-sw-probe.js +114 -0
- package/dist/scripts/diff-test.js +17 -12
- package/dist/scripts/doctor-tests.js +600 -0
- package/dist/scripts/drill-multiuser-ledger-tests.js +1076 -0
- package/dist/scripts/drill-sdk-descendant-cleanup-tests.js +606 -0
- package/dist/scripts/drill-w2a-sensor-tests.js +788 -0
- package/dist/scripts/dsh-artifact-e2e.js +279 -0
- package/dist/scripts/dsh-artifact-web-e2e.js +675 -0
- package/dist/scripts/dsh-http-proxy-sse-proof.js +90 -0
- package/dist/scripts/dsh-llm-tests.js +437 -0
- package/dist/scripts/dsh-runtime-closure-tests.js +182 -0
- package/dist/scripts/dsh-runtime-closure.js +162 -0
- package/dist/scripts/dsh-session-v3-migration-proof.js +109 -0
- package/dist/scripts/dsh-subprocess-local-proof.js +150 -0
- package/dist/scripts/dsh-target-closure-proof.js +178 -0
- package/dist/scripts/effect-tests.js +539 -0
- package/dist/scripts/engine-run.js +1 -3
- package/dist/scripts/engine-tests.js +16 -10
- package/dist/scripts/evaluation-cadence-tests.js +174 -0
- package/dist/scripts/evaluation-contract-tests.js +268 -0
- package/dist/scripts/extension-distribution-cli.js +39 -0
- package/dist/scripts/extension-distribution-tests.js +443 -0
- package/dist/scripts/extension-tests.js +988 -0
- package/dist/scripts/external-event-tests.js +350 -0
- package/dist/scripts/fact-gate-tests.js +869 -0
- package/dist/scripts/fixtures/extension-bridge-unref-child.mjs +21 -0
- package/dist/scripts/flight-hotel-anchor-363-registered-e2e.js +169 -0
- package/dist/scripts/flight-malformed-tests.js +159 -0
- package/dist/scripts/flyai-setup-tests.js +228 -0
- package/dist/scripts/flyai-setup-tool-tests.js +54 -0
- package/dist/scripts/flyai-tests.js +692 -0
- package/dist/scripts/flyai-tool-registration-contract-tests.js +91 -0
- package/dist/scripts/fx-contract-tests.js +201 -0
- package/dist/scripts/g5-guard-tests.js +150 -0
- package/dist/scripts/g5-guard.js +193 -0
- package/dist/scripts/gen-lunar-anchors.js +106 -0
- package/dist/scripts/geo-atlas-tests.js +283 -0
- package/dist/scripts/gotry-backend-kernel-tests.js +206 -0
- package/dist/scripts/gotry-try-demo-tests.js +79 -0
- package/dist/scripts/gotry-try-demo.js +49 -0
- package/dist/scripts/ground-transfer-tests.js +956 -0
- package/dist/scripts/hbcli-e2e-tests.js +159 -0
- package/dist/scripts/hbcli-live-optin-tests.js +96 -0
- package/dist/scripts/hbcli-release-contract-tests.js +122 -0
- package/dist/scripts/hbcli-tests.js +121 -69
- package/dist/scripts/health-watch-cli.js +73 -0
- package/dist/scripts/hotel-date-gate-tests.js +496 -0
- package/dist/scripts/hotelbyte-reconcile-tests.js +141 -0
- package/dist/scripts/hotelbyte-spawn-e2e-tests.js +373 -0
- package/dist/scripts/i18n-tests.js +41 -0
- package/dist/scripts/incident-tests.js +281 -87
- package/dist/scripts/issue-194-job-id-guard-tests.js +106 -0
- package/dist/scripts/issue-233-cancel-refund-commission-tests.js +392 -0
- package/dist/scripts/issue-271-liveness-tests.js +569 -0
- package/dist/scripts/issue-289-model-retry-real-tests.js +296 -0
- package/dist/scripts/issue-289-model-retry-tests.js +441 -0
- package/dist/scripts/issue-289-web-retry-e2e.js +630 -0
- package/dist/scripts/issue-338-home-city-e2e.js +577 -0
- package/dist/scripts/issue343-real-entry-e2e.js +160 -0
- package/dist/scripts/issue436-persisted-routing-e2e.js +247 -0
- package/dist/scripts/itinerary-artifact-tests.js +368 -0
- package/dist/scripts/itinerary-deck-artifact-tests.js +416 -0
- package/dist/scripts/itinerary-deck-export-tests.js +552 -0
- package/dist/scripts/itinerary-deck-tests.js +435 -0
- package/dist/scripts/itinerary-html-tests.js +426 -0
- package/dist/scripts/journey-tests.js +22 -27
- package/dist/scripts/kernel-manifest-evidence.js +109 -0
- package/dist/scripts/kernel-manifest-gate.js +126 -0
- package/dist/scripts/kernel-manifest-tests.js +212 -0
- package/dist/scripts/kernel-manifest-trace-entry.js +7 -0
- package/dist/scripts/kernel-manifest-trace-hook.mjs +28 -0
- package/dist/scripts/kernel-manifest.js +369 -0
- package/dist/scripts/lavish-local-tests.js +1226 -0
- package/dist/scripts/lavish-product-tools-tests.js +537 -0
- package/dist/scripts/ledger-repair-apply-tests.js +316 -0
- package/dist/scripts/ledger-repair-plan-tests.js +375 -0
- package/dist/scripts/ledger-tests.js +382 -246
- package/dist/scripts/ledger-workflow-crash.js +10 -20
- package/dist/scripts/m3-cohort-tests.js +714 -0
- package/dist/scripts/m3-cohort.js +310 -0
- package/dist/scripts/managed-dsh-cleanup-diagnostic-proof.js +184 -0
- package/dist/scripts/managed-dsh-close-failure-proof.js +172 -0
- package/dist/scripts/managed-dsh-run-port-proof.js +153 -0
- package/dist/scripts/managed-dsh-terminal-proof.js +252 -0
- package/dist/scripts/map-tools-vendor-package-proof.js +365 -0
- package/dist/scripts/memory-capture-tests.js +242 -61
- package/dist/scripts/memory-decay-tests.js +18 -52
- package/dist/scripts/memory-lifecycle-tests.js +657 -0
- package/dist/scripts/memory-lifecycle.js +196 -0
- package/dist/scripts/memory-metrics.js +24 -12
- package/dist/scripts/memory-value-report.js +631 -0
- package/dist/scripts/memory-value-tests.js +328 -0
- package/dist/scripts/metrics-report-tests.js +151 -0
- package/dist/scripts/model-override-e2e.js +137 -0
- package/dist/scripts/nightly-evidence-tests.js +203 -0
- package/dist/scripts/nightly-evidence.js +303 -0
- package/dist/scripts/nudge-digest.js +39 -28
- package/dist/scripts/observability-tests.js +381 -0
- package/dist/scripts/onboarding-tests.js +161 -0
- package/dist/scripts/opensky-check.js +18 -13
- package/dist/scripts/opensky-tests.js +28 -28
- package/dist/scripts/outcome-projection-tests.js +427 -0
- package/dist/scripts/persona-sim-tests.js +603 -0
- package/dist/scripts/persona-sim.js +1081 -0
- package/dist/scripts/persona-surface-guard-tests.js +49 -0
- package/dist/scripts/pnpm-dsh-closure-proof.js +17 -0
- package/dist/scripts/policy-anchor-359-registered-e2e.js +214 -0
- package/dist/scripts/price-drift-tests.js +340 -0
- package/dist/scripts/price-drift-watch.js +447 -0
- package/dist/scripts/probe-poi-tests.js +53 -45
- package/dist/scripts/product-metrics.js +483 -0
- package/dist/scripts/publish-preverify.js +110 -0
- package/dist/scripts/realtime-pricing-tests.js +76 -0
- package/dist/scripts/recall-tests.js +513 -0
- package/dist/scripts/replay-async.js +22 -18
- package/dist/scripts/replay-real.js +18 -18
- package/dist/scripts/replay.js +54 -82
- package/dist/scripts/route-provider-conformance-tests.js +391 -0
- package/dist/scripts/session-attach-diagnose.js +20 -20
- package/dist/scripts/session-attach-poc.js +34 -37
- package/dist/scripts/session-benchmark.js +180 -0
- package/dist/scripts/session-dida-live-e2e.js +199 -0
- package/dist/scripts/session-extract-tests.js +14 -35
- package/dist/scripts/session-link-tests.js +478 -0
- package/dist/scripts/session-login.js +27 -46
- package/dist/scripts/session-tests.js +796 -96
- package/dist/scripts/session-zone-crash.js +49 -0
- package/dist/scripts/session-zone-ledger-tests.js +432 -0
- package/dist/scripts/session-zone-observation-tests.js +492 -0
- package/dist/scripts/session-zone-observe.js +135 -0
- package/dist/scripts/session-zone-wiring-tests.js +566 -0
- package/dist/scripts/session-zones-tests.js +374 -0
- package/dist/scripts/sf-live-benchmark.js +367 -0
- package/dist/scripts/sf-live-challenge-stop-tests.js +453 -0
- package/dist/scripts/sf-live-cli-tests.js +92 -0
- package/dist/scripts/sf-live-options.js +46 -0
- package/dist/scripts/sf-manifest-tests.js +30 -0
- package/dist/scripts/sf-manifest.js +33 -0
- package/dist/scripts/sf-soft-score-tests.js +67 -0
- package/dist/scripts/sf-summary-tests.js +324 -0
- package/dist/scripts/sf-summary.js +525 -0
- package/dist/scripts/share-tests.js +432 -0
- package/dist/scripts/skeleton-check.js +16 -14
- package/dist/scripts/skeleton-integration-test.js +28 -11
- package/dist/scripts/skills-contract-tests.js +51 -46
- package/dist/scripts/smoke-session-gate-tests.js +21 -0
- package/dist/scripts/smoke.js +690 -246
- package/dist/scripts/spawn-bounded-abort-tests.js +244 -0
- package/dist/scripts/sponsor-reuse-tests.js +262 -0
- package/dist/scripts/state-cli-tests.js +226 -101
- package/dist/scripts/state-cli.js +565 -198
- package/dist/scripts/state-repair-cli.js +66 -0
- package/dist/scripts/state-repair-tests.js +140 -0
- package/dist/scripts/static-golden-tests.js +165 -0
- package/dist/scripts/time-eval-tests.js +212 -192
- package/dist/scripts/travel-timeline-tests.js +29 -93
- package/dist/scripts/turn-handoff-collect-tests.js +169 -0
- package/dist/scripts/turn-handoff-collect.js +161 -0
- package/dist/scripts/turn-policy-tests.js +55 -0
- package/dist/scripts/typed-contract-canary.js +176 -0
- package/dist/scripts/tz-resolver-sanity.js +50 -0
- package/dist/scripts/tz-resolver-tests.js +584 -0
- package/dist/scripts/unified-tests.js +60 -20
- package/dist/scripts/visa-policy-tests.js +62 -0
- package/dist/scripts/weather-tests.js +276 -41
- package/dist/scripts/wish-channel-gate-tests.js +54 -0
- package/dist/scripts/write-gate-tests.js +522 -0
- package/dist/scripts/z3-lifecycle-fault-tests.js +188 -0
- package/dist/scripts/z3-lifecycle-tests.js +170 -0
- package/dist/scripts/z3-race-repeat-tests.js +39 -0
- package/dist/scripts/z3-race-tests.js +46 -0
- package/dist/src/artifact-gate.js +829 -0
- package/dist/src/backend/kernel.js +91 -0
- package/dist/src/backend/modules/booking-copilot.js +92 -0
- package/dist/src/backend/modules/booking-executor.js +124 -0
- package/dist/src/backend/modules/session-search.js +551 -0
- package/dist/src/benchmark-agent-conformance.js +578 -0
- package/dist/src/benchmark-environment-bridge.js +515 -0
- package/dist/src/benchmark-headless-child-diagnostics.js +166 -0
- package/dist/src/benchmark-tool-isolation.js +151 -0
- package/dist/src/bookable-facts.js +533 -0
- package/dist/src/booking-saga.js +97 -0
- package/dist/src/booking-surface/availability-policy.js +697 -0
- package/dist/src/booking-surface/booking-intent.js +43 -0
- package/dist/src/booking-surface/cancel-refund-commission.js +379 -0
- package/dist/src/booking-surface/canonical-schema.js +116 -0
- package/dist/src/booking-surface/contracts.js +75 -0
- package/dist/src/booking-surface/dsh-planner.js +1854 -0
- package/dist/src/booking-surface/dsh-plugin.js +378 -0
- package/dist/src/booking-surface/dsh-worker.js +98 -0
- package/dist/src/booking-surface/error-codes.js +231 -0
- package/dist/src/booking-surface/index.js +9 -0
- package/dist/src/booking-surface/managed-dsh-cleanup-diagnostic.js +97 -0
- package/dist/src/booking-surface/managed-dsh-run-port.js +244 -0
- package/dist/src/booking-surface/profile.js +24 -0
- package/dist/src/booking-surface/recovery-chain.js +367 -0
- package/dist/src/booking-surface/runtime.js +1968 -0
- package/dist/src/booking-surface/server.js +674 -0
- package/dist/src/booking-surface/startup.js +168 -0
- package/dist/src/booking-surface/validation.js +261 -0
- package/dist/src/bridge.js +20 -13
- package/dist/src/city-scenario-tier.js +378 -0
- package/dist/src/companions.js +48 -74
- package/dist/src/contracts.js +21 -43
- package/dist/src/dsh-llm.js +171 -115
- package/dist/src/engine.js +276 -193
- package/dist/src/evaluation-cadence.js +97 -0
- package/dist/src/evaluation-contracts.js +283 -0
- package/dist/src/flight-pack-adapter.js +54 -0
- package/dist/src/flight-pack-contract.js +2 -0
- package/dist/src/flyai-setup-tool.js +70 -0
- package/dist/src/gotry-backend.js +125 -0
- package/dist/src/hotel-date-gate.js +118 -0
- package/dist/src/i18n.js +88 -0
- package/dist/src/index.js +2385 -881
- package/dist/src/itinerary-deck.js +139 -0
- package/dist/src/itinerary-doc-shared.js +661 -0
- package/dist/src/itinerary-html.js +131 -0
- package/dist/src/journey.js +155 -108
- package/dist/src/lavish-tools.js +400 -0
- package/dist/src/ledger-repair-apply.js +538 -0
- package/dist/src/ledger-repair-plan.js +463 -0
- package/dist/src/loop.js +331 -161
- package/dist/src/m3-cohort.js +1577 -0
- package/dist/src/memory-capture.js +180 -32
- package/dist/src/memory-decay.js +30 -14
- package/dist/src/memory-lifecycle.js +1310 -0
- package/dist/src/memory-utility.js +27 -40
- package/dist/src/mock-llm.js +36 -61
- package/dist/src/model.js +81 -36
- package/dist/src/outcome-projection.js +746 -0
- package/dist/src/realtime-pricing.js +103 -0
- package/dist/src/recall/card.js +74 -0
- package/dist/src/recall/evaluator.js +140 -0
- package/dist/src/recall/integration.js +17 -0
- package/dist/src/recall/tick.js +166 -0
- package/dist/src/session-link/plan-it-action.js +48 -0
- package/dist/src/session-link/session-link.js +248 -0
- package/dist/src/session-zone-ledger.js +312 -0
- package/dist/src/session-zone-observation.js +354 -0
- package/dist/src/session-zone-wiring.js +658 -0
- package/dist/src/session-zones.js +510 -0
- package/dist/src/share/adapters.js +51 -0
- package/dist/src/share/share-consent.js +76 -0
- package/dist/src/share/share-deck.js +58 -0
- package/dist/src/share/share-token.js +146 -0
- package/dist/src/slot-spec.js +84 -106
- package/dist/src/state-ledger.js +696 -524
- package/dist/src/state-repair.js +299 -0
- package/dist/src/subagent-job-id-guard.js +58 -0
- package/dist/src/time-anchor.js +231 -33
- package/dist/src/tool-packet.js +20 -8
- package/dist/src/travel-slots.js +58 -35
- package/dist/src/travel-timeline.js +44 -63
- package/dist/src/turn-deadline.js +287 -0
- package/dist/src/turn-policy.js +118 -0
- package/dist/src/tz-resolver.js +143 -0
- package/dist/src/unified.js +600 -360
- package/dist/src/wish-pool.js +42 -12
- package/dist/src/write-gate.js +495 -0
- package/dist/src/z3-shared.js +284 -0
- package/extension/README.md +21 -0
- package/extension/README.zh-CN.md +21 -0
- package/extension/background.js +463 -0
- package/extension/content-bridge.js +270 -0
- package/extension/content-main.js +111 -0
- package/extension/manifest.json +60 -0
- package/package.json +407 -14
- package/schemas/booking.intent.schema.json +193 -0
- package/schemas/booking.surface.schema.json +2622 -0
- package/ts/capabilities/agent-reach-deep.ts +114 -0
- package/ts/capabilities/agent-reach.ts +198 -0
- package/ts/capabilities/anything.ts +282 -0
- package/ts/capabilities/artifacts.ts +428 -0
- package/ts/capabilities/fact-log.ts +54 -0
- package/ts/capabilities/flyai-config.ts +388 -0
- package/ts/capabilities/flyai.ts +1274 -0
- package/ts/capabilities/hbcli.ts +253 -71
- package/ts/capabilities/incident-log.ts +88 -59
- package/ts/capabilities/itinerary-artifact.ts +214 -0
- package/ts/capabilities/itinerary-deck-artifact.ts +218 -0
- package/ts/capabilities/itinerary-deck-export.ts +378 -0
- package/ts/capabilities/opensky.ts +121 -0
- package/ts/capabilities/session/action-cache.ts +148 -0
- package/ts/capabilities/session/adapters/ctrip-flight.ts +181 -0
- package/ts/capabilities/session/adapters/ctrip-hotel.ts +238 -0
- package/ts/capabilities/session/adapters/dida-portal.ts +338 -0
- package/ts/capabilities/session/adapters/meituan-local.ts +70 -0
- package/ts/capabilities/session/adapters/rail-12306.ts +392 -0
- package/ts/capabilities/session/benchmark.ts +276 -0
- package/ts/capabilities/session/bridge-ledger.ts +333 -0
- package/ts/capabilities/session/extension-bridge.ts +794 -0
- package/ts/capabilities/session/extension-channel.ts +144 -0
- package/ts/capabilities/session/extension-distribution.ts +266 -0
- package/ts/capabilities/session/extract.ts +54 -0
- package/ts/capabilities/session/golden-score.ts +139 -0
- package/ts/capabilities/session/health-watch.ts +264 -0
- package/ts/capabilities/session/read-guard.ts +141 -0
- package/ts/capabilities/session/static-flight-golden.ts +209 -0
- package/ts/capabilities/session/transport.ts +146 -0
- package/ts/capabilities/session/wizard.ts +140 -0
- package/ts/capabilities/session-consent.ts +211 -0
- package/ts/capabilities/session-login.ts +208 -0
- package/ts/capabilities/session-search.ts +893 -0
- package/ts/capabilities/weather.ts +330 -0
- package/ts/dsh-runtime/vendor/README.md +68 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/LICENSE +21 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +405 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +404 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/client/client.js +1584 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/cordis.patch.yml +5 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/icon.svg +5 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/amap.js +595 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/nominatim.js +63 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/osrm.js +58 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/photon.js +55 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-file.js +87 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-route.js +131 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config.js +16 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/geo.js +232 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/index.js +120 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +40 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/staticmap-route.js +115 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/geocode.js +127 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/poi.js +84 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/routes.js +267 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/amap.d.ts +90 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/nominatim.d.ts +17 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/osrm.d.ts +15 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/photon.d.ts +22 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-file.d.ts +33 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-route.d.ts +23 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config.d.ts +23 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/geo.d.ts +61 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/index.d.ts +18 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +14 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/staticmap-route.d.ts +31 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/geocode.d.ts +11 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/poi.d.ts +9 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/routes.d.ts +75 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/types.d.ts +68 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types.js +16 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +97 -0
- package/ts/package.json +293 -3
- package/ts/scripts/async-collect.ts +91 -0
- package/ts/scripts/map-tools-vendor-package-proof.ts +404 -0
- package/ts/scripts/skeleton-check.ts +1 -1
- package/ts/scripts/skeleton-integration-test.ts +23 -1
- package/ts/scripts/state-cli.ts +586 -0
- package/ts/scripts/turn-handoff-collect.ts +178 -0
- package/ts/src/artifact-gate.ts +991 -0
- package/ts/src/benchmark-agent-conformance.ts +619 -0
- package/ts/src/benchmark-environment-bridge.ts +538 -0
- package/ts/src/benchmark-headless-child-diagnostics.ts +184 -0
- package/ts/src/benchmark-tool-isolation.ts +166 -0
- package/ts/src/bookable-facts.ts +837 -0
- package/ts/src/booking-saga.ts +133 -0
- package/ts/src/booking-surface/availability-policy.ts +522 -0
- package/ts/src/booking-surface/booking-intent.ts +86 -0
- package/ts/src/booking-surface/cancel-refund-commission.ts +488 -0
- package/ts/src/booking-surface/canonical-schema.js +116 -0
- package/ts/src/booking-surface/contracts.ts +475 -0
- package/ts/src/booking-surface/dsh-planner.ts +1949 -0
- package/ts/src/booking-surface/dsh-plugin.js +378 -0
- package/ts/src/booking-surface/dsh-worker.ts +110 -0
- package/ts/src/booking-surface/error-codes.ts +241 -0
- package/ts/src/booking-surface/index.ts +9 -0
- package/ts/src/booking-surface/managed-dsh-cleanup-diagnostic.ts +151 -0
- package/ts/src/booking-surface/managed-dsh-run-port.ts +273 -0
- package/ts/src/booking-surface/profile.ts +42 -0
- package/ts/src/booking-surface/recovery-chain.ts +409 -0
- package/ts/src/booking-surface/runtime.ts +1793 -0
- package/ts/src/booking-surface/server.ts +733 -0
- package/ts/src/booking-surface/startup.ts +201 -0
- package/ts/src/booking-surface/validation.ts +217 -0
- package/ts/src/companions.ts +113 -0
- package/ts/src/contracts.ts +17 -3
- package/ts/src/dsh-llm.ts +152 -17
- package/ts/src/flyai-setup-tool.ts +77 -0
- package/ts/src/index.ts +2123 -200
- package/ts/src/itinerary-deck.ts +189 -0
- package/ts/src/itinerary-doc-shared.ts +741 -0
- package/ts/src/itinerary-html.ts +171 -0
- package/ts/src/loop.ts +234 -26
- package/ts/src/memory-capture.ts +283 -0
- package/ts/src/memory-decay.ts +55 -0
- package/ts/src/memory-utility.ts +70 -0
- package/ts/src/mock-llm.ts +4 -8
- package/ts/src/model.ts +88 -2
- package/ts/src/recall/card.ts +106 -0
- package/ts/src/recall/evaluator.ts +170 -0
- package/ts/src/recall/integration.ts +35 -0
- package/ts/src/recall/tick.ts +213 -0
- package/ts/src/session-link/plan-it-action.ts +78 -0
- package/ts/src/session-link/session-link.ts +275 -0
- package/ts/src/share/adapters.ts +93 -0
- package/ts/src/share/share-consent.ts +105 -0
- package/ts/src/share/share-deck.ts +85 -0
- package/ts/src/share/share-token.ts +166 -0
- package/ts/src/slot-spec.ts +172 -0
- package/ts/src/state-ledger.ts +1166 -0
- package/ts/src/subagent-job-id-guard.ts +72 -0
- package/ts/src/time-anchor.ts +338 -0
- package/ts/src/tool-packet.ts +32 -0
- package/ts/src/travel-slots.ts +219 -0
- package/ts/src/travel-timeline.ts +83 -0
- package/ts/src/turn-deadline.ts +366 -0
- package/ts/src/turn-policy.ts +154 -0
- package/ts/src/unified.ts +444 -105
- package/ts/src/wish-pool.ts +79 -0
- package/dist/scripts/session-attach-wait.js +0 -41
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { ManagedDshRunPort } from '../src/booking-surface/managed-dsh-run-port.js';
|
|
7
|
+
const workerPath = fileURLToPath(new URL('./fixtures/managed-dsh-worker-fixture.mjs', import.meta.url));
|
|
8
|
+
const port = new ManagedDshRunPort({ workerPath, graceMs: 50 });
|
|
9
|
+
const result = await port.run('fixture', { sessionId: 'managed-dsh-proof' });
|
|
10
|
+
const pid = result.events[0].grandchildPid;
|
|
11
|
+
assert.ok(Number.isInteger(pid) && pid > 0, 'fixture reports its grandchild pid');
|
|
12
|
+
const started = Date.now();
|
|
13
|
+
await port.close();
|
|
14
|
+
assert.ok(Date.now() - started < 2_000, 'tree teardown is bounded');
|
|
15
|
+
const deadline = Date.now() + 1_000;
|
|
16
|
+
let alive = true;
|
|
17
|
+
while (alive && Date.now() < deadline) {
|
|
18
|
+
try {
|
|
19
|
+
process.kill(pid, 0);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
alive = false;
|
|
23
|
+
}
|
|
24
|
+
if (alive)
|
|
25
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
26
|
+
}
|
|
27
|
+
assert.equal(alive, false, `TERM-resistant grandchild ${pid} must be reaped with its worker tree`);
|
|
28
|
+
assert.ok(existsSync(join(process.cwd(), 'node_modules/@deepseek-ai/dsh-subprocess-local')), 'proof uses installed dsh subprocess-local runtime');
|
|
29
|
+
console.log('MANAGED DSH RUN PORT TREE PROOF: bounded close reaps TERM-resistant grandchild');
|
|
30
|
+
const pendingWorkerPath = fileURLToPath(new URL('./fixtures/managed-dsh-pending-worker-fixture.mjs', import.meta.url));
|
|
31
|
+
async function waitForFile(path, timeoutMs) {
|
|
32
|
+
const deadline = Date.now() + timeoutMs;
|
|
33
|
+
while (!existsSync(path)) {
|
|
34
|
+
if (Date.now() >= deadline)
|
|
35
|
+
throw new Error(`fixture marker did not appear: ${path}`);
|
|
36
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function waitForFileText(path, expected, timeoutMs) {
|
|
40
|
+
const deadline = Date.now() + timeoutMs;
|
|
41
|
+
while (!existsSync(path) || readFileSync(path, 'utf8') !== expected) {
|
|
42
|
+
if (Date.now() >= deadline)
|
|
43
|
+
throw new Error(`fixture marker did not reach ${expected}: ${path}`);
|
|
44
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function waitForDead(pid, timeoutMs) {
|
|
48
|
+
const deadline = Date.now() + timeoutMs;
|
|
49
|
+
while (true) {
|
|
50
|
+
try {
|
|
51
|
+
process.kill(pid, 0);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (Date.now() >= deadline)
|
|
57
|
+
throw new Error(`fixture process ${pid} was not reaped`);
|
|
58
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function bounded(promise, timeoutMs, label) {
|
|
62
|
+
let timer;
|
|
63
|
+
try {
|
|
64
|
+
return await Promise.race([
|
|
65
|
+
promise,
|
|
66
|
+
new Promise((_, reject) => { timer = setTimeout(() => reject(new Error(label)), timeoutMs); }),
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
clearTimeout(timer);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async function assertPendingRejected(settledPromise, expected, label) {
|
|
74
|
+
const settled = await bounded(settledPromise, 1_500, `${label}: pending requests did not settle`);
|
|
75
|
+
assert.equal(settled.length, expected, `${label}: every pending request settled`);
|
|
76
|
+
assert.ok(settled.every((entry) => entry.status === 'rejected'), `${label}: every pending request rejected`);
|
|
77
|
+
}
|
|
78
|
+
async function proveWorkerExitRejectsPending() {
|
|
79
|
+
const root = mkdtempSync(join(tmpdir(), 'gotry-managed-dsh-exit-'));
|
|
80
|
+
const pidFile = join(root, 'pid.json');
|
|
81
|
+
const requestFile = join(root, 'requests');
|
|
82
|
+
const statusFile = join(root, 'status.json');
|
|
83
|
+
const port = new ManagedDshRunPort({
|
|
84
|
+
workerPath: pendingWorkerPath,
|
|
85
|
+
graceMs: 50,
|
|
86
|
+
env: {
|
|
87
|
+
...process.env,
|
|
88
|
+
MANAGED_DSH_FIXTURE_PID_FILE: pidFile,
|
|
89
|
+
MANAGED_DSH_FIXTURE_REQUEST_FILE: requestFile,
|
|
90
|
+
MANAGED_DSH_FIXTURE_STATUS_FILE: statusFile,
|
|
91
|
+
MANAGED_DSH_FIXTURE_EXIT_AFTER_REQUESTS: '3',
|
|
92
|
+
MANAGED_DSH_FIXTURE_EXIT_CODE: '23',
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
try {
|
|
96
|
+
await waitForFile(pidFile, 1_000);
|
|
97
|
+
const pending = [
|
|
98
|
+
port.run('first pending run', { sessionId: 'managed-dsh-exit-1' }),
|
|
99
|
+
port.run('second pending run', { sessionId: 'managed-dsh-exit-2' }),
|
|
100
|
+
port.warmup(),
|
|
101
|
+
];
|
|
102
|
+
const settledPromise = Promise.allSettled(pending);
|
|
103
|
+
await waitForFileText(requestFile, '3', 1_000);
|
|
104
|
+
await assertPendingRejected(settledPromise, pending.length, 'worker exit');
|
|
105
|
+
await waitForFile(statusFile, 1_000);
|
|
106
|
+
const status = JSON.parse(readFileSync(statusFile, 'utf8'));
|
|
107
|
+
assert.equal(status.exitCode, 23, 'fixture exit code is recorded');
|
|
108
|
+
assert.equal(status.signal, null, 'fixture exited without a signal');
|
|
109
|
+
assert.ok(status.stderr.length <= 128, 'fixture stderr evidence is bounded');
|
|
110
|
+
assert.equal(status.stderr.includes('PRIVATE_'), false, 'fixture stderr evidence contains no sensitive marker');
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
await port.close().catch(() => undefined);
|
|
114
|
+
rmSync(root, { recursive: true, force: true });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async function proveCloseRejectsPendingAndReapsTree() {
|
|
118
|
+
const root = mkdtempSync(join(tmpdir(), 'gotry-managed-dsh-close-'));
|
|
119
|
+
const pidFile = join(root, 'pid.json');
|
|
120
|
+
const requestFile = join(root, 'requests');
|
|
121
|
+
const port = new ManagedDshRunPort({
|
|
122
|
+
workerPath: pendingWorkerPath,
|
|
123
|
+
graceMs: 50,
|
|
124
|
+
env: { ...process.env, MANAGED_DSH_FIXTURE_PID_FILE: pidFile, MANAGED_DSH_FIXTURE_REQUEST_FILE: requestFile },
|
|
125
|
+
});
|
|
126
|
+
try {
|
|
127
|
+
await waitForFile(pidFile, 1_000);
|
|
128
|
+
const pids = JSON.parse(readFileSync(pidFile, 'utf8'));
|
|
129
|
+
assert.ok(Number.isInteger(pids.workerPid) && Number.isInteger(pids.grandchildPid), 'pending fixture reports its worker tree');
|
|
130
|
+
const pending = [
|
|
131
|
+
port.run('first close run', { sessionId: 'managed-dsh-close-1' }),
|
|
132
|
+
port.run('second close run', { sessionId: 'managed-dsh-close-2' }),
|
|
133
|
+
port.warmup(),
|
|
134
|
+
];
|
|
135
|
+
const settledPromise = Promise.allSettled(pending);
|
|
136
|
+
await waitForFileText(requestFile, '3', 1_000);
|
|
137
|
+
const closeStarted = Date.now();
|
|
138
|
+
const closePromise = port.close();
|
|
139
|
+
assert.strictEqual(port.close(), closePromise, 'repeated close returns the same cleanup promise');
|
|
140
|
+
await assertPendingRejected(settledPromise, pending.length, 'caller close');
|
|
141
|
+
await closePromise;
|
|
142
|
+
assert.ok(Date.now() - closeStarted < 2_000, 'caller close and pending rejection are bounded');
|
|
143
|
+
await waitForDead(pids.workerPid, 1_000);
|
|
144
|
+
await waitForDead(pids.grandchildPid, 1_000);
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
await port.close().catch(() => undefined);
|
|
148
|
+
rmSync(root, { recursive: true, force: true });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
await proveWorkerExitRejectsPending();
|
|
152
|
+
await proveCloseRejectsPendingAndReapsTree();
|
|
153
|
+
console.log('MANAGED DSH RUN PORT PENDING PROOF: worker exit and caller close reject two runs plus warmup; tree cleanup remains bounded');
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { ManagedDshRunPort } from '../src/booking-surface/managed-dsh-run-port.js';
|
|
7
|
+
import { ManagedDshCleanupError } from '../src/booking-surface/managed-dsh-cleanup-diagnostic.js';
|
|
8
|
+
const pendingWorkerPath = fileURLToPath(new URL('./fixtures/managed-dsh-pending-worker-fixture.mjs', import.meta.url));
|
|
9
|
+
// Attach a rejection handler in the same turn as every operation that can reject.
|
|
10
|
+
// This proof intentionally exercises real SDK promises, so it must not synthesize
|
|
11
|
+
// a completed `done` promise or leave a rejected close/run promise unobserved.
|
|
12
|
+
function observe(promise) {
|
|
13
|
+
return promise.then((value) => ({ status: 'fulfilled', value }), (reason) => ({ status: 'rejected', reason }));
|
|
14
|
+
}
|
|
15
|
+
async function bounded(promise, timeoutMs, label) {
|
|
16
|
+
let timer;
|
|
17
|
+
try {
|
|
18
|
+
return await Promise.race([
|
|
19
|
+
promise,
|
|
20
|
+
new Promise((_, reject) => {
|
|
21
|
+
timer = setTimeout(() => reject(new Error(label)), timeoutMs);
|
|
22
|
+
}),
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
clearTimeout(timer);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function reasonMessage(reason) {
|
|
30
|
+
return reason instanceof Error ? reason.message : String(reason);
|
|
31
|
+
}
|
|
32
|
+
async function rejectedWith(promise, expected, label) {
|
|
33
|
+
const outcome = await bounded(promise, 1_500, `${label}: promise did not settle`);
|
|
34
|
+
assert.equal(outcome.status, 'rejected', `${label}: promise must reject`);
|
|
35
|
+
const message = reasonMessage(outcome.reason);
|
|
36
|
+
assert.equal(message, expected, `${label}: stable public error`);
|
|
37
|
+
}
|
|
38
|
+
async function rejectedBeforeNextImmediate(promise, expected, label) {
|
|
39
|
+
let immediate;
|
|
40
|
+
try {
|
|
41
|
+
const outcome = await Promise.race([
|
|
42
|
+
promise,
|
|
43
|
+
new Promise((_, reject) => {
|
|
44
|
+
immediate = setImmediate(() => reject(new Error(`${label}: promise did not reject before next setImmediate`)));
|
|
45
|
+
}),
|
|
46
|
+
]);
|
|
47
|
+
assert.equal(outcome.status, 'rejected', `${label}: promise must reject`);
|
|
48
|
+
assert.equal(reasonMessage(outcome.reason), expected, `${label}: stable public error`);
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
if (immediate)
|
|
52
|
+
clearImmediate(immediate);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function waitForFile(path, timeoutMs) {
|
|
56
|
+
const deadline = Date.now() + timeoutMs;
|
|
57
|
+
while (!existsSync(path)) {
|
|
58
|
+
if (Date.now() >= deadline)
|
|
59
|
+
throw new Error(`fixture marker did not appear: ${path}`);
|
|
60
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function waitForFileText(path, expected, timeoutMs) {
|
|
64
|
+
const deadline = Date.now() + timeoutMs;
|
|
65
|
+
while (!existsSync(path) || readFileSync(path, 'utf8') !== expected) {
|
|
66
|
+
if (Date.now() >= deadline)
|
|
67
|
+
throw new Error(`fixture marker did not reach ${expected}: ${path}`);
|
|
68
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function waitForDead(pid, timeoutMs) {
|
|
72
|
+
const deadline = Date.now() + timeoutMs;
|
|
73
|
+
while (true) {
|
|
74
|
+
try {
|
|
75
|
+
process.kill(pid, 0);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (Date.now() >= deadline)
|
|
81
|
+
throw new Error(`fixture process ${pid} was not reaped`);
|
|
82
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function cleanup(port) {
|
|
86
|
+
if (!port)
|
|
87
|
+
return;
|
|
88
|
+
// Keep cleanup rejection observed even when an assertion fails earlier.
|
|
89
|
+
await bounded(observe(port.close()), 2_000, 'cleanup did not settle');
|
|
90
|
+
}
|
|
91
|
+
async function proveNaturalExitRejectsNewRequests() {
|
|
92
|
+
const root = mkdtempSync(join(tmpdir(), 'gotry-managed-dsh-terminal-exit-'));
|
|
93
|
+
const pidFile = join(root, 'pid.json');
|
|
94
|
+
const requestFile = join(root, 'requests');
|
|
95
|
+
const statusFile = join(root, 'status.json');
|
|
96
|
+
let port;
|
|
97
|
+
try {
|
|
98
|
+
port = new ManagedDshRunPort({
|
|
99
|
+
workerPath: pendingWorkerPath,
|
|
100
|
+
graceMs: 50,
|
|
101
|
+
env: {
|
|
102
|
+
...process.env,
|
|
103
|
+
MANAGED_DSH_FIXTURE_PID_FILE: pidFile,
|
|
104
|
+
MANAGED_DSH_FIXTURE_REQUEST_FILE: requestFile,
|
|
105
|
+
MANAGED_DSH_FIXTURE_STATUS_FILE: statusFile,
|
|
106
|
+
MANAGED_DSH_FIXTURE_EXIT_AFTER_REQUESTS: '1',
|
|
107
|
+
MANAGED_DSH_FIXTURE_EXIT_CODE: '23',
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
await waitForFile(pidFile, 1_000);
|
|
111
|
+
const oldPending = observe(port.run('terminal exit pending run', { sessionId: 'managed-dsh-terminal-exit-old' }));
|
|
112
|
+
await waitForFileText(requestFile, '1', 1_000);
|
|
113
|
+
await rejectedWith(oldPending, 'managed DSH worker exited', 'natural exit pending run');
|
|
114
|
+
await waitForFile(statusFile, 1_000);
|
|
115
|
+
const status = JSON.parse(readFileSync(statusFile, 'utf8'));
|
|
116
|
+
assert.equal(status.exitCode, 23, 'fixture naturally exits with code 23');
|
|
117
|
+
assert.equal(status.signal, null, 'fixture natural exit has no signal');
|
|
118
|
+
assert.ok(status.stderr.length <= 128, 'fixture stderr evidence is bounded');
|
|
119
|
+
// Wait for the real handle.done rejection/settlement path above, then probe
|
|
120
|
+
// both public request methods after the worker has exited.
|
|
121
|
+
await rejectedBeforeNextImmediate(observe(port.run('terminal exit post run', { sessionId: 'managed-dsh-terminal-exit-new' })), 'managed DSH worker exited', 'natural exit new run');
|
|
122
|
+
await rejectedBeforeNextImmediate(observe(port.warmup()), 'managed DSH worker exited', 'natural exit new warmup');
|
|
123
|
+
const closePromise = port.close();
|
|
124
|
+
const repeatedClosePromise = port.close();
|
|
125
|
+
assert.strictEqual(repeatedClosePromise, closePromise, 'natural exit repeated close returns one cleanup promise');
|
|
126
|
+
assert.equal((await bounded(observe(closePromise), 2_000, 'natural exit close did not settle')).status, 'fulfilled', 'natural exit close succeeds');
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
await cleanup(port);
|
|
130
|
+
rmSync(root, { recursive: true, force: true });
|
|
131
|
+
}
|
|
132
|
+
console.log('PASS managed DSH terminal natural exit: old pending and post-exit run/warmup reject immediately');
|
|
133
|
+
}
|
|
134
|
+
async function proveExplicitCloseIsBoundedAndIdempotent() {
|
|
135
|
+
const root = mkdtempSync(join(tmpdir(), 'gotry-managed-dsh-terminal-close-'));
|
|
136
|
+
const pidFile = join(root, 'pid.json');
|
|
137
|
+
const requestFile = join(root, 'requests');
|
|
138
|
+
let port;
|
|
139
|
+
try {
|
|
140
|
+
port = new ManagedDshRunPort({
|
|
141
|
+
workerPath: pendingWorkerPath,
|
|
142
|
+
graceMs: 50,
|
|
143
|
+
env: {
|
|
144
|
+
...process.env,
|
|
145
|
+
MANAGED_DSH_FIXTURE_PID_FILE: pidFile,
|
|
146
|
+
MANAGED_DSH_FIXTURE_REQUEST_FILE: requestFile,
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
await waitForFile(pidFile, 1_000);
|
|
150
|
+
const pids = JSON.parse(readFileSync(pidFile, 'utf8'));
|
|
151
|
+
assert.ok(Number.isInteger(pids.workerPid) && Number.isInteger(pids.grandchildPid), 'fixture reports worker tree');
|
|
152
|
+
const pending = [
|
|
153
|
+
observe(port.run('terminal close first run', { sessionId: 'managed-dsh-terminal-close-1' })),
|
|
154
|
+
observe(port.run('terminal close second run', { sessionId: 'managed-dsh-terminal-close-2' })),
|
|
155
|
+
observe(port.warmup()),
|
|
156
|
+
];
|
|
157
|
+
await waitForFileText(requestFile, '3', 1_000);
|
|
158
|
+
const closePromise = port.close();
|
|
159
|
+
const repeatedClosePromise = port.close();
|
|
160
|
+
assert.strictEqual(repeatedClosePromise, closePromise, 'repeated close returns one cleanup promise');
|
|
161
|
+
const closeOutcome = observe(closePromise);
|
|
162
|
+
const repeatedOutcome = observe(repeatedClosePromise);
|
|
163
|
+
for (const [index, request] of pending.entries()) {
|
|
164
|
+
await rejectedWith(request, 'managed DSH run port closed', `explicit close old pending ${index + 1}`);
|
|
165
|
+
}
|
|
166
|
+
assert.equal((await bounded(closeOutcome, 2_000, 'explicit close did not settle')).status, 'fulfilled', 'explicit close succeeds');
|
|
167
|
+
assert.equal((await bounded(repeatedOutcome, 2_000, 'repeated close did not settle')).status, 'fulfilled', 'repeated close succeeds');
|
|
168
|
+
await rejectedWith(observe(port.run('terminal close post run', { sessionId: 'managed-dsh-terminal-close-new' })), 'managed DSH run port is closed', 'explicit close new run');
|
|
169
|
+
await rejectedWith(observe(port.warmup()), 'managed DSH run port is closed', 'explicit close new warmup');
|
|
170
|
+
await waitForDead(pids.workerPid, 1_000);
|
|
171
|
+
await waitForDead(pids.grandchildPid, 1_000);
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
await cleanup(port);
|
|
175
|
+
rmSync(root, { recursive: true, force: true });
|
|
176
|
+
}
|
|
177
|
+
console.log('PASS managed DSH terminal explicit close: pending rejection, idempotent close, signal cleanup, and closed guards');
|
|
178
|
+
}
|
|
179
|
+
async function proveSignalTerminationRejectsPending() {
|
|
180
|
+
const root = mkdtempSync(join(tmpdir(), 'gotry-managed-dsh-terminal-signal-'));
|
|
181
|
+
const pidFile = join(root, 'pid.json');
|
|
182
|
+
const requestFile = join(root, 'requests');
|
|
183
|
+
let port;
|
|
184
|
+
try {
|
|
185
|
+
port = new ManagedDshRunPort({
|
|
186
|
+
workerPath: pendingWorkerPath,
|
|
187
|
+
graceMs: 50,
|
|
188
|
+
env: { ...process.env, MANAGED_DSH_FIXTURE_PID_FILE: pidFile, MANAGED_DSH_FIXTURE_REQUEST_FILE: requestFile },
|
|
189
|
+
});
|
|
190
|
+
await waitForFile(pidFile, 1_000);
|
|
191
|
+
const pids = JSON.parse(readFileSync(pidFile, 'utf8'));
|
|
192
|
+
assert.ok(Number.isInteger(pids.workerPid) && Number.isInteger(pids.grandchildPid), 'signal fixture reports its worker tree');
|
|
193
|
+
const oldPending = observe(port.run('terminal signal pending run', { sessionId: 'managed-dsh-terminal-signal-old' }));
|
|
194
|
+
await waitForFileText(requestFile, '1', 1_000);
|
|
195
|
+
// Kill the real child from outside the port. This exercises the SDK's
|
|
196
|
+
// signal-shaped done resolution, rather than ManagedDshRunPort.close().
|
|
197
|
+
process.kill(pids.workerPid, 'SIGKILL');
|
|
198
|
+
await rejectedWith(oldPending, 'managed DSH worker exited', 'signal exit pending run');
|
|
199
|
+
await waitForDead(pids.workerPid, 1_000);
|
|
200
|
+
await rejectedBeforeNextImmediate(observe(port.run('terminal signal post run', { sessionId: 'managed-dsh-terminal-signal-new' })), 'managed DSH worker exited', 'signal exit new run');
|
|
201
|
+
await rejectedBeforeNextImmediate(observe(port.warmup()), 'managed DSH worker exited', 'signal exit new warmup');
|
|
202
|
+
const closePromise = port.close();
|
|
203
|
+
const repeatedClosePromise = port.close();
|
|
204
|
+
assert.strictEqual(repeatedClosePromise, closePromise, 'signal exit repeated close returns one cleanup promise');
|
|
205
|
+
assert.equal((await bounded(observe(closePromise), 2_000, 'signal exit close did not settle')).status, 'fulfilled', 'signal exit close succeeds');
|
|
206
|
+
await waitForDead(pids.grandchildPid, 1_000);
|
|
207
|
+
}
|
|
208
|
+
finally {
|
|
209
|
+
await cleanup(port);
|
|
210
|
+
rmSync(root, { recursive: true, force: true });
|
|
211
|
+
}
|
|
212
|
+
console.log('PASS managed DSH terminal signal: SIGKILL, post-signal guards, idempotent close, and tree cleanup');
|
|
213
|
+
}
|
|
214
|
+
async function proveSpawnFailureIsSanitized() {
|
|
215
|
+
const root = mkdtempSync(join(tmpdir(), 'gotry-managed-dsh-terminal-spawn-'));
|
|
216
|
+
const missingCwd = join(root, 'missing-cwd');
|
|
217
|
+
let port;
|
|
218
|
+
try {
|
|
219
|
+
// dsh-subprocess-local returns a live handle and rejects handle.done for a
|
|
220
|
+
// missing cwd; this uses that real failure path rather than a fake promise.
|
|
221
|
+
port = new ManagedDshRunPort({
|
|
222
|
+
cwd: missingCwd,
|
|
223
|
+
workerPath: pendingWorkerPath,
|
|
224
|
+
graceMs: 50,
|
|
225
|
+
env: { ...process.env },
|
|
226
|
+
});
|
|
227
|
+
await rejectedWith(observe(port.run('terminal spawn failure run', { sessionId: 'managed-dsh-terminal-spawn-failure' })), 'managed DSH worker failed', 'spawn failure run');
|
|
228
|
+
await rejectedBeforeNextImmediate(observe(port.warmup()), 'managed DSH worker failed', 'spawn failure warmup');
|
|
229
|
+
await rejectedBeforeNextImmediate(observe(port.run('terminal spawn failure post run', { sessionId: 'managed-dsh-terminal-spawn-failure-post' })), 'managed DSH worker failed', 'spawn failure post run');
|
|
230
|
+
const closePromise = port.close();
|
|
231
|
+
const repeatedClosePromise = port.close();
|
|
232
|
+
assert.strictEqual(repeatedClosePromise, closePromise, 'spawn failure repeated close is idempotent');
|
|
233
|
+
for (const [label, promise] of [['spawn failure close', closePromise], ['spawn failure repeated close', repeatedClosePromise]]) {
|
|
234
|
+
const outcome = await bounded(observe(promise), 2_000, `${label} did not settle`);
|
|
235
|
+
assert.equal(outcome.status, 'rejected', `${label} must reject`);
|
|
236
|
+
const reason = outcome.reason;
|
|
237
|
+
assert.ok(reason instanceof ManagedDshCleanupError, `${label} carries the typed cleanup diagnostic`);
|
|
238
|
+
assert.equal(reason.message.split(';')[0], 'managed DSH worker failed', `${label} stable public error`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
await cleanup(port);
|
|
243
|
+
rmSync(root, { recursive: true, force: true });
|
|
244
|
+
}
|
|
245
|
+
console.log('PASS managed DSH terminal spawn failure: real missing cwd and sanitized immediate guards');
|
|
246
|
+
}
|
|
247
|
+
await proveNaturalExitRejectsNewRequests();
|
|
248
|
+
await proveExplicitCloseIsBoundedAndIdempotent();
|
|
249
|
+
await proveSignalTerminationRejectsPending();
|
|
250
|
+
await proveSpawnFailureIsSanitized();
|
|
251
|
+
assert.ok(existsSync(join(process.cwd(), 'node_modules/@deepseek-ai/dsh-subprocess-local')), 'proof uses installed dsh subprocess-local runtime');
|
|
252
|
+
console.log('MANAGED DSH TERMINAL PROOF: natural exit, explicit close, signal cleanup, and spawn failure are bounded and sanitized');
|