Skip to content

[feat] share into the app + open files from the OS (60 Q4) - #431

Merged
AlexZ005 merged 3 commits into
feat/60from
feat/60-reach
Oct 23, 2026
Merged

AlexZ005 merged 3 commits into
feat/60from
feat/60-reach

Conversation

@AlexZ005

Copy link
Copy Markdown
Collaborator

Roadmap 60 Q4: share into the app and open files from the OS. (Q3 oEmbed is cloud PR theprototype-app/cloud#111.)

What

  • Manifest: share_target (POST multipart to /share-target: images, .glb/.gltf, .tpscene), file_handlers (.tpscene/.glb/.gltf), launch_handler focus-existing.
  • static/sw.js: the share POST is parked in the tp-share-inbox cache and answered with a 303 to /?shared=<n>. Every other request still goes straight to the network (no shell cache).
  • src/lib/launchInbox.js: one router for both entry points (share inbox + window.launchQueue):
    • a .tpscene opens (the Sidebar Load path)
    • models are imported into the current scene (with an .obj's .mtl/textures)
    • a lone image goes to the Library, with a "Show in Library" toast
    • anything else is skipped with a toast
    • Launches are serialised, and they wait for the boot and for the restore question (autosave.restoreSettled()), so a Restore cannot wipe a shared model.
  • Chromium ignores launch_handler for share launches, so a share is always a fresh navigation that the worker sees.

Tests

  • unit tests/unit/launchInbox.test.js (14): the manifest keys, the real sw.js in a fake worker scope, the inbox round trip, the classifier. Full unit suite 2504/2504; check-ratchet 299/39 = baseline.
  • e2e tests/e2e/launch-inbox.test.cjs: ALL PASS on the dev server (pc slot) and on a built app (serve-build, the app's own SW). It covers:
    • CDP manifest/installability
    • a real multipart share of a PNG (→ Library) and a .glb (→ scene)
    • the restore rule (nothing imported while the question is open, both doors after Restore)
    • launchQueue: .tpscene opens, then a .glb lands in the same scene, then a .txt changes nothing
    • CDP PWA.install is not available headless, so the native install + OS double-click are owner rows.

Owner rows (60-int)

  • Share → theprototype on the phone: an image AND a .glb.
  • Double-click a .tpscene with the installed desktop app; a second file goes to the same window.

Forks (with recommendations, proceeded on) are in the lane's QUESTIONS file: image → Library (Q5 underlay may take it later in route()), launches wait for the restore answer.

🤖 Generated with Claude Code

AlexZ005 and others added 3 commits October 23, 2026 15:40
- manifest: share_target (POST multipart `files`: images, glb/gltf, tpscene), file_handlers
  (.tpscene, .glb, .gltf → /), launch_handler focus-existing
- static/sw.js: receives the share POST (a static site has no server), parks the files in
  the `tp-share-inbox` cache and 303s to /?shared=<n>; everything else is still a no-cache
  passthrough
- src/lib/launchInbox.js: reads the inbox ONCE (cache deleted, ?shared= stripped) and takes
  launchQueue file launches; routes .tpscene → open (Sidebar Load path), models → import
  into the current scene (companions ride along), lone images → Explorer Library + "Show in
  Library"; waits for the scene group AND the restore-session answer first
- autosave: restoreSettled() — resolves once the boot's restore question is answered
  (no snapshot / non-empty / auto-restored / Restore finished / Dismiss)
- tests/unit/launchInbox.test.js (14): manifest keys, the real sw.js in a fake worker scope
  (park + 303, text-only, replace, passthrough), the worker → app round trip, classifier

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Share POST through the real service worker (image -> Library, .glb -> scene),
the restore rule, CDP manifest/installability, launchQueue file launches.
Not yet run green: the first run timed out waiting for a slot.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- a lone shared image no longer pulls in fileHandler (a cold dev-server compile stalled it)
- loadExplorer() before importFiles, so the index write cannot replace an unloaded library
- a failed route records the error and toasts it; lastLaunch.stage for diagnosis
- suite: --ignore-certificate-errors (SW script fetch on the self-signed dev cert),
  poll with until() instead of an async waitForFunction predicate, wait for the level name

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@AlexZ005
AlexZ005 merged commit d2e7516 into feat/60 Oct 23, 2026
9 checks passed
@AlexZ005
AlexZ005 deleted the feat/60-reach branch October 23, 2026 23:08
@AlexZ005

Copy link
Copy Markdown
Collaborator Author

In main via 60-int: released in v1.44.0 (#476).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant