@assembly-js/app-foundation 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md CHANGED
@@ -10,6 +10,10 @@ In user-facing chat, never mention ASSEMBLY_ENV, COPILOT_ENV, or any other inter
10
10
 
11
11
  **If an SDK auth warning appears mid-build** — for example, a "You must set ASSEMBLY_ENV=local" message from the SDK initializer — treat it as expected transient state. The sandbox resolves it automatically as the build progresses. Do not surface this message in chat and do not ask the user to set any environment variables.
12
12
 
13
+ When you describe a feature or a change, describe what the user and their clients will **experience** — who can open the app, what each audience sees or can do. The mechanics that produce it are plumbing too: keep manifest keys (`surfaces`, `app.json`), file names, SDK method names, and identity fields like `clientId`/`internalUserId` out of chat unless the user asks how it works. "Clients will see only their own record" is something they can act on; "add a client surface to the manifest and branch on `identity.clientId`" is not.
14
+
15
+ When a request implies a scope or permission change, apply it and report the product effect — don't stop to ask the user to approve the mechanics. "When a client views this, show them their own info" already means "make this client-facing," so make the change and say what happened ("clients now see just their own record; your team still sees everyone"). Ask first only on a genuine product choice the user can weigh — who should see the app, what each audience sees — phrased in those terms, never as a manifest or surface decision.
16
+
13
17
  ---
14
18
 
15
19
  ## Skills
package/dist/client.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './session-exchange.js';
2
2
  export * from './network-capture.js';
3
+ export * from './parent-origin.js';
3
4
  export * from './client-companies.js';
4
5
  export * from './pagination.js';
5
6
  export * from './theme.js';
package/dist/client.js CHANGED
@@ -7,6 +7,9 @@
7
7
  // also runs in the Edge middleware runtime that proxy.ts uses.
8
8
  export * from './session-exchange.js';
9
9
  export * from './network-capture.js';
10
+ // Self-running on client module load (see the module comment): registers the
11
+ // framing origin with the app-bridge allowlist so custom-domain portals work.
12
+ export * from './parent-origin.js';
10
13
  export * from './client-companies.js';
11
14
  export * from './pagination.js';
12
15
  export * from './theme.js';
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Resolve the origin of the window framing this app.
3
+ *
4
+ * Prefers `location.ancestorOrigins` (browser-attested, immune to referrer
5
+ * policy; Chromium/WebKit) and falls back to `document.referrer` (Firefox).
6
+ * Returns null outside an iframe or when neither source is available —
7
+ * e.g. a restrictive Referrer-Policy on the parent in Firefox.
8
+ */
9
+ export declare function resolveParentOrigin(): string | null;
10
+ /**
11
+ * Add the framing origin to the bridge's postMessage allowlist.
12
+ *
13
+ * Idempotent (the bridge holds origins in a Set) and restricted to https
14
+ * parents — local development origins are already on the default allowlist,
15
+ * so an http parent never needs registering.
16
+ */
17
+ export declare function registerParentOriginWithBridge(): void;
@@ -0,0 +1,57 @@
1
+ // Registers the app's real framing origin with the app-bridge postMessage
2
+ // allowlist, so the bridge works on workspaces with custom portal domains.
3
+ //
4
+ // The bridge SDK ships a hardcoded origin allowlist (localhost + assembly
5
+ // domains) and silently drops every outgoing and incoming message when the
6
+ // parent origin isn't on it. On a custom-domain portal that kills header CTAs,
7
+ // session-token refresh, and theme sync. Trusting the framing origin here is
8
+ // sound because the proxy already gates who may frame the app at all: its CSP
9
+ // frame-ancestors directive allows only the static assembly domains plus this
10
+ // workspace's own portal URL, and the browser enforces that before any of this
11
+ // bundle runs. Inside the frame, the browser-reported parent origin is
12
+ // therefore always one the platform trusts.
13
+ import { AssemblyBridge } from '@assembly-js/app-bridge';
14
+ /**
15
+ * Resolve the origin of the window framing this app.
16
+ *
17
+ * Prefers `location.ancestorOrigins` (browser-attested, immune to referrer
18
+ * policy; Chromium/WebKit) and falls back to `document.referrer` (Firefox).
19
+ * Returns null outside an iframe or when neither source is available —
20
+ * e.g. a restrictive Referrer-Policy on the parent in Firefox.
21
+ */
22
+ export function resolveParentOrigin() {
23
+ if (typeof window === 'undefined')
24
+ return null;
25
+ if (window.parent === window)
26
+ return null;
27
+ const ancestor = window.location.ancestorOrigins?.[0];
28
+ if (ancestor)
29
+ return ancestor;
30
+ try {
31
+ const referrer = document.referrer;
32
+ if (referrer)
33
+ return new URL(referrer).origin;
34
+ }
35
+ catch {
36
+ // Unparseable referrer — fall through to null.
37
+ }
38
+ return null;
39
+ }
40
+ /**
41
+ * Add the framing origin to the bridge's postMessage allowlist.
42
+ *
43
+ * Idempotent (the bridge holds origins in a Set) and restricted to https
44
+ * parents — local development origins are already on the default allowlist,
45
+ * so an http parent never needs registering.
46
+ */
47
+ export function registerParentOriginWithBridge() {
48
+ const origin = resolveParentOrigin();
49
+ if (!origin || !origin.startsWith('https://'))
50
+ return;
51
+ AssemblyBridge.configure({ additionalOrigins: [origin] });
52
+ }
53
+ // Run on module load: every app's client bundle imports this package (authFetch,
54
+ // network capture), and module evaluation precedes hydration — so the origin is
55
+ // registered before any component's first header/session-token call. Baked app
56
+ // files never call this module directly, which is exactly why it self-runs.
57
+ registerParentOriginWithBridge();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assembly-js/app-foundation",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Versioned foundation helpers and build context for Assembly generated apps",
5
5
  "type": "module",
6
6
  "files": [