@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,235 @@
|
|
|
1
|
+
# Native article drafts
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- [Own the editorial translation](#own-the-editorial-translation)
|
|
6
|
+
- [Build the mixed document](#build-the-mixed-document)
|
|
7
|
+
- [Project source-post embeds](#project-source-post-embeds)
|
|
8
|
+
- [Save without publishing](#save-without-publishing)
|
|
9
|
+
- [Read one saved X draft](#read-one-saved-x-draft)
|
|
10
|
+
- [Handle uncertainty](#handle-uncertainty)
|
|
11
|
+
- [Check provider state](#check-provider-state)
|
|
12
|
+
|
|
13
|
+
Use `articles.draft.save` to create or replace one private native long-form
|
|
14
|
+
draft. Treat it as an R2 mutation with its own preview, confirmation, dispatch
|
|
15
|
+
record, and provider-bound unpublished result. It has no publish-capable
|
|
16
|
+
branch.
|
|
17
|
+
|
|
18
|
+
Keep `articles.publish` separate. Publication is R3 and requires a different
|
|
19
|
+
installed observed contract, input, preview, and confirmation. A saved draft
|
|
20
|
+
ID is not permission to publish, and a draft preview cannot be reused for
|
|
21
|
+
publication.
|
|
22
|
+
|
|
23
|
+
## Own the editorial translation
|
|
24
|
+
|
|
25
|
+
Capture or read source material separately. The caller decides how to
|
|
26
|
+
translate, abridge, retitle, attribute, link, and place images. Ghostget does not
|
|
27
|
+
turn source HTML, Markdown, or a URL into provider copy and does not infer
|
|
28
|
+
attribution or alternative text. Pass only the final reviewed title, canonical
|
|
29
|
+
document, and exact local image files to the mutation.
|
|
30
|
+
|
|
31
|
+
## Build the mixed document
|
|
32
|
+
|
|
33
|
+
The current `x-web` and `linkedin-web` capabilities require canonical JSON for
|
|
34
|
+
`ArticleDraftDocument` schemaVersion 2. Text blocks are:
|
|
35
|
+
|
|
36
|
+
- `paragraph`
|
|
37
|
+
- `heading1`
|
|
38
|
+
- `heading2`
|
|
39
|
+
- `blockquote`
|
|
40
|
+
- `unordered-list-item`
|
|
41
|
+
- `ordered-list-item`
|
|
42
|
+
|
|
43
|
+
Represent a native link with an ordered, non-overlapping range over the
|
|
44
|
+
block's UTF-16 text and one canonical absolute HTTPS URL. Represent bold,
|
|
45
|
+
italic, or strikethrough with ordered style ranges. Put each paragraph or list
|
|
46
|
+
item in its own block; block text cannot contain a newline.
|
|
47
|
+
|
|
48
|
+
Place an inline image with an `image` block. Its `imageIndex` is the zero-based
|
|
49
|
+
position of the matching file in outer `input.inline_images`. Image indexes
|
|
50
|
+
must be unique, contiguous from zero, and referenced exactly once. A caption
|
|
51
|
+
is optional. Platform metadata differs:
|
|
52
|
+
|
|
53
|
+
- `x-web` supports captions but its native alt-text write remains
|
|
54
|
+
capture-required, so omit `altText`.
|
|
55
|
+
- `linkedin-web` requires a non-empty descriptive `altText`; captions are
|
|
56
|
+
optional.
|
|
57
|
+
|
|
58
|
+
Both current web adapters accept 1–20 ordered JPEG, PNG, or WebP files, at most
|
|
59
|
+
5 MiB each. Ghostget sniffs the bytes, copies them into the encrypted preview's
|
|
60
|
+
plan-asset bundle, hashes them, removes source paths and filenames from the
|
|
61
|
+
preview, and reverifies the exact bytes before dispatch. Do not pass a URL,
|
|
62
|
+
provider asset ID, expiring CDN source, cover, video, embed, HTML, Markdown, or
|
|
63
|
+
editor payload as an inline image.
|
|
64
|
+
|
|
65
|
+
`linkedin-web` requires one outer `input.cover_image` JPEG, PNG, or WebP file
|
|
66
|
+
up to 5 MiB when creating a draft. Supply it on replacement only to replace
|
|
67
|
+
the banner; omit it with an exact `draft_id` to preserve the independently
|
|
68
|
+
read existing banner without another cover registration or transfer. A
|
|
69
|
+
supplied cover is a separate plan-bound attachment and does not
|
|
70
|
+
implicitly create a document `image` block or appear in `input.inline_images`.
|
|
71
|
+
For a cover-only source asset, keep it out of the body; include the same bytes
|
|
72
|
+
as an inline image only when the reviewed article intentionally shows them in
|
|
73
|
+
both places.
|
|
74
|
+
Ghostget registers it as `PUBLISHING_COVER_IMAGE`, transfers the exact bytes,
|
|
75
|
+
binds the returned asset only through LinkedIn's `coverMediaV2Union.coverImage`
|
|
76
|
+
autosave, and independently verifies both saved cover projections. The current
|
|
77
|
+
contract writes an empty cover caption. `x-web` cover saving remains
|
|
78
|
+
capture-required.
|
|
79
|
+
|
|
80
|
+
Provider text support remains narrower where capture evidence is narrower:
|
|
81
|
+
`linkedin-web` accepts `paragraph`, `heading1`, `heading2`, and `blockquote`, native
|
|
82
|
+
HTTPS links, and no text styles. `x-web` accepts all listed text block types,
|
|
83
|
+
native links, and bold, italic, or strikethrough.
|
|
84
|
+
|
|
85
|
+
## Project source-post embeds
|
|
86
|
+
|
|
87
|
+
Treat a source X status as editorial content, not as provider editor payload.
|
|
88
|
+
Do not copy its profile chrome, timestamp, engagement counts, or screenshot of
|
|
89
|
+
the rendered card into an Article by default. Do not assume that pasting a URL
|
|
90
|
+
creates a proprietary embed.
|
|
91
|
+
|
|
92
|
+
Use the exported `projectXStatusArticleEmbed` helper with the exact status text,
|
|
93
|
+
canonical source URL, and destination adapter. It removes share-tracking query
|
|
94
|
+
parameters and emits the status URL as one native linked paragraph immediately
|
|
95
|
+
after the content:
|
|
96
|
+
|
|
97
|
+
- `x-web` and `linkedin-web`: emit each non-empty source line as a native
|
|
98
|
+
`blockquote`.
|
|
99
|
+
|
|
100
|
+
Preserve media attached to the source status only when the user explicitly
|
|
101
|
+
wants that media as independent Article images. Otherwise keep the quote and
|
|
102
|
+
status link only. The helper does not fetch a status, infer its text, upload
|
|
103
|
+
media, or claim that either provider created a native embed card.
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { projectXStatusArticleEmbed } from "@hraness/ghostget";
|
|
107
|
+
|
|
108
|
+
const blocks = projectXStatusArticleEmbed({
|
|
109
|
+
text: "Exact source-post text",
|
|
110
|
+
url: "https://x.com/example/status/123?s=20",
|
|
111
|
+
}, "x-web");
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
This is canonical X document JSON with one native link and one image:
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{"blocks":[{"links":[{"length":6,"offset":9,"url":"https://example.com/source"}],"text":"Read the source","type":"paragraph"},{"caption":"Puerto Rico","imageIndex":0,"type":"image"}],"schemaVersion":2}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Put that exact inner JSON string and an absolute local image path in a private
|
|
121
|
+
invocation input file:
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"title": "Reviewed title",
|
|
126
|
+
"document": "{\"blocks\":[{\"links\":[{\"length\":6,\"offset\":9,\"url\":\"https://example.com/source\"}],\"text\":\"Read the source\",\"type\":\"paragraph\"},{\"caption\":\"Puerto Rico\",\"imageIndex\":0,\"type\":\"image\"}],\"schemaVersion\":2}",
|
|
127
|
+
"inline_images": ["/absolute/private/puerto-rico.png"]
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
For LinkedIn, add `"altText":"A descriptive account of the image"` before
|
|
132
|
+
`caption` in the canonical image block. If the final block is an image, do not
|
|
133
|
+
add an empty paragraph after it; LinkedIn owns that editor-only trailing block
|
|
134
|
+
and Ghostget removes exactly that provider-added value during readback.
|
|
135
|
+
Also add a sibling `"cover_image":"/absolute/private/banner.jpg"` to the
|
|
136
|
+
outer invocation object when creating or replacing the banner; keep the banner
|
|
137
|
+
out of the document blocks and out of `inline_images`. For a replacement that
|
|
138
|
+
must retain its existing banner, omit `cover_image` and keep the exact
|
|
139
|
+
`draft_id`.
|
|
140
|
+
|
|
141
|
+
Add `draft_id` only to replace the exact existing private draft owned by the
|
|
142
|
+
bound account. Treat `ghostget capabilities <adapter> --json` as authoritative
|
|
143
|
+
for all installed bounds and contract versions.
|
|
144
|
+
|
|
145
|
+
## Save without publishing
|
|
146
|
+
|
|
147
|
+
Inspect support and use the exact provider and auth realm printed by the
|
|
148
|
+
installed capability:
|
|
149
|
+
|
|
150
|
+
```sh
|
|
151
|
+
ghostget capabilities x-web --json
|
|
152
|
+
ghostget x-web articles.draft.save \
|
|
153
|
+
--input @/absolute/private/article-draft-input.json \
|
|
154
|
+
--auth x-main --preview --json
|
|
155
|
+
ghostget confirm <preview-digest> --json
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Use the same sequence with `linkedin-web` and its bound LinkedIn cookie realm;
|
|
159
|
+
never switch adapter or auth realm after preview. LinkedIn executes its fixed
|
|
160
|
+
reviewed current single-upload registration, signed byte-transfer, autosave,
|
|
161
|
+
and editor-response readback contract inside contained headed Chrome. The reviewed editor proceeds
|
|
162
|
+
from the transfer's `201` response directly to autosave; Ghostget does not invent
|
|
163
|
+
a processing poll that the editor does not perform. The window may appear, but
|
|
164
|
+
Ghostget does not type into or read the editor DOM, and callers cannot supply a
|
|
165
|
+
URL, header, script, or selector.
|
|
166
|
+
|
|
167
|
+
Review the account, title, canonical document, separate cover hash, ordered inline attachment hashes,
|
|
168
|
+
optional draft ID, R2 side effect, contract version, and every planned
|
|
169
|
+
dispatch. X plans one dispatch per image followed by create, or image uploads
|
|
170
|
+
then title and content replacement. LinkedIn create plans the title shell,
|
|
171
|
+
cover, each inline image, then content; replacement plans cover, each inline
|
|
172
|
+
image, then one conservative title/content replacement.
|
|
173
|
+
|
|
174
|
+
Require a successful result to identify `articles.draft.save`, report
|
|
175
|
+
`published: false` and `mode: "draft"`, return the private draft identity, and
|
|
176
|
+
report the exact cover and inline image counts. X verifies the owner, private Draft lifecycle,
|
|
177
|
+
title, text/link/style structure, captions, image order, and uploaded media
|
|
178
|
+
IDs. LinkedIn verifies the current author, private `DRAFT` lifecycle, title,
|
|
179
|
+
separate cover asset, text/link structure, inline-image order, alt text,
|
|
180
|
+
captions, and stable asset URNs.
|
|
181
|
+
Never continue into publication.
|
|
182
|
+
|
|
183
|
+
## Read one saved X draft
|
|
184
|
+
|
|
185
|
+
`x-web articles.read@2` reads one exact current-viewer-owned private Article
|
|
186
|
+
draft by its 1–19 digit provider ID. It is an R1 operation, uses the same bound
|
|
187
|
+
X cookie realm, and never enters the mutation dispatch ledger.
|
|
188
|
+
|
|
189
|
+
```sh
|
|
190
|
+
ghostget x-web articles.read \
|
|
191
|
+
--input '{"article_id":"1234567890123456789"}' \
|
|
192
|
+
--auth x-main --json
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
The closed result identifies `provider: "x"` and `operation: "articles.read"`.
|
|
196
|
+
Its `article` binds the requested ID, current viewer's owner ID,
|
|
197
|
+
`kind: "private-draft"`, `lifecycle: "Draft"`, `published: false`, one bounded
|
|
198
|
+
single-line title, and bounded rich content. The contract fails closed if the
|
|
199
|
+
Article is missing, published, not in the Draft lifecycle, or owned by another
|
|
200
|
+
account.
|
|
201
|
+
|
|
202
|
+
This operation does not list drafts or read published X Articles. LinkedIn
|
|
203
|
+
Article reads remain capture-required; do not infer them from
|
|
204
|
+
`linkedin-web articles.draft.save` or switch transports to fill the gap.
|
|
205
|
+
|
|
206
|
+
## Handle uncertainty
|
|
207
|
+
|
|
208
|
+
Do not retry a partial or indeterminate image save. An upload may have produced
|
|
209
|
+
a provider asset even when its stable identity never entered the confirmed
|
|
210
|
+
result. Preserve the run, inspect the exact private draft, and do not search by
|
|
211
|
+
title, guess an ID, repeat uploads, switch transports, or publish as recovery.
|
|
212
|
+
|
|
213
|
+
Current image-capable X and LinkedIn draft contracts deliberately have no
|
|
214
|
+
automated reconciliation path. Only already-durable historical text-only
|
|
215
|
+
contracts retain read-only replacement reconciliation for an exact confirmed
|
|
216
|
+
`draft_id`; that historical route is never selected for a new preview.
|
|
217
|
+
|
|
218
|
+
## Check provider state
|
|
219
|
+
|
|
220
|
+
- `x`: the documented OAuth adapter has separate response-bound private-draft
|
|
221
|
+
and publish operations with its own plain-text/optional-cover schema. It is
|
|
222
|
+
not a substitute for `x-web` and does not accept this mixed document.
|
|
223
|
+
- `x-web`: `articles.draft.save@2` creates or replaces one private structured
|
|
224
|
+
Article with native links, styles, ordered inline images, and captions, then
|
|
225
|
+
verifies the unpublished result. `articles.read@2` separately reads one exact
|
|
226
|
+
current-viewer-owned private Draft. Alt text, covers, published Article reads,
|
|
227
|
+
and `articles.publish` remain capture-required.
|
|
228
|
+
- `linkedin-web`: `articles.draft.save@7` creates or replaces one private
|
|
229
|
+
paragraphs/headings/blockquotes/links Article with one separate new or preserved banner plus
|
|
230
|
+
ordered inline images, required alt text, and optional captions, then
|
|
231
|
+
verifies the exact current-author unpublished result. Styles, lists,
|
|
232
|
+
`articles.read`, and `articles.publish` remain capture-required.
|
|
233
|
+
|
|
234
|
+
Never switch between an official API and a signed-in web adapter because one
|
|
235
|
+
lacks a field or publishing capability.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Scaffold a provider source plugin
|
|
2
|
+
|
|
3
|
+
Use the scaffold after a managed derivation has produced
|
|
4
|
+
`internal-api-evidence.json`. It turns one explicitly selected, sanitized
|
|
5
|
+
candidate into a fail-closed source-plugin unit. It never reads a raw HAR,
|
|
6
|
+
copies an endpoint into executable code, replays a request, or generates a
|
|
7
|
+
browser action.
|
|
8
|
+
|
|
9
|
+
Read [provider-plugins.md](provider-plugins.md) first. Source plugins are trusted
|
|
10
|
+
code in Ghostget's process, not isolated installed extensions.
|
|
11
|
+
|
|
12
|
+
## Contents
|
|
13
|
+
|
|
14
|
+
- [Create the scaffold](#create-the-scaffold)
|
|
15
|
+
- [Implement the direct contract](#implement-the-direct-contract)
|
|
16
|
+
- [Prove promotion](#prove-promotion)
|
|
17
|
+
|
|
18
|
+
## Create the scaffold
|
|
19
|
+
|
|
20
|
+
Keep the derivation output private and select one candidate only after reviewing
|
|
21
|
+
it with `ghostget derive review`:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
ghostget plugin scaffold \
|
|
25
|
+
--site example \
|
|
26
|
+
--display-name Example \
|
|
27
|
+
--origin https://www.example.com \
|
|
28
|
+
--operation feeds.read \
|
|
29
|
+
--risk R1 \
|
|
30
|
+
--evidence /absolute/private/capture/internal-api-evidence.json \
|
|
31
|
+
--candidate 0 \
|
|
32
|
+
--output src/plugins/example-web
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`ghostget adapter scaffold` remains a compatibility alias. New workflows should use
|
|
36
|
+
`ghostget plugin scaffold`.
|
|
37
|
+
|
|
38
|
+
Use the exact `targetOrigin` and zero-based candidate index from the sanitized
|
|
39
|
+
evidence. The script requires a private, regular evidence file, refuses a
|
|
40
|
+
pre-existing non-empty output, rejects transport-shaped operation names, and
|
|
41
|
+
binds only the sanitized evidence file hash and candidate index into its
|
|
42
|
+
checklist. It also enforces the canonical risk for known verbs: reads and lists
|
|
43
|
+
are R1, reversible `set` and `save` operations are R2, and externally visible
|
|
44
|
+
creation, editing, publishing, sharing, and messaging are R3.
|
|
45
|
+
|
|
46
|
+
The generated source unit is self-contained:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
src/plugins/<site>-web/
|
|
50
|
+
├── plugin.ts
|
|
51
|
+
├── runtime.ts
|
|
52
|
+
├── plugin.test.ts
|
|
53
|
+
├── runtime.internal.test.ts
|
|
54
|
+
├── wrench-adapter.json
|
|
55
|
+
└── promotion-checklist.json
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Check the inert unit before registering it:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
ghostget plugin check src/plugins/example-web --json
|
|
62
|
+
bun test src/plugins/example-web
|
|
63
|
+
bun run src/scripts/generate-provider-plugin-catalog.ts
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Every generated operation is `capture-required`. The runtime throws before
|
|
67
|
+
cookie acquisition, account bootstrap, or network I/O. The manifest contains a
|
|
68
|
+
schema-v4 semantic selector, not a request description. Do not install it until
|
|
69
|
+
the plugin is present in the generated static catalog and its exact input schema
|
|
70
|
+
replaces the empty placeholder. `plugin check` reads and syntax-checks the fixed
|
|
71
|
+
file set without importing it; that check is not a sandbox or code review.
|
|
72
|
+
|
|
73
|
+
## Implement the direct contract
|
|
74
|
+
|
|
75
|
+
Replace the fail-closed boundaries one at a time without adding provider
|
|
76
|
+
switches to the kernel:
|
|
77
|
+
|
|
78
|
+
1. Define one `ProviderPluginV1` in `plugin.ts`. Bind the plugin ID, version,
|
|
79
|
+
display name, source kind, transport, site, exact origin, accepted auth
|
|
80
|
+
kinds, subject format and matcher, semantic operation, contract version,
|
|
81
|
+
current-subject probe, executor, and complete implementation-source list.
|
|
82
|
+
2. Implement a typed request authorizer in `runtime.ts` that fixes origin, method, path
|
|
83
|
+
structure, query names, body shape, non-secret headers, redirect behavior,
|
|
84
|
+
timeout, and output bound.
|
|
85
|
+
3. Acquire only the reviewed auth realm. If a dynamic token or registered
|
|
86
|
+
operation revision is unavoidable, use browser bootstrap only to resolve
|
|
87
|
+
that one value and route it only to its named sink.
|
|
88
|
+
4. Implement a reviewed current-account request and compare its stable,
|
|
89
|
+
namespaced provider subject with the bound auth realm before private reads or
|
|
90
|
+
dispatch.
|
|
91
|
+
5. Parse foreign responses from `unknown`, require exact success status and
|
|
92
|
+
content type, project bounded semantic fields, and verify target,
|
|
93
|
+
actor/parent, and desired-state bindings.
|
|
94
|
+
6. Replace the manifest input placeholder with precise IDs, enums, text,
|
|
95
|
+
attachment, pagination, and count bounds. Never accept arbitrary URLs,
|
|
96
|
+
headers, request bodies, GraphQL, Rest.li, JavaScript, selectors, or cookies.
|
|
97
|
+
7. Replace the generated tests with deterministic request, response, identity,
|
|
98
|
+
drift, size, dispatch, and recovery coverage. Keep provider-specific
|
|
99
|
+
behavior inside the plugin unit or its declared implementation sources.
|
|
100
|
+
8. Regenerate the static catalog. Use `ghostget plugin show <plugin-id> --json` to
|
|
101
|
+
verify registry ownership, then validate and install the separate data
|
|
102
|
+
manifest.
|
|
103
|
+
|
|
104
|
+
Use direct first-party HTTP for the semantic operation. Agent-browser may
|
|
105
|
+
navigate and exercise an authorized fixture during capture, or supply narrowly
|
|
106
|
+
reviewed session material at bootstrap. It must not click, type, upload, send,
|
|
107
|
+
publish, react, or read the DOM on behalf of the installed operation.
|
|
108
|
+
|
|
109
|
+
## Prove promotion
|
|
110
|
+
|
|
111
|
+
Treat `promotion-checklist.json` as review state, not proof by itself. The
|
|
112
|
+
scaffold checker requires every proof to remain false because it checks the
|
|
113
|
+
initial network-inert reservation. Set no operation to `observed` until all of
|
|
114
|
+
these are independently true:
|
|
115
|
+
|
|
116
|
+
- exact request shape and credential sinks;
|
|
117
|
+
- exact response variants and bounded projection;
|
|
118
|
+
- current-account, actor, target, and parent bindings;
|
|
119
|
+
- explicit exclusion or modeling of incidental acknowledgements;
|
|
120
|
+
- deterministic request, response, redirect, drift, mismatch, and size tests;
|
|
121
|
+
- durable dispatch and uncertainty behavior for R2/R3;
|
|
122
|
+
- one authorized low-stakes live fixture through the public CLI;
|
|
123
|
+
- duplicate refusal and independent provider-visible readback for mutations;
|
|
124
|
+
- secret scan of plans, receipts, logs, output, and temporary state.
|
|
125
|
+
|
|
126
|
+
For R1, prove that the request does not emit seen, presence, delivery, badge, or
|
|
127
|
+
read acknowledgements. For R2/R3, preview and confirm the exact bounded action
|
|
128
|
+
once. If any fact drifts, restore `capture-required` before another request.
|
|
129
|
+
|
|
130
|
+
After the reviewed source facts have been transferred into
|
|
131
|
+
`src/plugins/<plugin-id>`, delete the sanitized derivation output, managed
|
|
132
|
+
browser profile, any abandoned derivation, and any duplicate private scaffold.
|
|
133
|
+
Never commit raw HARs, profile state, tokens, cookies, captured payloads, or
|
|
134
|
+
authenticated DOM.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Cross-post video
|
|
2
|
+
|
|
3
|
+
Use the installed `ghostget` CLI as the only posting transport. Orchestrate
|
|
4
|
+
provider operations; do not implement a second HTTP client, click a composer
|
|
5
|
+
at runtime, or treat a browser login as proof that video publishing is
|
|
6
|
+
supported.
|
|
7
|
+
|
|
8
|
+
Reuse the preview, confirm, settlement, and ledger rules in
|
|
9
|
+
[cross-post text and images](cross-posting.md). Do not invent a second
|
|
10
|
+
confirmation model.
|
|
11
|
+
|
|
12
|
+
## Build one exact video package
|
|
13
|
+
|
|
14
|
+
Record these values before planning:
|
|
15
|
+
|
|
16
|
+
- one absolute path to the exact video file that will be posted;
|
|
17
|
+
- exact caption text, preserving whitespace and punctuation;
|
|
18
|
+
- selected platforms;
|
|
19
|
+
- explicit provider choices such as audience, visibility, or a YouTube title.
|
|
20
|
+
|
|
21
|
+
Do not silently recut, restyle, watermark, or replace the video after the
|
|
22
|
+
user has approved the package. Encoding happens before planning.
|
|
23
|
+
|
|
24
|
+
### Social encode
|
|
25
|
+
|
|
26
|
+
Prepare one social-friendly cut before any preview:
|
|
27
|
+
|
|
28
|
+
- 9:16, 1080x1920, H.264 Main, yuv420p, `+faststart`, AAC;
|
|
29
|
+
- if the source is landscape, letterbox or blur-pad into 9:16;
|
|
30
|
+
- do not crop away a required subject unless the user asked for a crop;
|
|
31
|
+
- if replacement background audio is supplied, replace the soundtrack and
|
|
32
|
+
trim or fade it to the video duration. Do not leave the original audio
|
|
33
|
+
mixed under it unless asked.
|
|
34
|
+
|
|
35
|
+
Encoding may use a local encoder such as ffmpeg. Posting may not.
|
|
36
|
+
|
|
37
|
+
### Caption and tags
|
|
38
|
+
|
|
39
|
+
- If the user provided a caption, use it exactly. Do not rewrite it to pass
|
|
40
|
+
a provider limit; ask for a shorter shared caption or an explicit
|
|
41
|
+
platform-specific variant. Never mark that user-supplied caption as
|
|
42
|
+
AI-generated; follow [X AI disclosure](x-ai-disclosure.md).
|
|
43
|
+
- If no caption was provided, write one short caption from the video's
|
|
44
|
+
actual subject: about one sentence, under 120 characters. Do not invent a
|
|
45
|
+
long marketing paragraph.
|
|
46
|
+
- Add hashtags only on TikTok, Instagram, and YouTube Shorts. Put a few
|
|
47
|
+
relevant tags after the caption on those platforms only.
|
|
48
|
+
- Do not add hashtags on X, LinkedIn, Substack, Bluesky, Threads, or Reddit.
|
|
49
|
+
|
|
50
|
+
That tag split is an explicit allowed platform-specific variant. It is not
|
|
51
|
+
a license to rewrite the caption.
|
|
52
|
+
|
|
53
|
+
Give the package a task-local identity. Preserve the same video bytes
|
|
54
|
+
through planning, settlement, duplicate accounting, and any cleanup
|
|
55
|
+
assessment.
|
|
56
|
+
|
|
57
|
+
## Preflight every target
|
|
58
|
+
|
|
59
|
+
1. Run `ghostget --help`; if it is unavailable, follow
|
|
60
|
+
[installation and diagnostics](install.md).
|
|
61
|
+
2. Read [video platform routing](social-video-platform-routing.md).
|
|
62
|
+
3. Run `ghostget capabilities <adapter> --json` for every candidate adapter.
|
|
63
|
+
Treat its current operation state and input schema as authoritative over
|
|
64
|
+
the reference and over remembered platform behavior.
|
|
65
|
+
4. Select one exact transport and auth realm per platform. Never switch
|
|
66
|
+
between a browser-session and official OAuth adapter after planning.
|
|
67
|
+
5. Choose the operation that actually accepts `video/mp4` on that adapter,
|
|
68
|
+
usually `media.publish`. A text or image `posts.publish` is not a video
|
|
69
|
+
operation, even when it is observed.
|
|
70
|
+
6. Require that video operation to be `observed`, the adapter to be valid,
|
|
71
|
+
and the auth realm to be bound to its current provider subject.
|
|
72
|
+
`capture-required` is unavailable, not degraded support.
|
|
73
|
+
7. Validate the exact file path, bytes, detected media type, caption, and
|
|
74
|
+
required scalars against each installed input schema before creating any
|
|
75
|
+
plan.
|
|
76
|
+
|
|
77
|
+
If a platform cannot accept this video under an observed contract, exclude
|
|
78
|
+
it from the batch and keep it on the ledger as unavailable. Never silently
|
|
79
|
+
drop it. Never post through the capture browser as the installed fallback.
|
|
80
|
+
|
|
81
|
+
Prefer a target-filtered cookie locator for a signed-in web adapter. Use a
|
|
82
|
+
profile-backed realm only when the provider contract requires browser
|
|
83
|
+
storage and the user has accepted that exact broader egress boundary. Bind
|
|
84
|
+
a new realm with `ghostget auth bind <id> --site <surface> --json` before any
|
|
85
|
+
preview.
|
|
86
|
+
|
|
87
|
+
If support is missing and the user asked to develop it, use the packaged
|
|
88
|
+
Ghostget derivation workflow with one expressly authorized low-stakes
|
|
89
|
+
fixture. Keep the operation `capture-required` until its contracts pass.
|
|
90
|
+
|
|
91
|
+
## Preview the complete batch
|
|
92
|
+
|
|
93
|
+
Construct each input only from its current installed schema. In CLI input
|
|
94
|
+
JSON, represent a scalar file field as one absolute path string.
|
|
95
|
+
|
|
96
|
+
Run every target with `--preview --json` before confirming any target.
|
|
97
|
+
Review and summarize adapter, transport, operation, risk, bound account,
|
|
98
|
+
exact scalar input, attachment hash, side effect, contract hash, and
|
|
99
|
+
five-minute expiry.
|
|
100
|
+
|
|
101
|
+
Cancel superseded or unused plans. If one target cannot be planned, report
|
|
102
|
+
that target separately; do not weaken the other inputs to manufacture
|
|
103
|
+
parity.
|
|
104
|
+
|
|
105
|
+
## Confirm once per platform
|
|
106
|
+
|
|
107
|
+
Cross-posting is not atomic. Confirm each reviewed digest once with
|
|
108
|
+
`ghostget confirm <digest> --json`. Do not recreate an expired plan without
|
|
109
|
+
rechecking the video package and authorization.
|
|
110
|
+
|
|
111
|
+
Classify each result independently:
|
|
112
|
+
|
|
113
|
+
- `submitted`: record the run and provider-created object evidence, then
|
|
114
|
+
settle availability through exact readback;
|
|
115
|
+
- pre-dispatch `failed`: diagnose safely and create a fresh preview only if
|
|
116
|
+
the original action remains authorized;
|
|
117
|
+
- `pending`, `partial`, or `indeterminate`: preserve the run and use only
|
|
118
|
+
an advertised, separately reviewed exact readback through
|
|
119
|
+
`ghostget runs reconcile`.
|
|
120
|
+
|
|
121
|
+
Never retry pending, partial, or indeterminate work. An unsettled target
|
|
122
|
+
does not create authority to delete or repost on other platforms.
|
|
123
|
+
|
|
124
|
+
## Settle and account for every attempt
|
|
125
|
+
|
|
126
|
+
Read [settlement and duplicate cleanup](settlement-and-duplicate-cleanup.md)
|
|
127
|
+
after confirmation. Give every attempt its own immutable ledger entry. Use
|
|
128
|
+
exact returned locators and exact provider readback; never infer delivery
|
|
129
|
+
from a cleared composer, a profile search, or matching text.
|
|
130
|
+
|
|
131
|
+
## Finish with a platform ledger
|
|
132
|
+
|
|
133
|
+
Return one row per requested platform and attempt with adapter, auth realm
|
|
134
|
+
label, plan or run ID, attachment hash summary, terminal state, exact
|
|
135
|
+
provider locator or public URL when exposed, readback state, and
|
|
136
|
+
availability timing.
|
|
137
|
+
|
|
138
|
+
Keep caption text, credentials, cookies, private response bodies, and
|
|
139
|
+
original local paths out of receipts and diagnostics.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Cross-post text and images
|
|
2
|
+
|
|
3
|
+
Use the installed `ghostget` CLI as the only posting transport. Orchestrate provider operations; do not implement a second HTTP client, click a composer at runtime, or treat a browser login as proof that publishing is supported.
|
|
4
|
+
|
|
5
|
+
## Build one exact post package
|
|
6
|
+
|
|
7
|
+
Record these values before planning:
|
|
8
|
+
|
|
9
|
+
- exact text, preserving whitespace and punctuation;
|
|
10
|
+
- an ordered optional image package, with one absolute path and optional alt description per image;
|
|
11
|
+
- selected platforms;
|
|
12
|
+
- explicit provider choices such as LinkedIn visibility or a platform-specific text variant.
|
|
13
|
+
|
|
14
|
+
Do not truncate text, omit or reorder images, make a collage, split a thread, or rewrite copy to pass a provider limit. Ask for a material content choice when exact parity is impossible. A social Substack target means a public Note; an article or newsletter is a different operation.
|
|
15
|
+
|
|
16
|
+
If alt text is absent, draft a short factual description from visible image content and include it in the preview summary. Never infer identity, health, ethnicity, relationships, or other sensitive traits from an image.
|
|
17
|
+
|
|
18
|
+
Give the package a task-local identity. Preserve image order through planning, settlement, duplicate accounting, and any cleanup assessment.
|
|
19
|
+
|
|
20
|
+
## Keep user-supplied copy unlabeled
|
|
21
|
+
|
|
22
|
+
When the user supplied the cross-post copy, never mark that package as AI-generated. This rule applies to X and every other platform in this workflow. On X, follow [X AI disclosure](x-ai-disclosure.md).
|
|
23
|
+
|
|
24
|
+
- Do not add "Made with AI", "Made with Grok", or similar disclosure text to the body.
|
|
25
|
+
- Do not set a provider metadata flag that labels the post or its media as AI-generated. Official `x` `posts.publish` exposes `made_with_ai`; leave it unset or `false` for this workflow. `x-web` `posts.publish` has no such input field; do not invent one. Inspect each installed schema for a comparable field and leave it unset or `false`.
|
|
26
|
+
- Prefer the installed Ghostget transport. Do not click the X composer because a contract is missing or `capture-required`.
|
|
27
|
+
- If the user explicitly asked for a composer fallback, open Content disclosure and require Made with AI OFF before Post. A locked or greyed toggle is an auto-label; stop. After publishing, open the live permalink. A sparkle Made with AI or Made with Grok label means the publish failed; do not report success, and do not delete or repost unless the user asks.
|
|
28
|
+
|
|
29
|
+
## Preflight every target
|
|
30
|
+
|
|
31
|
+
1. Run `ghostget --help`; if it is unavailable, follow [installation and diagnostics](install.md).
|
|
32
|
+
2. Read [social platform routing](social-platform-routing.md).
|
|
33
|
+
3. Run `ghostget capabilities <adapter> --json` for every candidate adapter. Treat its current operation state and input schema as authoritative over the reference and over remembered platform behavior.
|
|
34
|
+
4. Select one exact transport and auth realm per platform. Never switch between a browser-session and official OAuth adapter after planning.
|
|
35
|
+
5. Require `posts.publish` to be `observed`, the adapter to be valid, and the auth realm to be bound to its current provider subject. `capture-required` is unavailable, not degraded support.
|
|
36
|
+
6. Validate the exact text, ordered image count, bytes, detected media types, alt-field shape, and required scalar fields against each installed input schema before creating any plan.
|
|
37
|
+
|
|
38
|
+
Map the package only as the installed schema permits: a scalar file gets one path, a file array gets an ordered path array, and aligned accessibility fields retain the same image order. If a provider accepts fewer images, requires an image, or lacks an alt field, report that exact constraint. Obtain an explicit per-provider package choice when parity is impossible; never silently drop, duplicate, merge, convert, or reorder images.
|
|
39
|
+
|
|
40
|
+
Prefer a target-filtered cookie locator for a signed-in web adapter. Use a profile-backed realm only when the provider contract requires browser storage and the user has accepted that exact broader egress boundary. Bind a new realm with `ghostget auth bind <id> --site <surface> --json` before any preview.
|
|
41
|
+
|
|
42
|
+
If support is missing and the user asked to develop it, use the packaged Ghostget derivation workflow with one expressly authorized low-stakes fixture. Bind authorized capture images or MP4 video at derivation start with repeated `--fixture` options and upload only their returned `fixture:<n>` references. Keep the operation `capture-required` until its code-owned request, response, current-account, actor, attachment, returned-object, independent-readback, duplicate, and uncertainty contracts pass. Never post through the capture browser as the installed fallback.
|
|
43
|
+
|
|
44
|
+
## Preview the complete batch
|
|
45
|
+
|
|
46
|
+
Construct each input only from its current installed schema. In CLI input JSON, represent a scalar file field as one absolute path string and a file-array field as an ordered array of absolute path strings. Ghostget replaces those paths with plan-bound opaque file references and binds immutable attachment bytes, sizes, media types, and hashes into the plan.
|
|
47
|
+
|
|
48
|
+
Run every target with `--preview --json` before confirming any target. Capability availability is evaluated at preview time and the resulting contract identity is bound into the digest; a later adapter change must not be used to reinterpret that plan or an existing run. Review and summarize:
|
|
49
|
+
|
|
50
|
+
- adapter, transport, operation, and risk;
|
|
51
|
+
- bound account realm and provider subject;
|
|
52
|
+
- exact scalar input, without hiding platform-specific variants;
|
|
53
|
+
- attachment order, sizes, detected types, and SHA-256 hashes;
|
|
54
|
+
- side effect, contract hash, dispatch count, and five-minute expiry.
|
|
55
|
+
|
|
56
|
+
Cancel superseded or unused plans. If one target cannot be planned, report that target separately; do not weaken the other inputs to manufacture parity.
|
|
57
|
+
|
|
58
|
+
## Confirm once per platform
|
|
59
|
+
|
|
60
|
+
Cross-posting is not atomic. Confirm each reviewed digest once with `ghostget confirm <digest> --json`. Do not recreate an expired plan without rechecking the post package and authorization.
|
|
61
|
+
|
|
62
|
+
Classify each result independently:
|
|
63
|
+
|
|
64
|
+
- `submitted`: record the run and provider-created object evidence, then settle availability through exact readback;
|
|
65
|
+
- pre-dispatch `failed`: diagnose safely and create a fresh preview only if the original action remains authorized;
|
|
66
|
+
- `pending`, `partial`, or `indeterminate`: preserve the run and use only an advertised, separately reviewed exact readback through `ghostget runs reconcile`.
|
|
67
|
+
|
|
68
|
+
An unsettled target does not create authority to delete or repost on other platforms. Continue with another already-reviewed platform only when its dispatch is independent and still matches the user's requested batch.
|
|
69
|
+
|
|
70
|
+
## Settle and account for every attempt
|
|
71
|
+
|
|
72
|
+
Read [settlement and duplicate cleanup](settlement-and-duplicate-cleanup.md) after confirmation. Give every attempt its own immutable ledger entry. Use exact returned locators and exact provider readback; never infer delivery from a cleared composer, a profile search, or matching text.
|
|
73
|
+
|
|
74
|
+
A duplicate-tolerant action is a materially new intent, not a retry. Permit it only after explicit fresh authorization of the exact platform/package and duplicate risk. In the current v1 workflow, create the new preview with one exact eligible source run via `--duplicate-risk-of <run-id>`; Ghostget binds that run to one deterministic successor intent. Keep every other prior uncertain attempt linked separately in the task ledger. Never clear, overwrite, or weaken an old Ghostget ledger, receipt, recovery capsule, or attachment bundle.
|
|
75
|
+
|
|
76
|
+
Assess cleanup only through the installed canonical `content.delete` capability. If it is absent, `capture-required`, or blocked as R4, report cleanup as unavailable. Never use a semantic alias, raw HTTP, composer automation, or a capture session to perform deletion.
|
|
77
|
+
|
|
78
|
+
## Finish with a platform ledger
|
|
79
|
+
|
|
80
|
+
Return one row per requested platform and attempt with adapter, auth realm label, plan or run ID, attachment hash summary, terminal state, exact provider locator or public URL when exposed, readback state, and availability timing. Label provider creation time and first independent observation time separately; observation means the post was available no later than that check, not that it became available at that instant. If exact readback never observes it, report availability as unverified even when the provider accepted the mutation.
|
|
81
|
+
|
|
82
|
+
Keep post text, credentials, cookies, private response bodies, and original local paths out of receipts and diagnostics. Remove task-owned derivations and temporary profile snapshots after verified cleanup; retain evidence needed for unsettled runs.
|