create-bridgething 0.10.0 → 0.12.0
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/README.md +16 -12
- package/dist/index.mjs +86 -21
- package/package.json +9 -3
- package/template/CLAUDE.md +60 -84
- package/template/README.md +31 -44
- package/template/_claude/skills/bridgething/SKILL.md +12 -17
- package/template/_claude/skills/bridgething/reference/develop.md +84 -65
- package/template/_claude/skills/bridgething/reference/extension.md +183 -0
- package/template/_claude/skills/bridgething/reference/sdk.md +74 -106
- package/template/_claude/skills/bridgething/reference/ship.md +19 -38
- package/template/_gitignore +1 -0
- package/template/package.json +6 -5
- package/template/scripts/bridgething.ts +1086 -0
- package/template/scripts/push.ts +212 -193
- package/template/src/App.tsx +2 -5
- package/template/src/daemon.ts +14 -0
- package/template/vite.config.ts +5 -3
- package/template-extension/_claude_append.md +23 -0
- package/template-extension/extension/main.ts +20 -0
- package/template-launcher/_claude_append.md +14 -30
- package/template-launcher/src/App.tsx +2 -5
- package/template-overlay/_claude_append.md +31 -45
|
@@ -1,40 +1,24 @@
|
|
|
1
|
-
|
|
2
1
|
## This project is a launcher
|
|
3
2
|
|
|
4
|
-
`manifest.json` declares `"role": "launcher"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
- The bundle is eligible for the device's **launcher slot**. Holding that slot
|
|
9
|
-
makes this the home screen: the boot default, the target of the Mode-button
|
|
10
|
-
gesture, and what the back button returns to.
|
|
3
|
+
`manifest.json` declares `"role": "launcher"`. The daemon keeps this bundle out
|
|
4
|
+
of `client.webapp.list`, so the grid you draw excludes itself. Holding the
|
|
5
|
+
device's launcher slot makes it the home screen: the boot default, the target of
|
|
6
|
+
the Mode gesture, and where the Back button returns to.
|
|
11
7
|
|
|
12
|
-
`bun run push` claims the slot and switches to it
|
|
13
|
-
|
|
14
|
-
phone app can do the same. The built-in hub stays installed and can never be
|
|
15
|
-
uninstalled, so releasing the slot always gets the stock home screen back. That
|
|
16
|
-
is the recovery path if a launcher you are building wedges the device.
|
|
8
|
+
`bun run push` claims the slot and switches to it. `bun run push --release` hands
|
|
9
|
+
it back to the built-in hub, the recovery path when a build wedges the device.
|
|
17
10
|
|
|
18
|
-
### What a home screen
|
|
11
|
+
### What a home screen covers
|
|
19
12
|
|
|
20
|
-
|
|
21
|
-
particular surface; if yours does less than the built-in hub, that is a choice,
|
|
22
|
-
not an error, and the user can switch back. The built-in hub covers:
|
|
13
|
+
A launcher implements as much or as little as you want. The built-in hub covers:
|
|
23
14
|
|
|
24
|
-
- the app grid (`client.webapp.list
|
|
25
|
-
|
|
26
|
-
- bluetooth
|
|
15
|
+
- the app grid (`client.webapp.list`, `.icon`, `.activate`, `.current`, plus
|
|
16
|
+
`onWebappInstalled` and `onWebappUninstalled`)
|
|
17
|
+
- bluetooth bonds, adapter alias, discoverable
|
|
27
18
|
- display brightness
|
|
28
19
|
- system info and health
|
|
29
20
|
- power: restart, shut down, factory reset
|
|
30
|
-
- OTA progress (`client.system.onOtaProgress`
|
|
31
|
-
|
|
32
|
-
The starter here implements only the grid. Read the built-in hub's source if you
|
|
33
|
-
want a reference for the rest; everything it uses is on the public client SDK.
|
|
34
|
-
|
|
35
|
-
### Onboarding is not your problem
|
|
21
|
+
- OTA progress (`client.system.onOtaProgress` and `.onOtaError`)
|
|
36
22
|
|
|
37
|
-
The
|
|
38
|
-
|
|
39
|
-
device is set up. A factory reset clears the launcher slot along with everything
|
|
40
|
-
else, which puts the built-in hub and its wizard back.
|
|
23
|
+
The starter here draws the grid. Everything the hub uses is on the public client
|
|
24
|
+
SDK.
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { BridgethingClient, type WebappInfo } from '@bridgething/client';
|
|
2
2
|
import { useEffect, useMemo, useState } from 'react';
|
|
3
|
-
|
|
4
|
-
const wsUrl =
|
|
5
|
-
import.meta.env.VITE_BRIDGETHING_URL ??
|
|
6
|
-
(typeof window !== 'undefined' ? `ws://${window.location.host}/` : 'ws://127.0.0.1:8891/');
|
|
3
|
+
import { daemonUrl } from './daemon';
|
|
7
4
|
|
|
8
5
|
type Entry = {
|
|
9
6
|
info: WebappInfo;
|
|
@@ -11,7 +8,7 @@ type Entry = {
|
|
|
11
8
|
};
|
|
12
9
|
|
|
13
10
|
export default function App() {
|
|
14
|
-
const client = useMemo(() => new BridgethingClient({ url:
|
|
11
|
+
const client = useMemo(() => new BridgethingClient({ url: daemonUrl() }), []);
|
|
15
12
|
const [entries, setEntries] = useState<Entry[] | null>(null);
|
|
16
13
|
const [error, setError] = useState<string | null>(null);
|
|
17
14
|
const [activating, setActivating] = useState<string | null>(null);
|
|
@@ -1,19 +1,13 @@
|
|
|
1
|
-
|
|
2
1
|
## This project is a system overlay
|
|
3
2
|
|
|
4
|
-
`manifest.json` declares `"overlay": "overlay.js"`.
|
|
5
|
-
device's
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
`bun run push` claims the slot for you and reloads the kiosk, so the overlay
|
|
10
|
-
appears over whatever app is showing. It deliberately does **not** switch to
|
|
11
|
-
this bundle's own page - switching away from the app you are testing against is
|
|
12
|
-
the opposite of what you want.
|
|
3
|
+
`manifest.json` declares `"overlay": "overlay.js"`. While this bundle holds the
|
|
4
|
+
device's overlay slot, the daemon injects that file into every webapp's document
|
|
5
|
+
as it loads. The page in `src/` renders when someone launches this bundle from
|
|
6
|
+
the hub.
|
|
13
7
|
|
|
14
|
-
`bun run push
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
`bun run push` claims the overlay slot and reloads the kiosk, so the overlay
|
|
9
|
+
appears over the webapp that is showing. `bun run push --release` hands the slot
|
|
10
|
+
back to the built-in overlay, the recovery path when a build misbehaves.
|
|
17
11
|
|
|
18
12
|
### The contract
|
|
19
13
|
|
|
@@ -23,42 +17,34 @@ The daemon prepends one global before your bundle:
|
|
|
23
17
|
window.__bridgethingOverlay = { origin: 'http://127.0.0.1:8891', surfaces: {...} };
|
|
24
18
|
```
|
|
25
19
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
their own. If every surface is off, the daemon injects nothing at all.
|
|
31
|
-
- **`origin`** is the kiosk origin. Check `location.origin` against it before
|
|
32
|
-
mounting so the bundle never runs in a page the daemon did not serve.
|
|
20
|
+
`surfaces` is the active webapp's declared profile, a boolean each for
|
|
21
|
+
`notifications`, `call`, `pairing`, `connection`, `volume`, and `voice`. Render
|
|
22
|
+
only the surfaces set to true; an app that draws its own volume indicator
|
|
23
|
+
declares `volume: false`. When every surface is false the daemon injects nothing.
|
|
33
24
|
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
`origin` is the kiosk origin. Compare `location.origin` against it before
|
|
26
|
+
mounting. Everything else comes from `@bridgething/client` over the local
|
|
27
|
+
websocket.
|
|
36
28
|
|
|
37
|
-
###
|
|
29
|
+
### Output constraints
|
|
38
30
|
|
|
39
|
-
`overlay.js` must be
|
|
40
|
-
a script string into another app's document, so it
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
`overlay.js` must be one self-contained file under 512 KiB. The daemon injects it
|
|
32
|
+
as a script string into another app's document, so it carries its own code and
|
|
33
|
+
styles and reaches nothing at runtime. `vite.overlay.config.ts` builds a single
|
|
34
|
+
inlined iife; keep that shape.
|
|
43
35
|
|
|
44
|
-
|
|
45
|
-
`overlay/
|
|
46
|
-
|
|
47
|
-
so
|
|
48
|
-
shadow root. Add `@theme` tokens or plain rules there. Because the shadow root
|
|
49
|
-
is closed, tailwind is told not to scan the project (`source(none)`) and only
|
|
50
|
-
generates what `overlay/main.tsx` uses - if you split the overlay across more
|
|
51
|
-
files, add each one with `@source`.
|
|
36
|
+
Style `overlay/main.tsx` with tailwind classes like the rest of the project.
|
|
37
|
+
`overlay/style.css` is imported with vite's `?inline`, so the compiled css mounts
|
|
38
|
+
into the shadow root as a string. Tailwind scans only `overlay/main.tsx`
|
|
39
|
+
(`source(none)`), so add an `@source` line for every file you split across.
|
|
52
40
|
|
|
53
|
-
|
|
41
|
+
### Keep these four from the starter
|
|
54
42
|
|
|
55
|
-
1.
|
|
56
|
-
2.
|
|
57
|
-
3.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
showing. Your overlay sits on top of every app on the device; swallowing keys
|
|
61
|
-
broadly breaks all of them.
|
|
43
|
+
1. The origin guard before mounting.
|
|
44
|
+
2. The `__bridgethingOverlayMounted` guard, so a second injection is a no-op.
|
|
45
|
+
3. The closed shadow root, which keeps your styles and the host app's apart.
|
|
46
|
+
4. Escape-only key handling on the capture phase, active only while something is
|
|
47
|
+
showing.
|
|
62
48
|
|
|
63
|
-
You
|
|
64
|
-
|
|
49
|
+
You run inside every webapp's page. A crash, a fullscreen paint, or a broad key
|
|
50
|
+
handler takes down all of them.
|