brane 0.3.0 → 0.3.1
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/AGENTS.md +12 -7
- package/CHANGELOG.md +37 -4
- package/CONTRIBUTING.md +12 -2
- package/DESIGN.md +7 -4
- package/README.md +2 -2
- package/SECURITY.md +8 -0
- package/dist/commands/config.js +17 -0
- package/dist/commands/meld.js +38 -10
- package/dist/commands/spawn.js +11 -4
- package/dist/commands/token.js +2 -1
- package/dist/daemon/server.js +88 -84
- package/dist/db/schema.js +10 -0
- package/dist/db/tokens.js +43 -2
- package/dist/shared/app-origin.js +26 -0
- package/dist/shared/narrative-menu.js +8 -6
- package/dist/shared/view-url.js +39 -20
- package/dist/test/app-host-literal.test.js +53 -0
- package/dist/test/cors-preflight.test.js +28 -21
- package/dist/test/hook-config.test.js +38 -1
- package/dist/test/meld.test.js +59 -1
- package/dist/test/narrative-menu.test.js +13 -0
- package/dist/test/remote-meld.test.js +13 -0
- package/dist/test/terminal-size.test.js +36 -0
- package/dist/test/token-devices.test.js +59 -0
- package/dist/test/view-url.test.js +93 -47
- package/dist/test/wrangler-route.test.js +27 -0
- package/dist/tmux.js +11 -0
- package/docker-entrypoint.sh +15 -2
- package/docs/daemon-api.md +4 -4
- package/docs/releasing.md +59 -8
- package/docs/terminal-mirroring.md +32 -0
- package/docs/token-rotation.md +22 -4
- package/docs/view-urls.md +26 -6
- package/docs/web-app.md +1 -1
- package/expo/dist/_expo/static/js/web/{entry-e56efc1291dca7258ea00b8108b033a4.js → entry-e94247f119fdcd3b424a1764233a41d2.js} +47 -45
- package/expo/dist/index.html +1 -1
- package/expo/dist/sw.js +2 -2
- package/package.json +1 -1
- package/wiki/shared/index.md +5 -0
package/docs/view-urls.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
The query string of a narrative screen is not decoration — it is the only way
|
|
4
4
|
a view travels. Active tab, pinned tabs, open file and line range are kept in
|
|
5
5
|
`sessionStorage`, which is **origin-scoped**, and two menu items cross an
|
|
6
|
-
origin: **Isolate** hops between
|
|
6
|
+
origin: **Isolate** hops between a shared app's origin and a daemon's own
|
|
7
7
|
bundle, and **Meld** hands a URL to another device. Whatever is not in the URL
|
|
8
8
|
does not arrive.
|
|
9
9
|
|
|
@@ -15,16 +15,36 @@ tab, pin subset, path and line spec):
|
|
|
15
15
|
|---|---|
|
|
16
16
|
| `viewParams()` | The view as params, `undefined` for anything at its default — which is how `router.setParams` clears one |
|
|
17
17
|
| `parseActiveTab()`, `parsePinnedTabs()`, `parseLineSpec()` | Read them back. Writer and reader live together on purpose: a param whose two halves sit in different modules drifts |
|
|
18
|
+
| `isIsolated(pageHost, daemonHost)` | Whether this page is the daemon's own bundle: `location.host` against the connection's host, no constant in it |
|
|
18
19
|
| `buildViewUrl(target, opts)` | The same narrative, same view, somewhere else |
|
|
19
|
-
| `buildIsolateUrl()` / `buildMeldUrl()` | The same builder with one bit different — see below |
|
|
20
|
+
| `buildIsolateUrl()` / `buildMeldUrl()` | The same builder with one bit different — see below. Isolate is `null` from a daemon's bundle that reported no app host |
|
|
20
21
|
| `withoutConnectionParams()`, `withoutConnectionHash()` | Strip `host`/`token` from the query string and from the fragment, and leave everything else |
|
|
21
22
|
| `connectionFragment()` | `#host=…&token=…` for the shared app, `#token=…` for a daemon's own bundle — the one place the connection is written into a URL, used by `buildViewUrl` and by `brane meld` |
|
|
22
23
|
|
|
23
24
|
**Isolate flips the origin kind; Meld stays on it.** Isolate exists to change
|
|
24
|
-
which app serves you. Meld aims at another *device* — hand a phone a shared-
|
|
25
|
+
which app serves you. Meld aims at another *device* — hand a phone a shared-app
|
|
25
26
|
link while the operator is reaching the daemon directly, and the phone loads an
|
|
26
27
|
app that has never heard of that daemon.
|
|
27
28
|
|
|
29
|
+
**The app knows no host.** There is no constant naming `brane.organelle.dev`
|
|
30
|
+
in the bundle, and `src/test/app-host-literal.test.ts` keeps it that way.
|
|
31
|
+
"Isolated" means *this page is served by the daemon it is connected to*:
|
|
32
|
+
`window.location.host` equal to the connection's host, which a daemon's own
|
|
33
|
+
bundle fills from the same `location.host`. Everything else is a shared app,
|
|
34
|
+
whichever host serves it: the hosted shell, a staging hostname, a fork's
|
|
35
|
+
deployment, a dev server on `localhost`. From a shared app, Meld stays on
|
|
36
|
+
*that* origin and Isolate hops in to the daemon; neither needs to be told a
|
|
37
|
+
host. From a daemon's bundle, Isolate hops *out* to whatever the daemon
|
|
38
|
+
reports as its `app_domain` in `GET /api/status` (`useAppHost`,
|
|
39
|
+
`expo/lib/appHost.ts`, fetched before the tap, since a `window.open` after an
|
|
40
|
+
await is a popup the browser blocks). A daemon that reports none, or cannot
|
|
41
|
+
be reached for it, has no way out, and the menu leaves Isolate out rather
|
|
42
|
+
than hand you a link to a host the app made up. `brane meld` reads the same
|
|
43
|
+
config, so a fork changes `CONFIG_DEFAULTS.app_domain` and both its CLI and
|
|
44
|
+
its daemons name its own shell. None of this is trust: the daemon accepts any
|
|
45
|
+
origin (`SECURITY.md`, Authentication); the host only decides which copy of
|
|
46
|
+
the app a browser loads.
|
|
47
|
+
|
|
28
48
|
**Back undoes a jump, never a view change.** A jump pushes a history entry: to
|
|
29
49
|
a different narrative (from the list, an `@nid` link, the switcher, Revive or
|
|
30
50
|
Twin), and to a message by `nid:seq`, *including one in the narrative you are
|
|
@@ -86,9 +106,9 @@ by resetting to the bare pathname, which would throw away the view that just
|
|
|
86
106
|
arrived.
|
|
87
107
|
|
|
88
108
|
**The connection rides in the fragment; the view rides in the query string.**
|
|
89
|
-
A query string is part of the HTTP request. On a
|
|
90
|
-
|
|
91
|
-
|
|
109
|
+
A query string is part of the HTTP request. On a shared-app link that meant
|
|
110
|
+
the daemon's bearer token and tailnet hostname reached the shell host's edge
|
|
111
|
+
with every meld; on an Isolate hop it landed in the daemon's own request
|
|
92
112
|
log; and a meld URL pasted into iMessage or Slack handed it to the link
|
|
93
113
|
unfurler. A fragment is never sent to any server, so `#host=…&token=…` is what
|
|
94
114
|
every link carries now (`connectionFragment`), and `?token=` is read only for
|
package/docs/web-app.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Web App (Expo)
|
|
2
2
|
|
|
3
|
-
The Expo app runs as a web PWA served by the daemon (and optionally via Cloudflare Workers at `brane.organelle.dev`). It provides:
|
|
3
|
+
The Expo app runs as a web PWA served by the daemon (and optionally via Cloudflare Workers at `brane.organelle.dev`, which serves the app of the `latest` npm release and is deployed only by a release — see [The app ships with the release](releasing.md#the-app-ships-with-the-release)). It provides:
|
|
4
4
|
|
|
5
5
|
- **Narrative list** — shows all narratives with summary, status, and MCP connection indicator
|
|
6
6
|
- **Spawn button** — header button that opens fold picker modal (or spawns directly with 1 fold)
|