feat(ui): auto-tab fallback — embed-refusing apps become tab apps
Demo images / Build & push demo images (push) Successful in 3m49s

An app whose frame never loads while its backend reports Running (the
embed-refusal signature: frame-busting JS, top-level-origin apps,
SameSite=Strict logins — everything the gate's header stripping cannot
fix) is remembered in localStorage; every later launch opens a tab
straight from the click (user gesture, so no popup blocker), and
opensInTab() gives it the tab-launch icon. A successful iframe load
clears the memory and entries expire after 7 days, so nodes that gain
embedding (gate improvements) get re-probed instead of being remembered
broken forever. Dev guide updated; v1.8.2 changelog + What's New curated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-08-13 20:23:04 -04:00
co-authored by Claude Fable 5
parent 63cb9dd22c
commit 2399eeac66
6 changed files with 103 additions and 1 deletions
+5 -1
View File
@@ -4,6 +4,7 @@ import type { Ref } from 'vue'
import { computed } from 'vue'
import { PackageState, type PackageDataEntry } from '@/types/api'
import { resolveAppUrl } from '../appSession/appSessionConfig'
import { isAutoTabApp } from '@/utils/autoTabApps'
export type AppsTab = 'apps' | 'websites' | 'services'
@@ -173,7 +174,10 @@ export const TAB_LAUNCH_APPS = new Set([
])
export function opensInTab(id: string): boolean {
return TAB_LAUNCH_APPS.has(id)
// The launch icon and launch behavior follow the dynamic verdict too:
// apps observed refusing the iframe (remembered by the app session) show
// the same tab-launch affordance as the statically-known tab apps.
return TAB_LAUNCH_APPS.has(id) || isAutoTabApp(id)
}
// Backend services that ship no icon of their own reuse their PARENT app's icon