mirror of
https://github.com/different-ai/openwork
synced 2026-05-13 18:46:25 +02:00
The share app was missing a favicon (browser tabs showed default icon) and had no fallback OpenGraph/Twitter metadata in the root layout. This meant any route without explicit OG tags had no social card when shared on X, Slack, or messaging apps. - Add favicon using existing openwork-mark.svg (matches landing/den-web) - Add fallback OpenGraph metadata (type, siteName) to root layout - Add Twitter card defaults with @getopenwork site attribution Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
OpenWork Share Service (Publisher)
This is a Next.js publisher app for OpenWork "share link" bundles.
It keeps the existing bundle APIs, but the public share surface now runs as a simple Next.js site backed by Vercel Blob.
Endpoints
-
GET /- Human-friendly packaging page for OpenWork worker files.
- Supports drag/drop of skills, agents, commands,
opencode.json[c], andopenwork.json. - Previews the inferred bundle and publishes a share link.
-
POST /v1/bundles- Accepts JSON bundle payloads.
- Stores bytes in Vercel Blob.
- Returns
{ "url": "https://share.openwork.software/b/<id>" }.
-
POST /v1/package- Accepts
{ files: [{ path, name?, content }], preview?: boolean }. - Parses supported OpenWork files into the smallest useful bundle shape.
- Returns preview metadata when
previewistrue. - Publishes the generated bundle and returns the share URL otherwise.
- Accepts
-
GET /b/:id- Returns an HTML share page by default for browser requests.
- Includes an Open in app action that opens
openwork://import-bundlewith:ow_bundle=<share-url>ow_intent=new_worker(desktop OpenWork converts single-skill bundles into a destination picker before import)ow_source=share_service
- Also includes a web fallback action that opens
PUBLIC_OPENWORK_APP_URLwith the same query params. - Returns raw JSON for API/programmatic requests:
- send
Accept: application/json, or - append
?format=json.
- send
- The canonical raw endpoint is
/b/:id/data. - Supports
/b/:id/data?download=1and the legacy?format=json&download=1compatibility path.
Bundle Types
skill- A single skill install payload.
skills-set- A full skills pack (multiple skills) exported from a worker.
workspace-profile- Full workspace profile payload (config, MCP/OpenCode settings, commands, skills, and agent config).
Packager input support
- Skill markdown from
.opencode/skills/<name>/SKILL.md - Agent markdown from
.opencode/agents/*.md - Command markdown from
.opencode/commands/*.md opencode.json/opencode.jsonc(onlymcpandagentsections are exported)openwork.json
The packager rejects files that appear to contain secrets in shareable config.
Required Environment Variables
BLOB_READ_WRITE_TOKEN- Vercel Blob token with read/write permissions.
Optional Environment Variables
-
PUBLIC_BASE_URL- Default:
https://share.openwork.software - Used to construct the returned share URL.
- Default:
-
MAX_BYTES- Default:
5242880(5MB) - Hard upload limit.
- Default:
-
PUBLIC_OPENWORK_APP_URL- Default:
https://app.openwork.software - Target app URL for the Open in app action on bundle pages.
- Default:
-
LOCAL_BLOB_DIR- Optional local filesystem storage root for bundle JSON.
- When
BLOB_READ_WRITE_TOKENis unset in local/dev mode, the service falls back to local file storage automatically.
Local development
For local testing you can use:
pnpm install
pnpm --dir apps/share dev
Open http://localhost:3000.
Without a BLOB_READ_WRITE_TOKEN, local development now stores bundles on disk in a local dev blob directory so publishing works out of the box.
Deploy
Recommended project settings:
- Root directory:
apps/share - Framework preset: Next.js
- Build command:
next build - Output directory:
.next - Install command:
pnpm install --frozen-lockfile
Tests
pnpm --dir apps/share test
Quick checks
# Human-friendly page
curl -i "http://localhost:3000/b/<id>" -H "Accept: text/html"
# Machine-readable payload (OpenWork parser path)
curl -i "http://localhost:3000/b/<id>/data"
# Legacy compatibility path
curl -i "http://localhost:3000/b/<id>?format=json"
Notes
- Links are public and unguessable (no auth, no encryption).
- Do not publish secrets in bundles.