Parent
Part of #478 — PWA first-class excellence/hardening.
Product opportunity
WorldScript's manifest already declares a Web Share Target, but a manifest declaration alone is not a polished writing workflow. A PWA can become a lightweight system-level capture destination on supported mobile/desktop environments: share a URL, selected text, research snippet or compatible file into WorldScript and continue writing later — including offline.
For a writing application this can be a meaningful PWA differentiator because the browser/OS share sheet is available across many other apps without requiring a native WorldScript integration for each source.
Core concept: Capture Inbox
Incoming shares should never be injected directly into the current manuscript. Route them into an explicit local inbox:
OS/browser share sheet
↓
Web Share Target
↓
strict parse + normalize
↓
local Capture Inbox
↓
user chooses destination
note / research / character / scene / codex / discard
This separates capture from commit to project authority.
Input classes
Start with the manifest's current GET parameters:
Evaluate POST/multipart file sharing only after threat/size handling is designed. Candidate later types:
- plain text/Markdown;
- images;
- PDFs or documents as untrusted attachments for later import/extraction;
- WorldScript project/export packages.
Do not broaden accepted MIME types without a real workflow and parser.
Offline-first behavior
A key differentiator is capture when the user has no network.
If the installed PWA/app shell and local storage are available:
- accept and persist the share locally;
- show “Captured — organize later”;
- no cloud AI call is required;
- optional enrichment/summarization waits until a selected local/cloud backend is available and user requests it.
Never lose an accepted share merely because navigation or network fails immediately afterward.
Capture record
Persist a bounded, versioned record containing only what the user shared plus necessary metadata:
id
createdAt
sourceKind
sharedTitle?
sharedText?
sharedUrl?
attachmentRefs?
status = inbox / assigned / discarded
assignedProjectId?
Do not automatically fetch the shared URL in the background. That leaks browsing intent and introduces security/privacy complexity.
Organize workflow
From the inbox allow:
- append as research note;
- create project note;
- attach to scene/character/location/world entry;
- create a new idea/project seed;
- copy selected content to manuscript at user-chosen location;
- optionally run local AI classification/summarization;
- discard.
All destructive/transformative actions should be explicit and undoable where practical.
Outbound Web Share
Complement inbound capture with navigator.share() where supported:
- share a selected synopsis/logline/excerpt;
- share an export link/file only after explicit user action;
- never share manuscript content by default;
- fall back to copy/download when unsupported.
Protocol/deep-link relationship
The manifest also declares web+worldscript. Unify external entry points under one validated routing layer:
share target
protocol handler
shortcuts
launch handler
file handler (#481)
Every external payload is untrusted. Parse into a typed ExternalLaunchIntent before any navigation/state mutation.
Security / abuse resistance
- bound query/body lengths;
- reject malformed/oversized payloads;
- sanitize display text but preserve user data safely;
- do not execute shared HTML/scripts;
- do not auto-fetch URLs;
- prevent javascript/data/file scheme abuse;
- validate protocol-handler routes against an allowlist;
- never allow external launch payloads to trigger AI provider calls, file writes, plugin installs, destructive actions or project replacement without user confirmation;
- no sensitive payload telemetry.
Privacy
Capture stays local unless the user explicitly chooses a cloud-dependent action. UI must make this clear.
If local AI is used for classification, identify the local backend. If cloud AI is selected, request/reflect normal provider consent/routing semantics rather than treating capture as exempt.
Mobile UX
Optimize for a 5-second capture flow:
- app launches quickly;
- large editor need not fully initialize before durable capture if architecture permits;
- immediate acknowledgement;
- optional destination quick-pick;
- defer expensive indexing/AI.
This is a place where PWA startup/code-splitting can materially exceed a heavyweight desktop workflow.
Tests
- share title/text/url individually and combined;
- cold installed-PWA launch from share;
- warm existing-window share;
- offline share;
- malformed/oversized share;
- dangerous URL schemes;
- multiple rapid shares;
- app update/version skew with pending inbox;
- inbox survives relaunch;
- assignment to project is transactional;
- unsupported share-target browser fallback;
- outbound share fallback.
Acceptance criteria
Non-goals
- web scraping shared URLs by default;
- silently feeding captured content to AI;
- replacing project import validation;
- accepting every possible MIME type;
- turning the share target into an unauthenticated command interface.
Parent
Part of #478 — PWA first-class excellence/hardening.
Product opportunity
WorldScript's manifest already declares a Web Share Target, but a manifest declaration alone is not a polished writing workflow. A PWA can become a lightweight system-level capture destination on supported mobile/desktop environments: share a URL, selected text, research snippet or compatible file into WorldScript and continue writing later — including offline.
For a writing application this can be a meaningful PWA differentiator because the browser/OS share sheet is available across many other apps without requiring a native WorldScript integration for each source.
Core concept: Capture Inbox
Incoming shares should never be injected directly into the current manuscript. Route them into an explicit local inbox:
This separates capture from commit to project authority.
Input classes
Start with the manifest's current GET parameters:
Evaluate POST/multipart file sharing only after threat/size handling is designed. Candidate later types:
Do not broaden accepted MIME types without a real workflow and parser.
Offline-first behavior
A key differentiator is capture when the user has no network.
If the installed PWA/app shell and local storage are available:
Never lose an accepted share merely because navigation or network fails immediately afterward.
Capture record
Persist a bounded, versioned record containing only what the user shared plus necessary metadata:
Do not automatically fetch the shared URL in the background. That leaks browsing intent and introduces security/privacy complexity.
Organize workflow
From the inbox allow:
All destructive/transformative actions should be explicit and undoable where practical.
Outbound Web Share
Complement inbound capture with
navigator.share()where supported:Protocol/deep-link relationship
The manifest also declares
web+worldscript. Unify external entry points under one validated routing layer:Every external payload is untrusted. Parse into a typed
ExternalLaunchIntentbefore any navigation/state mutation.Security / abuse resistance
Privacy
Capture stays local unless the user explicitly chooses a cloud-dependent action. UI must make this clear.
If local AI is used for classification, identify the local backend. If cloud AI is selected, request/reflect normal provider consent/routing semantics rather than treating capture as exempt.
Mobile UX
Optimize for a 5-second capture flow:
This is a place where PWA startup/code-splitting can materially exceed a heavyweight desktop workflow.
Tests
Acceptance criteria
Non-goals