@hraness/ghostget 0.17.2
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/CHANGELOG.md +458 -0
- package/LICENSE +21 -0
- package/README.md +1359 -0
- package/bunfig.toml +2 -0
- package/dist/apple-photos-client.js +704 -0
- package/dist/beeper-client.js +4602 -0
- package/dist/client.js +1605 -0
- package/dist/index-26yq8q16.js +31 -0
- package/dist/index-9t13b4k7.js +508 -0
- package/dist/index-axwm9b3v.js +5 -0
- package/dist/index-gwk7rbyj.js +30 -0
- package/dist/index.js +701 -0
- package/dist/messaging.js +1130 -0
- package/dist/omni-client.js +1406 -0
- package/dist/whatsapp-client.js +355 -0
- package/docs/imessage-direct-provider.md +106 -0
- package/docs/rental-listings.md +94 -0
- package/package.json +600 -0
- package/skills/ghostget/SKILL.md +251 -0
- package/skills/ghostget/agents/openai.yaml +4 -0
- package/skills/ghostget/references/adapter-contract.md +181 -0
- package/skills/ghostget/references/apple-photos.md +115 -0
- package/skills/ghostget/references/article-drafts.md +235 -0
- package/skills/ghostget/references/code-owned-provider-scaffold.md +134 -0
- package/skills/ghostget/references/cross-posting-video.md +139 -0
- package/skills/ghostget/references/cross-posting.md +82 -0
- package/skills/ghostget/references/derivation.md +390 -0
- package/skills/ghostget/references/hraness-social-profile-stats.json +269 -0
- package/skills/ghostget/references/install.md +66 -0
- package/skills/ghostget/references/linkedin-adapter.md +442 -0
- package/skills/ghostget/references/messaging.md +168 -0
- package/skills/ghostget/references/meta-comet-contract.md +153 -0
- package/skills/ghostget/references/platform-patterns.md +122 -0
- package/skills/ghostget/references/provider-plugins.md +496 -0
- package/skills/ghostget/references/reddit-flair.md +78 -0
- package/skills/ghostget/references/safety-and-state.md +214 -0
- package/skills/ghostget/references/settlement-and-duplicate-cleanup.md +79 -0
- package/skills/ghostget/references/social-platform-routing.md +66 -0
- package/skills/ghostget/references/social-profile-stats.md +195 -0
- package/skills/ghostget/references/social-video-platform-routing.md +89 -0
- package/skills/ghostget/references/whatsapp-adapter.md +101 -0
- package/skills/ghostget/references/x-adapter.md +332 -0
- package/skills/ghostget/references/x-ai-disclosure.md +71 -0
- package/src/apple-photos-cli.ts +639 -0
- package/src/apple-photos-client-types.ts +168 -0
- package/src/apple-photos-client.ts +201 -0
- package/src/apple-photos-contact-evidence.ts +838 -0
- package/src/apple-photos-local-source.ts +1131 -0
- package/src/args.ts +2053 -0
- package/src/article-draft-document.ts +417 -0
- package/src/article-draft-embeds.ts +123 -0
- package/src/article-draft-images.ts +214 -0
- package/src/assets/adapter-template/wrench-adapter.json +40 -0
- package/src/assets/adapters/beeper/wrench-web-adapter.json +1500 -0
- package/src/assets/adapters/beeper/wrench-web-adapter.v1.0.0.json +129 -0
- package/src/assets/adapters/beeper/wrench-web-adapter.v1.1.0.json +207 -0
- package/src/assets/adapters/beeper/wrench-web-adapter.v2.0.0.json +1463 -0
- package/src/assets/adapters/beeper/wrench-web-adapter.v2.1.0.json +1463 -0
- package/src/assets/adapters/beeper/wrench-web-adapter.v2.2.0.json +1475 -0
- package/src/assets/adapters/beeper/wrench-web-adapter.v2.3.0.json +1488 -0
- package/src/assets/adapters/bluesky/wrench-web-adapter.json +684 -0
- package/src/assets/adapters/bluesky/wrench-web-adapter.v1.0.0.json +581 -0
- package/src/assets/adapters/bluesky/wrench-web-adapter.v1.1.0.json +581 -0
- package/src/assets/adapters/bluesky/wrench-web-adapter.v1.2.0.json +581 -0
- package/src/assets/adapters/bluesky/wrench-web-adapter.v1.3.0.json +615 -0
- package/src/assets/adapters/bluesky/wrench-web-adapter.v1.4.0.json +684 -0
- package/src/assets/adapters/bluesky/wrench-web-adapter.v1.5.0.json +684 -0
- package/src/assets/adapters/bluesky/wrench-web-adapter.v1.6.0.json +684 -0
- package/src/assets/adapters/clasificados/wrench-web-adapter.json +54 -0
- package/src/assets/adapters/facebook/wrench-web-adapter.json +750 -0
- package/src/assets/adapters/facebook/wrench-web-adapter.v1.0.0.json +706 -0
- package/src/assets/adapters/facebook/wrench-web-adapter.v1.1.0.json +703 -0
- package/src/assets/adapters/facebook/wrench-web-adapter.v1.2.0.json +750 -0
- package/src/assets/adapters/facebook-group/wrench-web-adapter.json +682 -0
- package/src/assets/adapters/facebook-group/wrench-web-adapter.v1.0.0.json +583 -0
- package/src/assets/adapters/facebook-group/wrench-web-adapter.v1.1.0.json +682 -0
- package/src/assets/adapters/facebook-marketplace/wrench-web-adapter.json +437 -0
- package/src/assets/adapters/facebook-marketplace/wrench-web-adapter.v1.0.0.json +383 -0
- package/src/assets/adapters/facebook-marketplace/wrench-web-adapter.v1.1.0.json +437 -0
- package/src/assets/adapters/facebook-marketplace/wrench-web-adapter.v1.1.1.json +437 -0
- package/src/assets/adapters/facebook-page/wrench-web-adapter.json +880 -0
- package/src/assets/adapters/facebook-page/wrench-web-adapter.v1.0.0.json +740 -0
- package/src/assets/adapters/facebook-page/wrench-web-adapter.v1.1.0.json +880 -0
- package/src/assets/adapters/github/wrench-web-adapter.json +69 -0
- package/src/assets/adapters/github/wrench-web-adapter.v1.0.0.json +42 -0
- package/src/assets/adapters/github/wrench-web-adapter.v1.1.0.json +69 -0
- package/src/assets/adapters/gmail/wrench-adapter.json +161 -0
- package/src/assets/adapters/gmail/wrench-adapter.v1.2.0.json +157 -0
- package/src/assets/adapters/hacker-news/wrench-web-adapter.json +315 -0
- package/src/assets/adapters/hacker-news/wrench-web-adapter.v1.0.0.json +315 -0
- package/src/assets/adapters/imessage/wrench-web-adapter.json +236 -0
- package/src/assets/adapters/instagram/wrench-web-adapter.json +719 -0
- package/src/assets/adapters/instagram/wrench-web-adapter.v1.0.0.json +627 -0
- package/src/assets/adapters/instagram/wrench-web-adapter.v1.1.0.json +609 -0
- package/src/assets/adapters/instagram/wrench-web-adapter.v1.2.0.json +640 -0
- package/src/assets/adapters/instagram/wrench-web-adapter.v1.3.0.json +671 -0
- package/src/assets/adapters/instagram/wrench-web-adapter.v1.4.0.json +710 -0
- package/src/assets/adapters/instagram/wrench-web-adapter.v1.5.0.json +710 -0
- package/src/assets/adapters/instagram/wrench-web-adapter.v1.6.0.json +719 -0
- package/src/assets/adapters/instagram/wrench-web-adapter.v1.7.0.json +719 -0
- package/src/assets/adapters/linkedin/wrench-adapter.json +442 -0
- package/src/assets/adapters/linkedin/wrench-adapter.v0.4.0.json +124 -0
- package/src/assets/adapters/linkedin/wrench-adapter.v1.0.0.json +411 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.json +914 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.0.0.json +604 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.1.0.json +604 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.10.0.json +809 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.11.0.json +809 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.12.0.json +820 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.13.0.json +819 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.14.0.json +819 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.15.0.json +819 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.16.0.json +874 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.17.0.json +874 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.18.0.json +874 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.19.0.json +874 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.2.0.json +731 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.3.0.json +768 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.4.0.json +808 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.5.0.json +808 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.6.0.json +808 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.7.0.json +825 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.8.0.json +792 -0
- package/src/assets/adapters/linkedin/wrench-web-adapter.v1.9.0.json +809 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.json +855 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.0.0.json +577 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.1.0.json +604 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.10.0.json +712 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.11.0.json +712 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.12.0.json +712 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.2.0.json +653 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.3.0.json +712 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.4.0.json +713 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.5.0.json +712 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.6.0.json +713 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.7.0.json +713 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.8.0.json +713 -0
- package/src/assets/adapters/reddit/wrench-web-adapter.v1.9.0.json +713 -0
- package/src/assets/adapters/substack/wrench-web-adapter.json +936 -0
- package/src/assets/adapters/substack/wrench-web-adapter.v1.0.0.json +817 -0
- package/src/assets/adapters/substack/wrench-web-adapter.v1.1.0.json +812 -0
- package/src/assets/adapters/substack/wrench-web-adapter.v1.2.0.json +812 -0
- package/src/assets/adapters/substack/wrench-web-adapter.v1.3.0.json +902 -0
- package/src/assets/adapters/substack/wrench-web-adapter.v1.4.0.json +936 -0
- package/src/assets/adapters/substack/wrench-web-adapter.v1.5.0.json +936 -0
- package/src/assets/adapters/substack/wrench-web-adapter.v1.6.0.json +936 -0
- package/src/assets/adapters/threads/wrench-web-adapter.json +692 -0
- package/src/assets/adapters/threads/wrench-web-adapter.v1.0.0.json +629 -0
- package/src/assets/adapters/threads/wrench-web-adapter.v1.1.0.json +623 -0
- package/src/assets/adapters/threads/wrench-web-adapter.v1.2.0.json +622 -0
- package/src/assets/adapters/threads/wrench-web-adapter.v1.3.0.json +622 -0
- package/src/assets/adapters/threads/wrench-web-adapter.v1.4.0.json +622 -0
- package/src/assets/adapters/threads/wrench-web-adapter.v1.5.0.json +699 -0
- package/src/assets/adapters/threads/wrench-web-adapter.v1.6.0.json +693 -0
- package/src/assets/adapters/threads/wrench-web-adapter.v1.7.0.json +692 -0
- package/src/assets/adapters/tiktok/wrench-web-adapter.json +762 -0
- package/src/assets/adapters/tiktok/wrench-web-adapter.v1.0.0.json +681 -0
- package/src/assets/adapters/tiktok/wrench-web-adapter.v1.1.0.json +708 -0
- package/src/assets/adapters/tiktok/wrench-web-adapter.v1.2.0.json +762 -0
- package/src/assets/adapters/tiktok/wrench-web-adapter.v1.3.0.json +762 -0
- package/src/assets/adapters/twitch/wrench-web-adapter.json +42 -0
- package/src/assets/adapters/twitch/wrench-web-adapter.v1.0.0.json +42 -0
- package/src/assets/adapters/whatsapp/wrench-web-adapter.json +400 -0
- package/src/assets/adapters/whatsapp/wrench-web-adapter.v1.0.0.json +355 -0
- package/src/assets/adapters/whatsapp/wrench-web-adapter.v1.1.0.json +386 -0
- package/src/assets/adapters/whatsapp/wrench-web-adapter.v1.2.0.json +386 -0
- package/src/assets/adapters/whatsapp/wrench-web-adapter.v1.3.0.json +400 -0
- package/src/assets/adapters/x/wrench-adapter.json +749 -0
- package/src/assets/adapters/x/wrench-adapter.v1.0.0.json +700 -0
- package/src/assets/adapters/x/wrench-adapter.v1.1.0.json +707 -0
- package/src/assets/adapters/x/wrench-web-adapter.json +712 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.1.0.json +579 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.10.0.json +685 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.11.0.json +712 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.12.0.json +712 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.13.0.json +712 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.2.0.json +578 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.3.0.json +610 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.4.0.json +617 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.5.0.json +634 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.6.0.json +632 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.7.0.json +649 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.8.0.json +649 -0
- package/src/assets/adapters/x/wrench-web-adapter.v1.9.0.json +683 -0
- package/src/assets/adapters/youtube/wrench-web-adapter.json +561 -0
- package/src/assets/adapters/youtube/wrench-web-adapter.v1.0.0.json +465 -0
- package/src/assets/adapters/youtube/wrench-web-adapter.v1.1.0.json +519 -0
- package/src/assets/adapters/youtube/wrench-web-adapter.v1.2.0.json +561 -0
- package/src/assets/adapters/youtube/wrench-web-adapter.v1.3.0.json +561 -0
- package/src/assets/code-owned-provider-template/plugin.test.ts.template +54 -0
- package/src/assets/code-owned-provider-template/plugin.ts.template +102 -0
- package/src/assets/code-owned-provider-template/runtime.internal.test.ts.template +44 -0
- package/src/assets/code-owned-provider-template/runtime.ts.template +59 -0
- package/src/assets/code-owned-provider-template/wrench-adapter.json.template +33 -0
- package/src/assets/fonts/nebula-sans/LICENSE.txt +96 -0
- package/src/assets/fonts/nebula-sans/NebulaSans-Book.woff2 +0 -0
- package/src/assets/fonts/nebula-sans/PROVENANCE.md +14 -0
- package/src/assets.d.ts +4 -0
- package/src/auth.ts +1157 -0
- package/src/beeper-client-types.ts +169 -0
- package/src/beeper-client.ts +250 -0
- package/src/beeper-contact-interactions-cli.ts +180 -0
- package/src/beeper-contact-interactions.ts +1612 -0
- package/src/beeper-message-bundle-v1.ts +257 -0
- package/src/beeper-message-like-me-cli.ts +84 -0
- package/src/beeper-message-like-me-export.ts +2274 -0
- package/src/beeper-message-like-me-recovery.ts +931 -0
- package/src/beeper-message-like-me-source.ts +4034 -0
- package/src/browser-admission.ts +928 -0
- package/src/browser-snapshots.ts +260 -0
- package/src/browser.ts +3873 -0
- package/src/canonical-json.ts +60 -0
- package/src/catalog-cli.ts +638 -0
- package/src/cli.ts +208 -0
- package/src/client-types.ts +301 -0
- package/src/client.ts +2726 -0
- package/src/confirmed-write-failure.ts +44 -0
- package/src/confirmed-write-model.ts +72 -0
- package/src/confirmed-write-platform.ts +1055 -0
- package/src/confirmed-write-program.ts +224 -0
- package/src/confirmed-write-runtime.ts +16 -0
- package/src/cursor-token.ts +228 -0
- package/src/derivation-dnr-readiness.ts +367 -0
- package/src/derivation-file-chooser.ts +384 -0
- package/src/derivation-network-boundary.ts +835 -0
- package/src/derivation-network-guard.ts +782 -0
- package/src/derivation-network-proxy-helper.ts +440 -0
- package/src/derivation-network-proxy.ts +385 -0
- package/src/derive-command-helper.ts +693 -0
- package/src/derive-fixtures.ts +343 -0
- package/src/derive-review.ts +980 -0
- package/src/derive.ts +4754 -0
- package/src/fixtures/beeper-message-like-me-v1/accounts.ndjson +2 -0
- package/src/fixtures/beeper-message-like-me-v1/conversations.ndjson +1 -0
- package/src/fixtures/beeper-message-like-me-v1/manifest.json +1 -0
- package/src/fixtures/beeper-message-like-me-v1/messages.ndjson +2 -0
- package/src/fixtures/beeper-message-like-me-v1/participants.ndjson +3 -0
- package/src/fixtures/beeper-message-like-me-v1/reactions.ndjson +1 -0
- package/src/fixtures/beeper-message-like-me-v1/tombstones.ndjson +1 -0
- package/src/ghostget.ts +3672 -0
- package/src/gmail-capture.ts +1244 -0
- package/src/har-internal.ts +1242 -0
- package/src/har.ts +743 -0
- package/src/index.ts +218 -0
- package/src/invocation-read-platform.ts +55 -0
- package/src/invocation-read-program.ts +93 -0
- package/src/invocation-read-runtime.ts +11 -0
- package/src/linked-device-lifecycle-admission.ts +450 -0
- package/src/linked-device-lifecycle-journal.ts +1560 -0
- package/src/linked-device-lifecycle-runtime.ts +1602 -0
- package/src/local-cli-admission.ts +135 -0
- package/src/local-cli-contracts.ts +271 -0
- package/src/local-cli-execution.ts +98 -0
- package/src/local-cli-surface-contract.ts +1510 -0
- package/src/local-cli-tool-identity.ts +336 -0
- package/src/media/archive.ts +2325 -0
- package/src/media/args.ts +303 -0
- package/src/media/cli.ts +287 -0
- package/src/media/doctor.ts +475 -0
- package/src/media/ffmpeg.ts +1330 -0
- package/src/media/http-capture.ts +711 -0
- package/src/media/http-probe.ts +593 -0
- package/src/media/http.ts +387 -0
- package/src/media/index.ts +10 -0
- package/src/media/local-transcription.ts +613 -0
- package/src/media/lock.ts +321 -0
- package/src/media/manifest.ts +1712 -0
- package/src/media/metadata.ts +906 -0
- package/src/media/process.ts +723 -0
- package/src/media/revision.ts +166 -0
- package/src/media/runtime-closure.ts +1063 -0
- package/src/media/source-router.ts +187 -0
- package/src/media/transcriber-config.ts +1122 -0
- package/src/media/transcript-persistence-model.ts +15 -0
- package/src/media/transcript-persistence-platform.ts +89 -0
- package/src/media/transcript-persistence-program.ts +39 -0
- package/src/media/transcript-persistence-runtime.ts +24 -0
- package/src/media/transcript.ts +616 -0
- package/src/media/utf8-order.ts +30 -0
- package/src/media/whisper-cpp.ts +464 -0
- package/src/media/whisper-language.ts +58 -0
- package/src/media/yt-dlp.ts +439 -0
- package/src/message-like-me-agentic-messaging.ts +882 -0
- package/src/messaging-action-store.ts +793 -0
- package/src/messaging-runtime.ts +2136 -0
- package/src/messaging-store.ts +539 -0
- package/src/messaging-types.ts +1663 -0
- package/src/messaging.ts +334 -0
- package/src/model.ts +2671 -0
- package/src/oauth-google.ts +888 -0
- package/src/omni-client-types.ts +306 -0
- package/src/omni-client.ts +2225 -0
- package/src/omni-limits.ts +34 -0
- package/src/omni-model.ts +1614 -0
- package/src/omni-request.ts +379 -0
- package/src/omni-runtime.ts +1632 -0
- package/src/operation-deadline.ts +189 -0
- package/src/path-helper.ts +1656 -0
- package/src/pinned-https.ts +194 -0
- package/src/plan-assets.ts +832 -0
- package/src/platform-catalog.ts +1832 -0
- package/src/plugins/beeper-linked-device/plugin.ts +310 -0
- package/src/plugins/bluesky-web/plugin.ts +178 -0
- package/src/plugins/clasificados-web/plugin.ts +66 -0
- package/src/plugins/github-web/plugin.ts +80 -0
- package/src/plugins/gmail-official/plugin.ts +110 -0
- package/src/plugins/hacker-news-web/plugin.ts +52 -0
- package/src/plugins/imessage-direct/plugin.ts +195 -0
- package/src/plugins/imessage-direct/vendor/0001-fix-keep-AppleScript-send-payloads-out-of-child-argv.patch +1430 -0
- package/src/plugins/imessage-direct/vendor/0002-feat-rpc-add-exact-chat-lookup.patch +225 -0
- package/src/plugins/imessage-direct/vendor/provenance.json +80 -0
- package/src/plugins/linkedin-official/plugin.ts +84 -0
- package/src/plugins/linkedin-web/plugin.ts +412 -0
- package/src/plugins/meta-web/plugin.ts +317 -0
- package/src/plugins/reddit-web/flair.ts +492 -0
- package/src/plugins/reddit-web/plugin.ts +477 -0
- package/src/plugins/substack-web/plugin.ts +124 -0
- package/src/plugins/tiktok-web/plugin.ts +67 -0
- package/src/plugins/twitch-web/plugin.ts +54 -0
- package/src/plugins/whatsapp-linked-device/plugin.ts +105 -0
- package/src/plugins/x-official/plugin.ts +64 -0
- package/src/plugins/x-web/plugin.ts +488 -0
- package/src/plugins/youtube-web/plugin.ts +101 -0
- package/src/portable-run-recovery.ts +466 -0
- package/src/process-identity.ts +501 -0
- package/src/profile-clone-helper.ts +104 -0
- package/src/provider-catalog-views.ts +51 -0
- package/src/provider-context.ts +69 -0
- package/src/provider-contract-definitions-x.ts +45 -0
- package/src/provider-contract-definitions.ts +948 -0
- package/src/provider-contract-input-gmail.ts +176 -0
- package/src/provider-contract-input-linkedin.ts +77 -0
- package/src/provider-contract-input-x.ts +304 -0
- package/src/provider-contract-planning.ts +23 -0
- package/src/provider-contract-semantic-identity.ts +54 -0
- package/src/provider-contracts.ts +251 -0
- package/src/provider-http.ts +723 -0
- package/src/provider-plugin-auth.ts +36 -0
- package/src/provider-plugin-builtins.ts +229 -0
- package/src/provider-plugin-cleanup-barrier.ts +229 -0
- package/src/provider-plugin-cleanup-execution.ts +79 -0
- package/src/provider-plugin-cleanup-resource.ts +470 -0
- package/src/provider-plugin-contract-identity.ts +707 -0
- package/src/provider-plugin-host.ts +1972 -0
- package/src/provider-plugin-identifiers.ts +60 -0
- package/src/provider-plugin-invocation-lease.ts +889 -0
- package/src/provider-plugin-lifecycle-kernel.ts +566 -0
- package/src/provider-plugin-lifecycle.ts +1455 -0
- package/src/provider-plugin-module-analysis.ts +336 -0
- package/src/provider-plugin-package.ts +2530 -0
- package/src/provider-plugin-portable-authority.ts +106 -0
- package/src/provider-plugin-portable-catalog.ts +94 -0
- package/src/provider-plugin-portable-identity.ts +315 -0
- package/src/provider-plugin-portable-runtime.ts +2057 -0
- package/src/provider-plugin-protocol.ts +1625 -0
- package/src/provider-plugin-registry.ts +3342 -0
- package/src/provider-plugin-store.ts +2155 -0
- package/src/provider-plugin-test-fixture.ts +5 -0
- package/src/provider-plugin.ts +4907 -0
- package/src/provider-plugins.generated.ts +43 -0
- package/src/provider-plugins.ts +8 -0
- package/src/provider-subject.ts +41 -0
- package/src/provider.ts +315 -0
- package/src/providers/beeper-local-runtime.ts +5426 -0
- package/src/providers/beeper-local.ts +2739 -0
- package/src/providers/beeper-messaging.ts +462 -0
- package/src/providers/beeper-omni.ts +1159 -0
- package/src/providers/bluesky-web-runtime.ts +2895 -0
- package/src/providers/bluesky-web.ts +1614 -0
- package/src/providers/clasificados-web-runtime.ts +255 -0
- package/src/providers/clasificados-web.ts +503 -0
- package/src/providers/contact-projection.ts +301 -0
- package/src/providers/github-read-model.ts +94 -0
- package/src/providers/github-read-platform.ts +165 -0
- package/src/providers/github-read-program.ts +97 -0
- package/src/providers/github-web-runtime.ts +320 -0
- package/src/providers/github-web.ts +403 -0
- package/src/providers/gmail-api.ts +2834 -0
- package/src/providers/gmail-omni.ts +830 -0
- package/src/providers/gmail.ts +1130 -0
- package/src/providers/hacker-news-web-runtime.ts +220 -0
- package/src/providers/hacker-news-web.ts +809 -0
- package/src/providers/imessage-direct-install.ts +354 -0
- package/src/providers/imessage-direct-messaging.ts +532 -0
- package/src/providers/imessage-direct-omni.ts +400 -0
- package/src/providers/imessage-direct-runtime.ts +1498 -0
- package/src/providers/imessage-direct.ts +351 -0
- package/src/providers/instagram-video-foundations.ts +913 -0
- package/src/providers/instagram-web-profile-browser.ts +600 -0
- package/src/providers/iso-bmff.ts +338 -0
- package/src/providers/linkedin-company-platform.ts +42 -0
- package/src/providers/linkedin-company-program.ts +88 -0
- package/src/providers/linkedin-contact-failure.ts +84 -0
- package/src/providers/linkedin-contact-platform.ts +45 -0
- package/src/providers/linkedin-contact-program.ts +91 -0
- package/src/providers/linkedin-profile-activity-failure.ts +76 -0
- package/src/providers/linkedin-profile-activity-platform.ts +41 -0
- package/src/providers/linkedin-profile-activity-program.ts +67 -0
- package/src/providers/linkedin-read-failure.ts +52 -0
- package/src/providers/linkedin-self-platform.ts +53 -0
- package/src/providers/linkedin-self-program.ts +122 -0
- package/src/providers/linkedin-web-article-browser.ts +794 -0
- package/src/providers/linkedin-web-bootstrap.ts +146 -0
- package/src/providers/linkedin-web-contact.ts +830 -0
- package/src/providers/linkedin-web-feed-browser.ts +832 -0
- package/src/providers/linkedin-web-feed.ts +864 -0
- package/src/providers/linkedin-web-post-browser.ts +653 -0
- package/src/providers/linkedin-web-profile-browser.ts +683 -0
- package/src/providers/linkedin-web-runtime.ts +2388 -0
- package/src/providers/linkedin-web.ts +3305 -0
- package/src/providers/linkedin.ts +1885 -0
- package/src/providers/meta-bootstrap.ts +1043 -0
- package/src/providers/meta-facebook-group.ts +690 -0
- package/src/providers/meta-marketplace-relay.ts +747 -0
- package/src/providers/meta-omni.ts +373 -0
- package/src/providers/meta-relay-bundle.ts +1049 -0
- package/src/providers/meta-web-descriptors.ts +1740 -0
- package/src/providers/meta-web-runtime.ts +3388 -0
- package/src/providers/meta-web.ts +2931 -0
- package/src/providers/read-failure.ts +139 -0
- package/src/providers/reddit-omni.ts +462 -0
- package/src/providers/reddit-web-runtime.ts +1929 -0
- package/src/providers/reddit-web.ts +1611 -0
- package/src/providers/rental-listings.ts +460 -0
- package/src/providers/substack-omni.ts +406 -0
- package/src/providers/substack-video-mp4.ts +33 -0
- package/src/providers/substack-web-runtime.ts +2812 -0
- package/src/providers/substack-web.ts +1502 -0
- package/src/providers/tiktok-video-mp4.ts +33 -0
- package/src/providers/tiktok-web-runtime.ts +770 -0
- package/src/providers/tiktok-web.ts +2786 -0
- package/src/providers/twitch-web-runtime.ts +226 -0
- package/src/providers/twitch-web.ts +274 -0
- package/src/providers/whatsapp-account-identity.ts +55 -0
- package/src/providers/whatsapp-contact-projection-helper.ts +874 -0
- package/src/providers/whatsapp-contact-projection-protocol.ts +403 -0
- package/src/providers/whatsapp-interaction-projection-helper.ts +1452 -0
- package/src/providers/whatsapp-interaction-projection-protocol.ts +462 -0
- package/src/providers/whatsapp-message-export-projection-protocol.ts +532 -0
- package/src/providers/whatsapp-messaging.ts +132 -0
- package/src/providers/whatsapp-omni.ts +586 -0
- package/src/providers/whatsapp-web-runtime.ts +3108 -0
- package/src/providers/whatsapp-web.ts +1037 -0
- package/src/providers/x-image-provenance.ts +523 -0
- package/src/providers/x-made-with-ai.ts +106 -0
- package/src/providers/x-transaction-id.ts +413 -0
- package/src/providers/x-web-runtime.ts +3485 -0
- package/src/providers/x-web.ts +2332 -0
- package/src/providers/x.ts +1889 -0
- package/src/providers/youtube-web-runtime.ts +1400 -0
- package/src/providers/youtube-web.ts +1221 -0
- package/src/read-admission-runtime.ts +91 -0
- package/src/read-client.ts +521 -0
- package/src/read-effect-platform.ts +7 -0
- package/src/read-effect-runtime.ts +14 -0
- package/src/read-effect.ts +52 -0
- package/src/read-projection-admission.ts +866 -0
- package/src/read-projections.ts +3151 -0
- package/src/recovery.ts +1492 -0
- package/src/reviewed-template.ts +146 -0
- package/src/run-journal.ts +1272 -0
- package/src/runtime.ts +5116 -0
- package/src/scripts/generate-provider-plugin-catalog.ts +121 -0
- package/src/scripts/install-whatsapp-protocol.sh +232 -0
- package/src/scripts/recover-install-stages.ts +1491 -0
- package/src/scripts/resolve-state-home.ts +30 -0
- package/src/scripts/scaffold-web-provider.ts +973 -0
- package/src/scripts/sync-bundled-adapters.ts +695 -0
- package/src/session-secrets.ts +1183 -0
- package/src/state-helper.bunfig.toml +2 -0
- package/src/state-helper.ts +2914 -0
- package/src/storage.ts +3842 -0
- package/src/transport-policy.ts +2 -0
- package/src/usage.ts +182 -0
- package/src/version.ts +2 -0
- package/src/web-session-authentication-policy.ts +136 -0
- package/src/web-session-cleanup-admission.ts +2344 -0
- package/src/web-session-cleanup-join.ts +99 -0
- package/src/web-session-client.ts +996 -0
- package/src/web-session-contract-definitions.ts +820 -0
- package/src/web-session-contract-planning.ts +42 -0
- package/src/web-session-contracts.ts +228 -0
- package/src/web-session-cookies.ts +500 -0
- package/src/web-session-execution.ts +385 -0
- package/src/web-session-http.ts +373 -0
- package/src/web-session-read-errors.ts +19 -0
- package/src/web-session-read-runtime.ts +124 -0
- package/src/web-session-recovery.ts +818 -0
- package/src/web-session-sites.ts +58 -0
- package/src/web-session-template.ts +994 -0
- package/src/web-session.ts +93 -0
- package/src/whatsapp-client-binding.ts +21 -0
- package/src/whatsapp-client-types.ts +75 -0
- package/src/whatsapp-client.ts +395 -0
- package/src/whatsapp-export-coordinate.ts +17 -0
- package/src/whatsapp-message-bundle-v2.ts +195 -0
- package/src/whatsapp-message-like-me-cli.ts +195 -0
- package/src/whatsapp-message-like-me-export.ts +1072 -0
- package/src/whatsapp-message-like-me-source.ts +1012 -0
- package/tsconfig.json +67 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/provider-plugin-identifiers.ts
|
|
3
|
+
var PROVIDER_PLUGIN_ID_MAX_LENGTH = 63;
|
|
4
|
+
var PROVIDER_PLUGIN_OPERATION_NAME_MAX_LENGTH = 163;
|
|
5
|
+
var strictKebabPattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
|
|
6
|
+
var strictKebabSegmentPattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
|
|
7
|
+
var portableProviderPluginVersionPattern = /^(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u;
|
|
8
|
+
function isPortableProviderPluginVersion(value) {
|
|
9
|
+
if (typeof value !== "string" || value.length > 128)
|
|
10
|
+
return false;
|
|
11
|
+
const match = portableProviderPluginVersionPattern.exec(value);
|
|
12
|
+
if (match === null)
|
|
13
|
+
return false;
|
|
14
|
+
const prerelease = match[1];
|
|
15
|
+
return prerelease === undefined || prerelease.split(".").every((identifier) => !/^[0-9]+$/u.test(identifier) || identifier === "0" || !identifier.startsWith("0"));
|
|
16
|
+
}
|
|
17
|
+
function isProviderPluginId(value) {
|
|
18
|
+
return typeof value === "string" && value.length <= PROVIDER_PLUGIN_ID_MAX_LENGTH && strictKebabPattern.test(value);
|
|
19
|
+
}
|
|
20
|
+
function isProviderPluginSurfaceId(value) {
|
|
21
|
+
return isProviderPluginId(value);
|
|
22
|
+
}
|
|
23
|
+
function isProviderPluginOperationName(value) {
|
|
24
|
+
if (typeof value !== "string" || value.length > PROVIDER_PLUGIN_OPERATION_NAME_MAX_LENGTH) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const segments = value.split(".");
|
|
28
|
+
return segments.length >= 2 && segments.length <= 4 && segments.every((segment) => segment.length <= 40 && strictKebabSegmentPattern.test(segment));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { PROVIDER_PLUGIN_ID_MAX_LENGTH, PROVIDER_PLUGIN_OPERATION_NAME_MAX_LENGTH, isPortableProviderPluginVersion, isProviderPluginId, isProviderPluginSurfaceId, isProviderPluginOperationName };
|
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
canonicalJson,
|
|
4
|
+
sha256
|
|
5
|
+
} from "./index-gwk7rbyj.js";
|
|
6
|
+
|
|
7
|
+
// src/message-like-me-agentic-messaging.ts
|
|
8
|
+
import { types as nodeTypes } from "util";
|
|
9
|
+
var MESSAGE_LIKE_ME_SOURCE_CONVERSATION_COORDINATE_V1_SCHEMA_VERSION = 1;
|
|
10
|
+
var MESSAGE_LIKE_ME_SOURCE_CONVERSATION_COORDINATE_V1_CONTRACT_ID = "wrench.message-like-me.source-conversation-coordinate.v1";
|
|
11
|
+
var GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_FORMAT = "wrench.messaging-context-binding";
|
|
12
|
+
var GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_ID = "wrench.messaging-context-binding.v1";
|
|
13
|
+
var GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_DESCRIPTOR = Object.freeze({
|
|
14
|
+
contractId: GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_ID,
|
|
15
|
+
fields: Object.freeze([
|
|
16
|
+
"schemaVersion:1",
|
|
17
|
+
"format:wrench.messaging-context-binding",
|
|
18
|
+
"contractId:wrench.messaging-context-binding.v1",
|
|
19
|
+
"contractHash:sha256",
|
|
20
|
+
"routeRef:opaque",
|
|
21
|
+
"contextRef:opaque",
|
|
22
|
+
"exactDataRevision:sha256",
|
|
23
|
+
"latestMessageRevision:sha256",
|
|
24
|
+
"validatedAt:rfc3339",
|
|
25
|
+
"expiresAt:rfc3339"
|
|
26
|
+
]),
|
|
27
|
+
format: "wrench.messaging-contract-descriptor",
|
|
28
|
+
schemaVersion: 1
|
|
29
|
+
});
|
|
30
|
+
var GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_HASH = "5e64da6a3d826e7f6fa3db7dca0a4ba92c10cfb784981e71a25aed9513a5c687";
|
|
31
|
+
var GHOSTGET_MESSAGING_RECEIPT_BINDING_V1_FORMAT = "wrench.messaging-receipt-binding";
|
|
32
|
+
var GHOSTGET_MESSAGING_RECEIPT_BINDING_V1_CONTRACT_ID = "wrench.messaging-receipt-binding.v1";
|
|
33
|
+
var GHOSTGET_MESSAGING_RECEIPT_BINDING_V1_CONTRACT_DESCRIPTOR = Object.freeze({
|
|
34
|
+
contractId: GHOSTGET_MESSAGING_RECEIPT_BINDING_V1_CONTRACT_ID,
|
|
35
|
+
fields: Object.freeze([
|
|
36
|
+
"schemaVersion:1",
|
|
37
|
+
"format:wrench.messaging-receipt-binding",
|
|
38
|
+
"contractId:wrench.messaging-receipt-binding.v1",
|
|
39
|
+
"contractHash:sha256",
|
|
40
|
+
"clientIntentSha256:sha256",
|
|
41
|
+
"routeRefSha256:sha256",
|
|
42
|
+
"contextRefSha256:sha256",
|
|
43
|
+
"turnDigest:sha256",
|
|
44
|
+
"previewDigest:sha256",
|
|
45
|
+
"runId:opaque",
|
|
46
|
+
"state:submitted|failed|partial|indeterminate",
|
|
47
|
+
"partCount:uint",
|
|
48
|
+
"provenPartCount:uint",
|
|
49
|
+
"receiptSha256:sha256",
|
|
50
|
+
"recordedAt:rfc3339"
|
|
51
|
+
]),
|
|
52
|
+
format: "wrench.messaging-contract-descriptor",
|
|
53
|
+
schemaVersion: 1
|
|
54
|
+
});
|
|
55
|
+
var GHOSTGET_MESSAGING_RECEIPT_BINDING_V1_CONTRACT_HASH = "7f6cf724f0200b2399e4f4641c637b20b48914fc5c9b13755127a8ec69fe66f4";
|
|
56
|
+
var GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_FORMAT = "wrench.messaging-context-binding";
|
|
57
|
+
var GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_ID = "wrench.messaging-context-binding.v2";
|
|
58
|
+
var GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_DESCRIPTOR = Object.freeze({
|
|
59
|
+
contractId: GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_ID,
|
|
60
|
+
fields: Object.freeze([
|
|
61
|
+
"schemaVersion:2",
|
|
62
|
+
"format:wrench.messaging-context-binding",
|
|
63
|
+
"contractId:wrench.messaging-context-binding.v2",
|
|
64
|
+
"contractHash:sha256",
|
|
65
|
+
"sourceConversationCoordinate:{contractId,schemaVersion,sha256}",
|
|
66
|
+
"routeRef:opaque",
|
|
67
|
+
"contextRef:opaque",
|
|
68
|
+
"exactDataRevision:sha256",
|
|
69
|
+
"latestMessageRevision:sha256",
|
|
70
|
+
"validatedAt:rfc3339",
|
|
71
|
+
"expiresAt:rfc3339"
|
|
72
|
+
]),
|
|
73
|
+
format: "wrench.messaging-contract-descriptor",
|
|
74
|
+
schemaVersion: 2
|
|
75
|
+
});
|
|
76
|
+
var GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_HASH = sha256(canonicalJson(GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_DESCRIPTOR));
|
|
77
|
+
var GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_FORMAT = "wrench.messaging-receipt-binding";
|
|
78
|
+
var GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_CONTRACT_ID = "wrench.messaging-receipt-binding.v2";
|
|
79
|
+
var GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_CONTRACT_DESCRIPTOR = Object.freeze({
|
|
80
|
+
contractId: GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_CONTRACT_ID,
|
|
81
|
+
fields: Object.freeze([
|
|
82
|
+
"schemaVersion:2",
|
|
83
|
+
"format:wrench.messaging-receipt-binding",
|
|
84
|
+
"contractId:wrench.messaging-receipt-binding.v2",
|
|
85
|
+
"contractHash:sha256",
|
|
86
|
+
"clientIntentSha256:sha256",
|
|
87
|
+
"contextBindingSha256:sha256",
|
|
88
|
+
"sourceConversationCoordinateSha256:sha256",
|
|
89
|
+
"routeRefSha256:sha256",
|
|
90
|
+
"contextRefSha256:sha256",
|
|
91
|
+
"turnDigest:sha256",
|
|
92
|
+
"previewDigest:sha256",
|
|
93
|
+
"runId:opaque",
|
|
94
|
+
"state:submitted|failed|partial|indeterminate",
|
|
95
|
+
"partCount:uint",
|
|
96
|
+
"provenPartCount:uint",
|
|
97
|
+
"receiptSha256:sha256",
|
|
98
|
+
"recordedAt:rfc3339"
|
|
99
|
+
]),
|
|
100
|
+
format: "wrench.messaging-contract-descriptor",
|
|
101
|
+
schemaVersion: 2
|
|
102
|
+
});
|
|
103
|
+
var GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_CONTRACT_HASH = sha256(canonicalJson(GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_CONTRACT_DESCRIPTOR));
|
|
104
|
+
var GHOSTGET_MESSAGING_CLIENT_INTENT_BINDING_V1_FORMAT = "wrench.messaging-client-intent-binding";
|
|
105
|
+
var GHOSTGET_MESSAGING_CLIENT_INTENT_BINDING_V1_CONTRACT_ID = "wrench.messaging-client-intent-binding.v1";
|
|
106
|
+
var GHOSTGET_MESSAGING_CONTEXT_INSTANCE_V1_CONTRACT_ID = "wrench.messaging-context-instance.v1";
|
|
107
|
+
var GHOSTGET_MESSAGING_CONTEXT_INSTANCE_V2_CONTRACT_ID = "wrench.messaging-context-instance.v2";
|
|
108
|
+
function fail(message) {
|
|
109
|
+
throw new TypeError(message);
|
|
110
|
+
}
|
|
111
|
+
function plainObject(value, label) {
|
|
112
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || nodeTypes.isProxy(value) || Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)
|
|
113
|
+
return fail(`${label} must be a plain object`);
|
|
114
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
115
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
116
|
+
if (typeof key !== "string" || descriptor === undefined || !("value" in descriptor) || !descriptor.enumerable)
|
|
117
|
+
return fail(`${label} must contain only enumerable string-keyed data properties`);
|
|
118
|
+
}
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
function exactKeys(value, expected, label) {
|
|
122
|
+
const actual = Object.keys(value).sort();
|
|
123
|
+
const sortedExpected = [...expected].sort();
|
|
124
|
+
if (actual.length !== sortedExpected.length || actual.some((key, index) => key !== sortedExpected[index]))
|
|
125
|
+
return fail(`${label} must contain exactly ${sortedExpected.join(", ")}`);
|
|
126
|
+
}
|
|
127
|
+
function isWellFormedUnicode(value) {
|
|
128
|
+
for (let index = 0;index < value.length; index += 1) {
|
|
129
|
+
const unit = value.charCodeAt(index);
|
|
130
|
+
if (unit >= 55296 && unit <= 56319) {
|
|
131
|
+
const next = value.charCodeAt(index + 1);
|
|
132
|
+
if (!(next >= 56320 && next <= 57343))
|
|
133
|
+
return false;
|
|
134
|
+
index += 1;
|
|
135
|
+
} else if (unit >= 56320 && unit <= 57343) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
function text(value, label, maximumBytes = 1024) {
|
|
142
|
+
if (typeof value !== "string" || value.length === 0 || Buffer.byteLength(value, "utf8") > maximumBytes || /\p{Cc}|\p{Zl}|\p{Zp}/u.test(value) || value !== value.trim() || !isWellFormedUnicode(value))
|
|
143
|
+
return fail(`${label} must be bounded well-formed text without controls or surrounding space`);
|
|
144
|
+
return value;
|
|
145
|
+
}
|
|
146
|
+
function digest(value, label) {
|
|
147
|
+
if (typeof value !== "string" || !/^[a-f0-9]{64}$/u.test(value)) {
|
|
148
|
+
return fail(`${label} must be a lowercase SHA-256 digest`);
|
|
149
|
+
}
|
|
150
|
+
return value;
|
|
151
|
+
}
|
|
152
|
+
function timestamp(value, label) {
|
|
153
|
+
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/u.test(value) || new Date(value).toISOString() !== value)
|
|
154
|
+
return fail(`${label} must be a canonical RFC 3339 timestamp`);
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
function legacyTimestamp(value, label) {
|
|
158
|
+
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?Z$/u.test(value) || !Number.isFinite(Date.parse(value)))
|
|
159
|
+
return fail(`${label} must be an RFC 3339 UTC timestamp`);
|
|
160
|
+
return value;
|
|
161
|
+
}
|
|
162
|
+
function parseMessageLikeMeSourceConversationCoordinateV1(value) {
|
|
163
|
+
const source = plainObject(value, "Message Like Me source-conversation coordinate");
|
|
164
|
+
exactKeys(source, ["sourceAccountId", "sourceExternalId", "coordinate"], "Message Like Me source-conversation coordinate");
|
|
165
|
+
const sourceExternalId = text(source.sourceExternalId, "Message Like Me source-conversation coordinate.sourceExternalId");
|
|
166
|
+
const coordinate = plainObject(source.coordinate, "Message Like Me source-conversation coordinate.coordinate");
|
|
167
|
+
if (coordinate.kind === "beeperConversation") {
|
|
168
|
+
exactKeys(coordinate, ["kind", "network", "conversationId"], "Message Like Me Beeper coordinate");
|
|
169
|
+
const sourceAccountId = text(source.sourceAccountId, "Message Like Me source-conversation coordinate.sourceAccountId");
|
|
170
|
+
if (sourceExternalId !== sourceAccountId) {
|
|
171
|
+
return fail("Message Like Me Beeper source account and external identity must match");
|
|
172
|
+
}
|
|
173
|
+
return Object.freeze({
|
|
174
|
+
sourceAccountId,
|
|
175
|
+
sourceExternalId,
|
|
176
|
+
coordinate: Object.freeze({
|
|
177
|
+
kind: "beeperConversation",
|
|
178
|
+
network: text(coordinate.network, "Message Like Me Beeper coordinate.network", 512),
|
|
179
|
+
conversationId: text(coordinate.conversationId, "Message Like Me Beeper coordinate.conversationId")
|
|
180
|
+
})
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
if (coordinate.kind === "imessageChat") {
|
|
184
|
+
exactKeys(coordinate, ["kind", "chatGuid", "service", "observedChatRowId"], "Message Like Me iMessage coordinate");
|
|
185
|
+
if (source.sourceAccountId !== null) {
|
|
186
|
+
return fail("Message Like Me iMessage sourceAccountId must be null");
|
|
187
|
+
}
|
|
188
|
+
let observedChatRowId;
|
|
189
|
+
if (coordinate.observedChatRowId === null) {
|
|
190
|
+
observedChatRowId = null;
|
|
191
|
+
} else if (typeof coordinate.observedChatRowId === "number" && Number.isFinite(coordinate.observedChatRowId) && Number.isSafeInteger(coordinate.observedChatRowId) && coordinate.observedChatRowId >= 1) {
|
|
192
|
+
observedChatRowId = coordinate.observedChatRowId;
|
|
193
|
+
} else {
|
|
194
|
+
return fail("Message Like Me iMessage observedChatRowId must be a positive safe integer or null");
|
|
195
|
+
}
|
|
196
|
+
return Object.freeze({
|
|
197
|
+
sourceAccountId: null,
|
|
198
|
+
sourceExternalId,
|
|
199
|
+
coordinate: Object.freeze({
|
|
200
|
+
kind: "imessageChat",
|
|
201
|
+
chatGuid: text(coordinate.chatGuid, "Message Like Me iMessage coordinate.chatGuid"),
|
|
202
|
+
service: coordinate.service === null ? null : text(coordinate.service, "Message Like Me iMessage coordinate.service", 512),
|
|
203
|
+
observedChatRowId
|
|
204
|
+
})
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return fail("Message Like Me source-conversation coordinate has an unsupported tag");
|
|
208
|
+
}
|
|
209
|
+
function messageLikeMeSourceConversationCoordinateBindingV1(value) {
|
|
210
|
+
const coordinate = parseMessageLikeMeSourceConversationCoordinateV1(value);
|
|
211
|
+
const canonicalPreimage = Object.freeze({
|
|
212
|
+
contractId: MESSAGE_LIKE_ME_SOURCE_CONVERSATION_COORDINATE_V1_CONTRACT_ID,
|
|
213
|
+
schemaVersion: MESSAGE_LIKE_ME_SOURCE_CONVERSATION_COORDINATE_V1_SCHEMA_VERSION,
|
|
214
|
+
value: coordinate
|
|
215
|
+
});
|
|
216
|
+
return Object.freeze({
|
|
217
|
+
contractId: MESSAGE_LIKE_ME_SOURCE_CONVERSATION_COORDINATE_V1_CONTRACT_ID,
|
|
218
|
+
schemaVersion: MESSAGE_LIKE_ME_SOURCE_CONVERSATION_COORDINATE_V1_SCHEMA_VERSION,
|
|
219
|
+
sha256: sha256(canonicalJson(canonicalPreimage))
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
function parseMessageLikeMeSourceConversationCoordinateBindingV1(value) {
|
|
223
|
+
const binding = plainObject(value, "Ghostget source-conversation coordinate binding");
|
|
224
|
+
exactKeys(binding, ["contractId", "schemaVersion", "sha256"], "Ghostget source-conversation coordinate binding");
|
|
225
|
+
if (binding.contractId !== MESSAGE_LIKE_ME_SOURCE_CONVERSATION_COORDINATE_V1_CONTRACT_ID || binding.schemaVersion !== MESSAGE_LIKE_ME_SOURCE_CONVERSATION_COORDINATE_V1_SCHEMA_VERSION)
|
|
226
|
+
return fail("Ghostget source-conversation coordinate binding has an unsupported contract identity");
|
|
227
|
+
return Object.freeze({
|
|
228
|
+
contractId: MESSAGE_LIKE_ME_SOURCE_CONVERSATION_COORDINATE_V1_CONTRACT_ID,
|
|
229
|
+
schemaVersion: MESSAGE_LIKE_ME_SOURCE_CONVERSATION_COORDINATE_V1_SCHEMA_VERSION,
|
|
230
|
+
sha256: digest(binding.sha256, "Ghostget source-conversation coordinate binding.sha256")
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
function parseGhostgetMessagingContextBindingV1(value) {
|
|
234
|
+
const context = plainObject(value, "Ghostget messaging context binding V1");
|
|
235
|
+
exactKeys(context, [
|
|
236
|
+
"schemaVersion",
|
|
237
|
+
"format",
|
|
238
|
+
"contractId",
|
|
239
|
+
"contractHash",
|
|
240
|
+
"routeRef",
|
|
241
|
+
"contextRef",
|
|
242
|
+
"exactDataRevision",
|
|
243
|
+
"latestMessageRevision",
|
|
244
|
+
"validatedAt",
|
|
245
|
+
"expiresAt"
|
|
246
|
+
], "Ghostget messaging context binding V1");
|
|
247
|
+
if (context.schemaVersion !== 1 || context.format !== GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_FORMAT || context.contractId !== GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_ID || context.contractHash !== GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_HASH)
|
|
248
|
+
return fail("Ghostget messaging context binding V1 has an unsupported contract identity");
|
|
249
|
+
const validatedAt = legacyTimestamp(context.validatedAt, "Ghostget messaging context binding V1.validatedAt");
|
|
250
|
+
const expiresAt = legacyTimestamp(context.expiresAt, "Ghostget messaging context binding V1.expiresAt");
|
|
251
|
+
if (Date.parse(expiresAt) <= Date.parse(validatedAt)) {
|
|
252
|
+
return fail("Ghostget messaging context binding V1.expiresAt must follow validatedAt");
|
|
253
|
+
}
|
|
254
|
+
return Object.freeze({
|
|
255
|
+
schemaVersion: 1,
|
|
256
|
+
format: GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_FORMAT,
|
|
257
|
+
contractId: GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_ID,
|
|
258
|
+
contractHash: GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_HASH,
|
|
259
|
+
routeRef: text(context.routeRef, "Ghostget messaging context binding V1.routeRef", 2048),
|
|
260
|
+
contextRef: text(context.contextRef, "Ghostget messaging context binding V1.contextRef", 2048),
|
|
261
|
+
exactDataRevision: digest(context.exactDataRevision, "Ghostget messaging context binding V1.exactDataRevision"),
|
|
262
|
+
latestMessageRevision: digest(context.latestMessageRevision, "Ghostget messaging context binding V1.latestMessageRevision"),
|
|
263
|
+
validatedAt,
|
|
264
|
+
expiresAt
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
function parseGhostgetMessagingContextBindingV2(value) {
|
|
268
|
+
const context = plainObject(value, "Ghostget messaging context binding");
|
|
269
|
+
exactKeys(context, [
|
|
270
|
+
"schemaVersion",
|
|
271
|
+
"format",
|
|
272
|
+
"contractId",
|
|
273
|
+
"contractHash",
|
|
274
|
+
"sourceConversationCoordinate",
|
|
275
|
+
"routeRef",
|
|
276
|
+
"contextRef",
|
|
277
|
+
"exactDataRevision",
|
|
278
|
+
"latestMessageRevision",
|
|
279
|
+
"validatedAt",
|
|
280
|
+
"expiresAt"
|
|
281
|
+
], "Ghostget messaging context binding");
|
|
282
|
+
if (context.schemaVersion !== 2 || context.format !== GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_FORMAT || context.contractId !== GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_ID || context.contractHash !== GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_HASH)
|
|
283
|
+
return fail("Ghostget messaging context binding has an unsupported contract identity");
|
|
284
|
+
const validatedAt = timestamp(context.validatedAt, "Ghostget messaging context binding.validatedAt");
|
|
285
|
+
const expiresAt = timestamp(context.expiresAt, "Ghostget messaging context binding.expiresAt");
|
|
286
|
+
const lifetime = Date.parse(expiresAt) - Date.parse(validatedAt);
|
|
287
|
+
if (lifetime <= 0 || lifetime > 24 * 60 * 60 * 1000) {
|
|
288
|
+
return fail("Ghostget messaging context binding has an invalid lifetime");
|
|
289
|
+
}
|
|
290
|
+
return Object.freeze({
|
|
291
|
+
schemaVersion: 2,
|
|
292
|
+
format: GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_FORMAT,
|
|
293
|
+
contractId: GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_ID,
|
|
294
|
+
contractHash: GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_HASH,
|
|
295
|
+
sourceConversationCoordinate: parseMessageLikeMeSourceConversationCoordinateBindingV1(context.sourceConversationCoordinate),
|
|
296
|
+
routeRef: text(context.routeRef, "Ghostget messaging context binding.routeRef", 2048),
|
|
297
|
+
contextRef: text(context.contextRef, "Ghostget messaging context binding.contextRef", 2048),
|
|
298
|
+
exactDataRevision: digest(context.exactDataRevision, "Ghostget messaging context binding.exactDataRevision"),
|
|
299
|
+
latestMessageRevision: digest(context.latestMessageRevision, "Ghostget messaging context binding.latestMessageRevision"),
|
|
300
|
+
validatedAt,
|
|
301
|
+
expiresAt
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
function ghostgetMessagingContextBindingSha256V1(value) {
|
|
305
|
+
const context = parseGhostgetMessagingContextBindingV1(value);
|
|
306
|
+
return sha256(canonicalJson({
|
|
307
|
+
contractId: GHOSTGET_MESSAGING_CONTEXT_INSTANCE_V1_CONTRACT_ID,
|
|
308
|
+
schemaVersion: 1,
|
|
309
|
+
value: context
|
|
310
|
+
}));
|
|
311
|
+
}
|
|
312
|
+
function parsedContextBindingSha256V2(context) {
|
|
313
|
+
return sha256(canonicalJson({
|
|
314
|
+
contractId: GHOSTGET_MESSAGING_CONTEXT_INSTANCE_V2_CONTRACT_ID,
|
|
315
|
+
schemaVersion: 2,
|
|
316
|
+
value: context
|
|
317
|
+
}));
|
|
318
|
+
}
|
|
319
|
+
function ghostgetMessagingContextBindingSha256V2(value) {
|
|
320
|
+
return parsedContextBindingSha256V2(parseGhostgetMessagingContextBindingV2(value));
|
|
321
|
+
}
|
|
322
|
+
var BEEPER_EXACT_CONVERSATION_KEYS = Object.freeze([
|
|
323
|
+
"id",
|
|
324
|
+
"localChatId",
|
|
325
|
+
"accountId",
|
|
326
|
+
"network",
|
|
327
|
+
"title",
|
|
328
|
+
"type",
|
|
329
|
+
"description",
|
|
330
|
+
"descriptionObserved",
|
|
331
|
+
"hasAvatar",
|
|
332
|
+
"avatarObserved",
|
|
333
|
+
"lastReadMessageSortKey",
|
|
334
|
+
"lastActivity",
|
|
335
|
+
"unreadCount",
|
|
336
|
+
"unreadMentionsCount",
|
|
337
|
+
"isMarkedUnread",
|
|
338
|
+
"isArchived",
|
|
339
|
+
"isLowPriority",
|
|
340
|
+
"isMuted",
|
|
341
|
+
"isPinned",
|
|
342
|
+
"isReadOnly",
|
|
343
|
+
"messageExpirySeconds",
|
|
344
|
+
"messageExpiryObserved",
|
|
345
|
+
"draft",
|
|
346
|
+
"draftObserved",
|
|
347
|
+
"reminder",
|
|
348
|
+
"reminderObserved",
|
|
349
|
+
"participants"
|
|
350
|
+
]);
|
|
351
|
+
function createBeeperMessageLikeMeSourceConversationCoordinateBindingV1(input) {
|
|
352
|
+
const read = plainObject(input.conversationRead, "Ghostget Beeper exact conversation read");
|
|
353
|
+
exactKeys(read, ["provider", "operation", "accountSubject", "conversation"], "Ghostget Beeper exact conversation read");
|
|
354
|
+
if (read.provider !== "beeper" || read.operation !== "conversations.read") {
|
|
355
|
+
return fail("Ghostget context requires an exact Beeper conversations.read projection");
|
|
356
|
+
}
|
|
357
|
+
const expectedAccountSubject = text(input.expectedAccountSubject, "Ghostget Beeper expected account subject");
|
|
358
|
+
if (text(read.accountSubject, "Ghostget Beeper exact conversation read.accountSubject") !== expectedAccountSubject)
|
|
359
|
+
return fail("Ghostget Beeper exact conversation read did not bind the expected account subject");
|
|
360
|
+
const conversation = plainObject(read.conversation, "Ghostget Beeper exact conversation read.conversation");
|
|
361
|
+
exactKeys(conversation, BEEPER_EXACT_CONVERSATION_KEYS, "Ghostget Beeper exact conversation read.conversation");
|
|
362
|
+
if (conversation.type !== "single") {
|
|
363
|
+
return fail("Ghostget Message Like Me context requires a direct Beeper conversation");
|
|
364
|
+
}
|
|
365
|
+
if (conversation.isReadOnly !== false) {
|
|
366
|
+
return fail("Ghostget Message Like Me context requires a writable Beeper conversation");
|
|
367
|
+
}
|
|
368
|
+
const accountId = text(conversation.accountId, "Ghostget Beeper exact conversation read.conversation.accountId");
|
|
369
|
+
return messageLikeMeSourceConversationCoordinateBindingV1({
|
|
370
|
+
sourceAccountId: accountId,
|
|
371
|
+
sourceExternalId: accountId,
|
|
372
|
+
coordinate: {
|
|
373
|
+
kind: "beeperConversation",
|
|
374
|
+
network: text(conversation.network, "Ghostget Beeper exact conversation read.conversation.network", 512),
|
|
375
|
+
conversationId: text(conversation.id, "Ghostget Beeper exact conversation read.conversation.id")
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
function createBeeperMessageLikeMeContextBindingV1(input) {
|
|
380
|
+
createBeeperMessageLikeMeSourceConversationCoordinateBindingV1({
|
|
381
|
+
conversationRead: input.conversationRead,
|
|
382
|
+
expectedAccountSubject: input.expectedAccountSubject
|
|
383
|
+
});
|
|
384
|
+
return parseGhostgetMessagingContextBindingV1(Object.freeze({
|
|
385
|
+
schemaVersion: 1,
|
|
386
|
+
format: GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_FORMAT,
|
|
387
|
+
contractId: GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_ID,
|
|
388
|
+
contractHash: GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_HASH,
|
|
389
|
+
routeRef: text(input.routeRef, "Ghostget messaging context binding V1.routeRef", 2048),
|
|
390
|
+
contextRef: text(input.contextRef, "Ghostget messaging context binding V1.contextRef", 2048),
|
|
391
|
+
exactDataRevision: digest(input.exactDataRevision, "Ghostget messaging context binding V1.exactDataRevision"),
|
|
392
|
+
latestMessageRevision: digest(input.latestMessageRevision, "Ghostget messaging context binding V1.latestMessageRevision"),
|
|
393
|
+
validatedAt: input.validatedAt,
|
|
394
|
+
expiresAt: input.expiresAt
|
|
395
|
+
}));
|
|
396
|
+
}
|
|
397
|
+
function createBeeperMessageLikeMeContextBindingV2(input) {
|
|
398
|
+
const sourceConversationCoordinate = createBeeperMessageLikeMeSourceConversationCoordinateBindingV1({
|
|
399
|
+
conversationRead: input.conversationRead,
|
|
400
|
+
expectedAccountSubject: input.expectedAccountSubject
|
|
401
|
+
});
|
|
402
|
+
return parseGhostgetMessagingContextBindingV2(Object.freeze({
|
|
403
|
+
schemaVersion: 2,
|
|
404
|
+
format: GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_FORMAT,
|
|
405
|
+
contractId: GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_ID,
|
|
406
|
+
contractHash: GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_HASH,
|
|
407
|
+
sourceConversationCoordinate,
|
|
408
|
+
routeRef: text(input.routeRef, "Ghostget messaging context binding.routeRef", 2048),
|
|
409
|
+
contextRef: text(input.contextRef, "Ghostget messaging context binding.contextRef", 2048),
|
|
410
|
+
exactDataRevision: digest(input.exactDataRevision, "Ghostget messaging context binding.exactDataRevision"),
|
|
411
|
+
latestMessageRevision: digest(input.latestMessageRevision, "Ghostget messaging context binding.latestMessageRevision"),
|
|
412
|
+
validatedAt: input.validatedAt,
|
|
413
|
+
expiresAt: input.expiresAt
|
|
414
|
+
}));
|
|
415
|
+
}
|
|
416
|
+
function parseGhostgetMessagingClientIntentBindingV1(value, contextValue) {
|
|
417
|
+
const context = parseGhostgetMessagingContextBindingV2(contextValue);
|
|
418
|
+
const intent = plainObject(value, "Ghostget messaging client-intent binding");
|
|
419
|
+
exactKeys(intent, [
|
|
420
|
+
"schemaVersion",
|
|
421
|
+
"format",
|
|
422
|
+
"contractId",
|
|
423
|
+
"clientIntentSha256",
|
|
424
|
+
"contextBindingSha256",
|
|
425
|
+
"sourceConversationCoordinateSha256",
|
|
426
|
+
"routeRefSha256",
|
|
427
|
+
"contextRefSha256",
|
|
428
|
+
"turnDigest",
|
|
429
|
+
"partCount"
|
|
430
|
+
], "Ghostget messaging client-intent binding");
|
|
431
|
+
if (intent.schemaVersion !== 1 || intent.format !== GHOSTGET_MESSAGING_CLIENT_INTENT_BINDING_V1_FORMAT || intent.contractId !== GHOSTGET_MESSAGING_CLIENT_INTENT_BINDING_V1_CONTRACT_ID)
|
|
432
|
+
return fail("Ghostget messaging client-intent binding has an unsupported contract identity");
|
|
433
|
+
if (!Number.isSafeInteger(intent.partCount) || intent.partCount < 1 || intent.partCount > 8) {
|
|
434
|
+
return fail("Ghostget messaging client-intent binding.partCount must be from 1 through 8");
|
|
435
|
+
}
|
|
436
|
+
const parsed = Object.freeze({
|
|
437
|
+
schemaVersion: 1,
|
|
438
|
+
format: GHOSTGET_MESSAGING_CLIENT_INTENT_BINDING_V1_FORMAT,
|
|
439
|
+
contractId: GHOSTGET_MESSAGING_CLIENT_INTENT_BINDING_V1_CONTRACT_ID,
|
|
440
|
+
clientIntentSha256: digest(intent.clientIntentSha256, "Ghostget messaging client-intent binding.clientIntentSha256"),
|
|
441
|
+
contextBindingSha256: digest(intent.contextBindingSha256, "Ghostget messaging client-intent binding.contextBindingSha256"),
|
|
442
|
+
sourceConversationCoordinateSha256: digest(intent.sourceConversationCoordinateSha256, "Ghostget messaging client-intent binding.sourceConversationCoordinateSha256"),
|
|
443
|
+
routeRefSha256: digest(intent.routeRefSha256, "Ghostget messaging client-intent binding.routeRefSha256"),
|
|
444
|
+
contextRefSha256: digest(intent.contextRefSha256, "Ghostget messaging client-intent binding.contextRefSha256"),
|
|
445
|
+
turnDigest: digest(intent.turnDigest, "Ghostget messaging client-intent binding.turnDigest"),
|
|
446
|
+
partCount: intent.partCount
|
|
447
|
+
});
|
|
448
|
+
if (parsed.contextBindingSha256 !== parsedContextBindingSha256V2(context) || parsed.sourceConversationCoordinateSha256 !== context.sourceConversationCoordinate.sha256 || parsed.routeRefSha256 !== sha256(context.routeRef) || parsed.contextRefSha256 !== sha256(context.contextRef))
|
|
449
|
+
return fail("Ghostget messaging client intent does not bind the exact context instance");
|
|
450
|
+
return parsed;
|
|
451
|
+
}
|
|
452
|
+
function createGhostgetMessagingReceiptBindingV2(input) {
|
|
453
|
+
const intent = parseGhostgetMessagingClientIntentBindingV1(input.clientIntent, input.context);
|
|
454
|
+
if (input.state !== "submitted" && input.state !== "failed" && input.state !== "partial" && input.state !== "indeterminate")
|
|
455
|
+
return fail("Ghostget messaging receipt binding has an invalid state");
|
|
456
|
+
if (!Number.isSafeInteger(input.provenPartCount) || input.provenPartCount < 0 || input.provenPartCount > intent.partCount)
|
|
457
|
+
return fail("Ghostget messaging receipt binding.provenPartCount is out of range");
|
|
458
|
+
const provenPartCount = input.provenPartCount;
|
|
459
|
+
if (input.state === "submitted" && provenPartCount !== intent.partCount || input.state === "failed" && provenPartCount !== 0 || input.state === "partial" && (provenPartCount < 1 || provenPartCount >= intent.partCount) || input.state === "indeterminate" && provenPartCount >= intent.partCount)
|
|
460
|
+
return fail("Ghostget messaging receipt binding state does not match its proven prefix");
|
|
461
|
+
const core = Object.freeze({
|
|
462
|
+
schemaVersion: 2,
|
|
463
|
+
format: GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_FORMAT,
|
|
464
|
+
contractId: GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_CONTRACT_ID,
|
|
465
|
+
contractHash: GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_CONTRACT_HASH,
|
|
466
|
+
clientIntentSha256: intent.clientIntentSha256,
|
|
467
|
+
contextBindingSha256: intent.contextBindingSha256,
|
|
468
|
+
sourceConversationCoordinateSha256: intent.sourceConversationCoordinateSha256,
|
|
469
|
+
routeRefSha256: intent.routeRefSha256,
|
|
470
|
+
contextRefSha256: intent.contextRefSha256,
|
|
471
|
+
turnDigest: intent.turnDigest,
|
|
472
|
+
previewDigest: digest(input.previewDigest, "Ghostget receipt.previewDigest"),
|
|
473
|
+
runId: text(input.runId, "Ghostget receipt.runId", 256),
|
|
474
|
+
state: input.state,
|
|
475
|
+
partCount: intent.partCount,
|
|
476
|
+
provenPartCount,
|
|
477
|
+
recordedAt: timestamp(input.recordedAt, "Ghostget receipt.recordedAt")
|
|
478
|
+
});
|
|
479
|
+
return Object.freeze({
|
|
480
|
+
...core,
|
|
481
|
+
receiptSha256: sha256(canonicalJson(core))
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
function createGhostgetMessagingReceiptBindingV1(input) {
|
|
485
|
+
const enriched = createGhostgetMessagingReceiptBindingV2(input);
|
|
486
|
+
const core = Object.freeze({
|
|
487
|
+
schemaVersion: 1,
|
|
488
|
+
format: GHOSTGET_MESSAGING_RECEIPT_BINDING_V1_FORMAT,
|
|
489
|
+
contractId: GHOSTGET_MESSAGING_RECEIPT_BINDING_V1_CONTRACT_ID,
|
|
490
|
+
contractHash: GHOSTGET_MESSAGING_RECEIPT_BINDING_V1_CONTRACT_HASH,
|
|
491
|
+
clientIntentSha256: enriched.clientIntentSha256,
|
|
492
|
+
routeRefSha256: enriched.routeRefSha256,
|
|
493
|
+
contextRefSha256: enriched.contextRefSha256,
|
|
494
|
+
turnDigest: enriched.turnDigest,
|
|
495
|
+
previewDigest: enriched.previewDigest,
|
|
496
|
+
runId: enriched.runId,
|
|
497
|
+
state: enriched.state,
|
|
498
|
+
partCount: enriched.partCount,
|
|
499
|
+
provenPartCount: enriched.provenPartCount,
|
|
500
|
+
recordedAt: enriched.recordedAt
|
|
501
|
+
});
|
|
502
|
+
return Object.freeze({
|
|
503
|
+
...core,
|
|
504
|
+
receiptSha256: sha256(canonicalJson(core))
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
export { MESSAGE_LIKE_ME_SOURCE_CONVERSATION_COORDINATE_V1_SCHEMA_VERSION, MESSAGE_LIKE_ME_SOURCE_CONVERSATION_COORDINATE_V1_CONTRACT_ID, GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_FORMAT, GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_ID, GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_DESCRIPTOR, GHOSTGET_MESSAGING_CONTEXT_BINDING_V1_CONTRACT_HASH, GHOSTGET_MESSAGING_RECEIPT_BINDING_V1_FORMAT, GHOSTGET_MESSAGING_RECEIPT_BINDING_V1_CONTRACT_ID, GHOSTGET_MESSAGING_RECEIPT_BINDING_V1_CONTRACT_DESCRIPTOR, GHOSTGET_MESSAGING_RECEIPT_BINDING_V1_CONTRACT_HASH, GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_FORMAT, GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_ID, GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_DESCRIPTOR, GHOSTGET_MESSAGING_CONTEXT_BINDING_V2_CONTRACT_HASH, GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_FORMAT, GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_CONTRACT_ID, GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_CONTRACT_DESCRIPTOR, GHOSTGET_MESSAGING_RECEIPT_BINDING_V2_CONTRACT_HASH, GHOSTGET_MESSAGING_CLIENT_INTENT_BINDING_V1_FORMAT, GHOSTGET_MESSAGING_CLIENT_INTENT_BINDING_V1_CONTRACT_ID, GHOSTGET_MESSAGING_CONTEXT_INSTANCE_V1_CONTRACT_ID, GHOSTGET_MESSAGING_CONTEXT_INSTANCE_V2_CONTRACT_ID, parseMessageLikeMeSourceConversationCoordinateV1, messageLikeMeSourceConversationCoordinateBindingV1, parseGhostgetMessagingContextBindingV1, parseGhostgetMessagingContextBindingV2, ghostgetMessagingContextBindingSha256V1, ghostgetMessagingContextBindingSha256V2, createBeeperMessageLikeMeContextBindingV1, createBeeperMessageLikeMeContextBindingV2, parseGhostgetMessagingClientIntentBindingV1, createGhostgetMessagingReceiptBindingV2, createGhostgetMessagingReceiptBindingV1 };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/canonical-json.ts
|
|
3
|
+
import { createHash } from "crypto";
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function canonicalJson(value) {
|
|
8
|
+
if (value === null || typeof value === "boolean" || typeof value === "string") {
|
|
9
|
+
return JSON.stringify(value);
|
|
10
|
+
}
|
|
11
|
+
if (typeof value === "number") {
|
|
12
|
+
if (!Number.isFinite(value)) {
|
|
13
|
+
throw new Error("canonical JSON cannot represent a non-finite number");
|
|
14
|
+
}
|
|
15
|
+
return JSON.stringify(value);
|
|
16
|
+
}
|
|
17
|
+
if (Array.isArray(value)) {
|
|
18
|
+
return `[${value.map((item) => canonicalJson(item)).join(",")}]`;
|
|
19
|
+
}
|
|
20
|
+
if (isRecord(value)) {
|
|
21
|
+
const entries = Object.entries(value).filter(([, item]) => item !== undefined).sort(([left], [right]) => left.localeCompare(right));
|
|
22
|
+
return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${canonicalJson(item)}`).join(",")}}`;
|
|
23
|
+
}
|
|
24
|
+
throw new Error("canonical JSON supports only JSON-compatible values");
|
|
25
|
+
}
|
|
26
|
+
function sha256(value) {
|
|
27
|
+
return createHash("sha256").update(value).digest("hex");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { canonicalJson, sha256 };
|