@crossworks/app-build 0.232.381 → 0.232.385

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossworks/app-build",
3
- "version": "0.232.381",
3
+ "version": "0.232.385",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -11,7 +11,7 @@
11
11
  "src"
12
12
  ],
13
13
  "dependencies": {
14
- "@mantle/share-ui": "npm:@crossworks/share-ui@0.232.381",
14
+ "@mantle/share-ui": "npm:@crossworks/share-ui@0.232.385",
15
15
  "@tailwindcss/oxide": "^4.3.3",
16
16
  "esbuild": "^0.28.2",
17
17
  "lucide-react": "^1.41.0",
package/src/kit.test.ts CHANGED
@@ -14,6 +14,29 @@ describe('@host kit ↔ bridge protocol mirror', () => {
14
14
  }
15
15
  });
16
16
 
17
+ it('exposes host.me(), read from the frame-baked viewer (app identity)', () => {
18
+ expect(HOST).toContain('window.__mantleHostMe');
19
+ expect(HOST).toMatch(/export const host = \{\n {2}me,/);
20
+ // No email anywhere in the answer.
21
+ expect(HOST).not.toMatch(/email:/);
22
+ });
23
+
24
+ it('host.me() answers the baked viewer, and rejects where none was baked', async () => {
25
+ const src = HOST.slice(HOST.indexOf('function me() {'));
26
+ const body = src.slice(0, src.indexOf('\n}\n') + 2);
27
+ const make = (win: Record<string, unknown>) =>
28
+ new Function('window', `${body}; return me;`)(win) as () => Promise<unknown>;
29
+ await expect(
30
+ make({ __mantleHostMe: { id: 'u_a', name: 'Pat', kind: 'member', email: 'x' } })(),
31
+ ).resolves.toEqual({ id: 'u_a', name: 'Pat', kind: 'member' });
32
+ await expect(make({ __mantleHostMe: { kind: 'public' } })()).resolves.toEqual({
33
+ id: null,
34
+ name: null,
35
+ kind: 'public',
36
+ });
37
+ await expect(make({})()).rejects.toThrow(/not available/);
38
+ });
39
+
17
40
  it('exposes the team-hub namespace with the enumerated hub kinds', () => {
18
41
  expect(HOST).toContain("kind: 'hub.get'");
19
42
  // All nav intents post the SAME event kind with the target shapes the
package/src/kit.ts CHANGED
@@ -200,7 +200,23 @@ function paintAnnotations(regions) {
200
200
  }
201
201
  }
202
202
 
203
+ // Who runs the app (app identity): { id, name, kind }, for DISPLAY. The
204
+ // frame route bakes it into the frame document from its verified ticket
205
+ // (window.__mantleHostMe), so it needs no round trip and no parent support.
206
+ // id is a per-app pseudonym (null on an open link), name the display name
207
+ // or null, kind 'admin' | 'member' | 'client' | 'contact' | 'public'. There
208
+ // is no email. To RECORD who did something, put :host_me_id / :host_me_name /
209
+ // :host_me_kind in host.db SQL: the server fills those, the browser cannot.
210
+ function me() {
211
+ const v = window.__mantleHostMe;
212
+ if (!v || typeof v !== 'object') {
213
+ return Promise.reject(new Error('host.me() is not available in this frame'));
214
+ }
215
+ return Promise.resolve({ id: v.id ?? null, name: v.name ?? null, kind: v.kind });
216
+ }
217
+
203
218
  export const host = {
219
+ me,
204
220
  tools: {
205
221
  call: (slug, input) => post({ kind: 'tool.call', slug, input: input ?? {} }),
206
222
  },