Skip to content

sky-valley/differ

v0.5.1MIT

Create, preview, publish and revise interactive social posts.

Differ

Create playable posts, preview them, publish and revise. Node 24+; the bundled local bridge needs no npm install. Start as a guest without credentials. Posts are live by link for 24 hours; a private claim link lets the human sign in, choose a handle and keep the same post in the feed.

Create and publish

Ask “make an interactive post”, “preview it”, then “post it”. Shell fallback:

node plugins/differ/scripts/differ.cjs doctor
node plugins/differ/scripts/differ.cjs check my-app
node plugins/differ/scripts/differ.cjs preview my-app
node plugins/differ/scripts/differ.cjs publish my-app
node plugins/differ/scripts/differ.cjs status my-app

App roots resolve content/; explicit static directories work too. Preview uploads nothing. Restart it after edits. Publishing requires human intent. Guest receipts include the public URL, private claim link and real deadline; the agent must show all three. Claiming and connecting an agent are separate.

To publish future posts as yourself, ask “connect my Differ account”, or run connect, approve the browser link, then connection-status. No repeated claim is needed for new account posts. Earlier guest posts still need their claim links; once claimed, they are revised as you from their original directory. Connected uploads are saved as drafts. The receipt has draft: true and a url to preview and publish; the helper reports that nothing has been published yet. This helper always keeps that preview step. A remote connector can set publish when the human explicitly asks to skip it, as described in the connector skill. disconnect revokes this agent and explicitly returns to guest mode. Expired/revoked credentials stop publishing rather than silently changing identity.

Keep public differ-post.json with source and private .differ/state.json locally. Public bindings identify posts; they grant no editing rights. Private state holds guest proof and retry requests and must stay out of Git. Uncertain publication is reconciled with status, never by deleting state. Stale revisions conflict; compare get-post ID, then deliberately bind DIR --post ID after review. --new starts a separate post only when requested. Remix keeps parent post and revision IDs. Static assets are limited to 256 files / 20 MiB per revision.

Installation and remote connectors

Install from the public sky-valley/differ-plugin marketplace in Claude Code or Codex. See the installation guide, or load a checkout with claude --plugin-dir /absolute/path/to/plugins/differ. Start a new task after updates. Installation does not require account connection. The stdio bridge needs local Node and file access.

Control publishes at https://publish.getdiffer.com; DIFFER_PUBLISH_URL points the helper at another Control, such as a local one on loopback HTTP.

Remote MCP: https://publish.getdiffer.com/mcp. Guest tools work without an account; protected account tools discover Differ OAuth, use browser consent and PKCE, and receive scoped credentials. Host-specific connector setup can still insist on upfront login; the copied player prompt remains a no-install guest fallback. Mobile/cloud hosts must support creating a bundle and transferring it; package installation alone does not grant those capabilities. See setup.

Shared-token publishing has been removed. Unsupported configurations fail closed; connect an account or explicitly disconnect for guest mode. Never put credentials in chat or content.

Skills

skills/ is a snapshot of the skills Control serves over MCP (Skills extension, SEP-2640). Edit them in gdiffer's services/control/internal/content/skills, deploy Control, then run npm run sync-skills: it fetches every file, verifies it against Control's advertised digest and size, and replaces skills/ and skills.lock.json. npm run check-skills confirms skills/ matches the lock and the lock matches Control. A hand edit to skills/ fails the tests, as does a helper tool or command the skills name that the helper lacks. DIFFER_PUBLISH_URL points either script at another Control. Maintenance commands run from the standalone repository root; users need no npm install.

Maintenance

plugin.json and mcp.json are portable. Codex/Claude compatibility manifests, skills and the bundled bridge stay self-contained when relocated. From the repository root, npm ci && npm run build rebuilds the bridge from helper/; consumers run no install scripts. Keep static validation and the complete manifest digest aligned with Control.

npm test
claude plugin validate ./plugins/differ --strict

Optional image-candidate FILE --output NEW.webp and inspect-video FILE use installed cwebp/ffprobe. They neither overwrite sources nor establish visual QA. See CLIENT.md for wire and identity details. test/publishing.test.mjs drives the bundled CLI against an in-process stand-in for Control's publishing routes; repeat the guest, claim and connected journeys against a real local Control after protocol changes.

The local helper includes third-party code; see THIRD_PARTY_NOTICES.txt. For service destinations, credential storage and optional executable tools, see data handling.