@agentshouse/app-bridge 0.1.0-c357a960443ec → 0.1.0-c7e28272ee501

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Anton (trof3039)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -7,18 +7,17 @@ installation, notifications, status, Site image reads, App release code,
7
7
  external calls, App messages and App and Site screenshot reads.
8
8
  [docs/families.md](docs/families.md) describes each and the test host.
9
9
 
10
- The package carries no credential handling and no Runtime family. It surfaces
11
- the dedicated Runtime port the worker transfers over the bridge as a plain
12
- message port, which the App hands to the MD Runtime client entry.
10
+ The package carries no credential handling and no Runtime family. House builds
11
+ the MD Runtime client into the page beside the bridge, and `bridge.runtime`
12
+ resolves to that client, so the App imports and constructs none.
13
13
 
14
14
  ## Use
15
15
 
16
16
  ```js
17
17
  import { connectHouseBridge } from '@agentshouse/app-bridge';
18
- import { connectMdRuntime } from '@agentshouse/mdruntime/client';
19
18
 
20
19
  const bridge = connectHouseBridge();
21
- const md = connectMdRuntime(await bridge.runtime);
20
+ const md = await bridge.runtime;
22
21
 
23
22
  bridge.onAddress((address) => render(address));
24
23
  bridge.onStatus((status) => showSync(status.sync));
@@ -38,9 +37,8 @@ async function manageSecurity(securityPath) {
38
37
  }
39
38
  ```
40
39
 
41
- `bridge.runtime` resolves with a structural `HouseMessagePort`. A consumer whose
42
- Runtime client entry asks for the DOM `MessagePort` type passes it through
43
- directly at run time and casts at the type level.
40
+ `bridge.runtime` resolves to the `MdRuntimeClient` of
41
+ `@agentshouse/mdruntime/client`, whose README describes its members.
44
42
 
45
43
  ## Test without a House
46
44
 
@@ -49,7 +47,7 @@ import { connectHouseBridge } from '@agentshouse/app-bridge';
49
47
  import { createHouseBridgeTestHost } from '@agentshouse/app-bridge/test-host';
50
48
 
51
49
  const host = createHouseBridgeTestHost({ address: '/rooms/atlas' });
52
- const bridge = connectHouseBridge(host.port);
50
+ const bridge = connectHouseBridge(host);
53
51
 
54
52
  bridge.push('/rooms/atlas/members');
55
53
  host.open('/rooms/atlas');
@@ -1,4 +1,5 @@
1
- import type { HouseAppMessage, HouseExternalAnswer, HouseExternalRequest, HouseBridgePort, HouseGaChoice, HouseMessagePort, HouseRefusal, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab } from './wire.js';
1
+ import type { MdRuntimeClient } from '@agentshouse/mdruntime/client';
2
+ import type { HouseAppMessage, HouseExternalAnswer, HouseExternalRequest, HouseBridgePort, HouseGaChoice, HouseRefusal, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab } from './wire.js';
2
3
  export declare class HouseCeremonyRefused extends Error {
3
4
  readonly path: string | null;
4
5
  constructor(path: string | null);
@@ -15,8 +16,12 @@ export interface HouseImageCopy {
15
16
  }
16
17
  type HouseInstallation = 'accepted' | 'dismissed' | 'manual';
17
18
  type HouseNotifications = 'on' | 'off' | 'blocked' | 'unavailable';
19
+ export interface HouseBridgeSource {
20
+ readonly port: Promise<HouseBridgePort>;
21
+ readonly runtime: Promise<MdRuntimeClient>;
22
+ }
18
23
  export interface HouseBridge {
19
- readonly runtime: Promise<HouseMessagePort>;
24
+ readonly runtime: Promise<MdRuntimeClient>;
20
25
  address(): string | null;
21
26
  onAddress(listener: (address: string) => void): () => void;
22
27
  push(address: string): Promise<string>;
@@ -37,5 +42,5 @@ export interface HouseBridge {
37
42
  messages(listener: (message: HouseAppMessage) => void): () => void;
38
43
  gaConsent(choice: HouseGaChoice): void;
39
44
  }
40
- export declare function connectHouseBridge(source?: Promise<HouseBridgePort>): HouseBridge;
45
+ export declare function connectHouseBridge(source?: HouseBridgeSource): HouseBridge;
41
46
  export {};
@@ -36,13 +36,12 @@ function settled() {
36
36
  return { promise, settle: settle };
37
37
  }
38
38
  function heldBridge() {
39
- const held = globalThis.houseBridge;
40
- if (held === undefined)
39
+ const held = globalThis;
40
+ if (held.houseBridge === undefined || held.houseRuntime === undefined)
41
41
  throw new Error('house_bridge_absent');
42
- return held;
42
+ return { port: held.houseBridge, runtime: held.houseRuntime };
43
43
  }
44
44
  export function connectHouseBridge(source = heldBridge()) {
45
- const runtime = settled();
46
45
  const ceremonies = [];
47
46
  const navigations = [];
48
47
  const attachments = new Map();
@@ -76,12 +75,6 @@ export function connectHouseBridge(source = heldBridge()) {
76
75
  const data = event.data;
77
76
  if (data === null || typeof data !== 'object')
78
77
  return;
79
- if (data.house === 'runtime') {
80
- const [port] = event.ports;
81
- if (port !== undefined)
82
- runtime.settle.resolve(port);
83
- return;
84
- }
85
78
  if (data.house === 'status') {
86
79
  status = data.status;
87
80
  for (const listener of statusListeners)
@@ -176,7 +169,7 @@ export function connectHouseBridge(source = heldBridge()) {
176
169
  pending?.settle.reject(new HouseCeremonyRefused(named));
177
170
  }
178
171
  }
179
- void source.then((port) => {
172
+ void source.port.then((port) => {
180
173
  held = port;
181
174
  port.addEventListener('message', receive);
182
175
  port.start();
@@ -206,7 +199,7 @@ export function connectHouseBridge(source = heldBridge()) {
206
199
  return pending.promise;
207
200
  }
208
201
  return {
209
- runtime: runtime.promise,
202
+ runtime: source.runtime,
210
203
  address() {
211
204
  return address;
212
205
  },
@@ -1,3 +1,3 @@
1
- export { connectHouseBridge, HouseCeremonyRefused, HouseNavigationRefused, type HouseBridge, type HouseImageCopy, } from './bridge.js';
1
+ export { connectHouseBridge, HouseCeremonyRefused, HouseNavigationRefused, type HouseBridge, type HouseBridgeSource, type HouseImageCopy, } from './bridge.js';
2
2
  export { HOUSE_ADDRESS_MAX_CHARS } from './wire.js';
3
- export type { HouseAppMessage, HouseBridgeEvent, HouseBridgePort, HouseCredentialState, HouseExternalAnswer, HouseExternalRequest, HouseGa, HouseGaChoice, HouseMessagePort, HouseNavigationMode, HouseRefusal, HouseSourceDownload, HouseSourceFile, HouseSourceTop, HouseStatus, HouseSyncState, } from './wire.js';
3
+ export type { HouseAppMessage, HouseBridgeEvent, HouseBridgePort, HouseCredentialState, HouseExternalAnswer, HouseExternalRequest, HouseGa, HouseGaChoice, HouseNavigationMode, HouseRefusal, HouseSourceDownload, HouseSourceFile, HouseSourceTop, HouseStatus, HouseSyncState, } from './wire.js';
@@ -1,11 +1,11 @@
1
- import type { HouseImageCopy } from './bridge.js';
2
- import type { HouseAppMessage, HouseBridgePort, HouseExternalAnswer, HouseExternalRequest, HouseGaChoice, HouseMessagePort, HouseNavigationMode, HouseRefusal, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab } from './wire.js';
1
+ import type { MdRuntimeClient } from '@agentshouse/mdruntime/client';
2
+ import type { HouseBridgeSource, HouseImageCopy } from './bridge.js';
3
+ import type { HouseAppMessage, HouseExternalAnswer, HouseExternalRequest, HouseGaChoice, HouseNavigationMode, HouseRefusal, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab } from './wire.js';
3
4
  export interface HouseBridgeNavigation {
4
5
  readonly mode: HouseNavigationMode;
5
6
  readonly address: string;
6
7
  }
7
- export interface HouseBridgeTestHost {
8
- readonly port: Promise<HouseBridgePort>;
8
+ export interface HouseBridgeTestHost extends HouseBridgeSource {
9
9
  readonly navigations: readonly HouseBridgeNavigation[];
10
10
  readonly ceremonies: readonly string[];
11
11
  readonly consents: readonly HouseGaChoice[];
@@ -15,7 +15,7 @@ export interface HouseBridgeTestHost {
15
15
  open(address: string): void;
16
16
  publish(status: HouseStatus): void;
17
17
  message(message: HouseAppMessage): void;
18
- attachRuntime(runtime: HouseMessagePort): void;
18
+ attachRuntime(runtime: MdRuntimeClient): void;
19
19
  }
20
20
  export interface HouseBridgeTestHostOptions {
21
21
  readonly address?: string;
@@ -23,8 +23,12 @@ export function createHouseBridgeTestHost(options = {}) {
23
23
  let started = false;
24
24
  let address = appAddressOf('/', options.address ?? '/');
25
25
  let status = options.status ?? null;
26
- function deliver(data, ports = []) {
27
- const event = { data, ports };
26
+ let attached = () => { };
27
+ const runtime = new Promise((resolve) => {
28
+ attached = resolve;
29
+ });
30
+ function deliver(data) {
31
+ const event = { data };
28
32
  if (!started) {
29
33
  queued.push(event);
30
34
  return;
@@ -158,6 +162,7 @@ export function createHouseBridgeTestHost(options = {}) {
158
162
  deliver({ house: 'address', address, navigated: false });
159
163
  return {
160
164
  port: Promise.resolve(port),
165
+ runtime,
161
166
  navigations,
162
167
  ceremonies,
163
168
  consents,
@@ -173,8 +178,8 @@ export function createHouseBridgeTestHost(options = {}) {
173
178
  message(message) {
174
179
  deliver({ house: 'app-message', from: message.from, body: message.body });
175
180
  },
176
- attachRuntime(runtime) {
177
- deliver({ house: 'runtime' }, [runtime]);
181
+ attachRuntime(client) {
182
+ attached(client);
178
183
  },
179
184
  };
180
185
  }
@@ -1,14 +1,12 @@
1
1
  import type { TabChange } from '../../src/apps/tab.js';
2
2
  export interface HouseBridgeEvent {
3
3
  readonly data: unknown;
4
- readonly ports: readonly HouseMessagePort[];
5
4
  }
6
- export interface HouseMessagePort {
5
+ export interface HouseBridgePort {
7
6
  postMessage(message: unknown): void;
8
7
  addEventListener(type: 'message', listener: (event: HouseBridgeEvent) => void): void;
9
8
  start(): void;
10
9
  }
11
- export type HouseBridgePort = HouseMessagePort;
12
10
  export interface HouseSyncState {
13
11
  readonly state: string;
14
12
  readonly providerUnreachable: boolean;
@@ -33,6 +31,7 @@ export interface HouseStatus {
33
31
  readonly loss: string | null;
34
32
  readonly ga: HouseGa;
35
33
  readonly service_mode: 'open' | 'write-halted' | null;
34
+ readonly offline: boolean;
36
35
  }
37
36
  export type HouseNavigationMode = 'push' | 'replace';
38
37
  interface HouseRelease {
@@ -12,5 +12,5 @@ export function appAddressOf(root, address) {
12
12
  export function shellAddressOf(root, appAddress) {
13
13
  const { path, rest } = split(appAddress);
14
14
  const below = path === '/' ? '' : path;
15
- return `${root === '/' ? '' : root}${below}${rest}` || '/';
15
+ return `${`${root === '/' ? '' : root}${below}` || '/'}${rest}`;
16
16
  }
package/docs/families.md CHANGED
@@ -32,7 +32,7 @@
32
32
  click. `setBadge(unread)` takes the identifiers of the Human Notifications
33
33
  unread in this storage and sets the icon's badge to their number, or clears
34
34
  it at none, where the browser shows one.
35
- - **Status** - the App reference the Runtime port is attached under, sync
35
+ - **Status** - the App reference the runtime client is attached under, sync
36
36
  state, credential state and observed failure, `ga`:
37
37
  whether the page measures and the visitor's stored analytics choice, and
38
38
  `service_mode`: `open`, `write-halted` while House refuses writes, so the
@@ -100,4 +100,5 @@ reference and `readSiteScreenshot` from the `siteScreenshots` it was given by
100
100
  Site identifier, answers every `install()` `'manual'`, as a browser with no install
101
101
  prompt does, answers every `notifications()` `'unavailable'`, as a browser
102
102
  without push does, settles every `setBadge`, delivers each App message
103
- `message({ from, body })` plays, and attaches a Runtime port.
103
+ `message({ from, body })` plays, and hands `bridge.runtime` the MD Runtime
104
+ client `attachRuntime(client)` gives it.
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@agentshouse/app-bridge",
3
- "version": "0.1.0-c357a960443ec",
3
+ "version": "0.1.0-c7e28272ee501",
4
4
  "description": "Renderer-side client of the agents.house App bridge: navigation, the tab title and icon, ceremonies, installation, notifications and the icon badge, status, Site image reads, App release code, App and Site screenshot reads, and App messages, with an in-page test host.",
5
- "license": "UNLICENSED",
5
+ "license": "MIT",
6
6
  "type": "module",
7
7
  "sideEffects": false,
8
8
  "engines": {
@@ -18,9 +18,13 @@
18
18
  "default": "./dist/client/src/test-host.js"
19
19
  }
20
20
  },
21
+ "dependencies": {
22
+ "@agentshouse/mdruntime": "0.1.0-c7b0ab1aa40a3"
23
+ },
21
24
  "files": [
22
25
  "dist",
23
26
  "docs",
24
- "README.md"
27
+ "README.md",
28
+ "LICENSE"
25
29
  ]
26
30
  }