@unifedev/thread-pages 0.3.2 → 1.1.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 +77 -129
- package/dist/server.js +11779 -11801
- package/dist/server.meta.json +2 -2
- package/docs/B1-OWN-FILES.md +133 -0
- package/docs/FOR-PAGE-AUTHORS-1.1.md +167 -0
- package/docs/UPGRADING.md +53 -0
- package/package.json +26 -18
- package/server.ts +3 -2175
- package/src/agent/cli.ts +193 -0
- package/src/agent/guide.ts +450 -0
- package/src/agent/instruction.ts +59 -0
- package/src/agent/seed/seed.ts +73 -0
- package/{theme.ts → src/agent/seed/theme-css.ts} +9 -11
- package/src/agent/starter-hub.ts +217 -0
- package/src/bb/activity.ts +59 -0
- package/src/bb/bb-host.ts +280 -0
- package/src/bb/public-origin.ts +45 -0
- package/src/config/settings.ts +82 -0
- package/src/domain/capabilities/contract.ts +48 -0
- package/src/domain/capabilities/index.ts +10 -0
- package/src/domain/capabilities/protocol.ts +113 -0
- package/src/domain/capabilities/registry.ts +48 -0
- package/src/domain/capabilities/renamed.ts +34 -0
- package/src/domain/capabilities/schema.ts +198 -0
- package/src/domain/capabilities/specs.ts +479 -0
- package/src/domain/eligibility.ts +43 -0
- package/src/domain/errors.ts +116 -0
- package/src/domain/html/document.ts +109 -0
- package/src/domain/html/escape.ts +16 -0
- package/src/domain/ids.ts +37 -0
- package/src/domain/json/canonical.ts +19 -0
- package/src/domain/json/strict-json.ts +139 -0
- package/src/domain/limits.ts +98 -0
- package/src/domain/rate-limit.ts +64 -0
- package/src/domain/revision.ts +27 -0
- package/src/domain/submissions/idempotency.ts +59 -0
- package/src/domain/submissions/message.ts +42 -0
- package/src/domain/submissions/parse.ts +105 -0
- package/src/domain/tokens/action-token.ts +52 -0
- package/src/domain/tokens/confirmation.ts +99 -0
- package/src/domain/tokens/mac.ts +50 -0
- package/src/generated/kernel-runtime.ts +3 -0
- package/src/generated/shell-runtime.ts +3 -0
- package/src/host/contract.ts +65 -0
- package/src/host/types.ts +89 -0
- package/src/pages/inline.ts +277 -0
- package/src/pages/layout.ts +65 -0
- package/src/pages/page-store.ts +170 -0
- package/src/pages/site.ts +36 -0
- package/src/plugin.ts +81 -0
- package/src/runtime/kernel/anchors.ts +45 -0
- package/src/runtime/kernel/api.ts +15 -0
- package/src/runtime/kernel/bridge-client.ts +148 -0
- package/src/runtime/kernel/dirty.ts +51 -0
- package/src/runtime/kernel/forms.ts +114 -0
- package/src/runtime/kernel/install.ts +156 -0
- package/src/runtime/kernel/labels.ts +98 -0
- package/src/runtime/kernel/main.ts +6 -0
- package/src/runtime/kernel/readonly.ts +75 -0
- package/src/runtime/shared/protocol.ts +125 -0
- package/src/runtime/shell/confirm.ts +70 -0
- package/src/runtime/shell/install.ts +79 -0
- package/src/runtime/shell/main.ts +12 -0
- package/src/runtime/shell/navigate.ts +64 -0
- package/src/runtime/shell/poll.ts +125 -0
- package/src/runtime/shell/relay.ts +185 -0
- package/src/serving/action-request.ts +32 -0
- package/src/serving/bridge/dispatcher.ts +112 -0
- package/src/serving/bridge/handler.ts +37 -0
- package/src/serving/bridge/handlers/index.ts +26 -0
- package/src/serving/bridge/handlers/navigation.ts +43 -0
- package/src/serving/bridge/handlers/reads.ts +186 -0
- package/src/serving/bridge/handlers/writes.ts +175 -0
- package/src/serving/bridge/selection-store.ts +58 -0
- package/src/serving/bridge-route.ts +23 -0
- package/src/serving/context.ts +34 -0
- package/src/serving/document-route.ts +37 -0
- package/src/serving/home-route.ts +23 -0
- package/src/serving/responses.ts +81 -0
- package/src/serving/routes.ts +26 -0
- package/src/serving/session-access.ts +22 -0
- package/src/serving/shell-html.ts +77 -0
- package/src/serving/shell-route.ts +51 -0
- package/src/serving/signing-key.ts +25 -0
- package/src/serving/submit-route.ts +47 -0
- package/src/serving/upload-route.ts +46 -0
- package/tsconfig.json +10 -6
- package/ARCHITECTURE.md +0 -230
- package/PLUGIN_OVERVIEW.md +0 -83
- package/authoring.ts +0 -368
- package/bridge.ts +0 -1721
- package/docs/MODEL.md +0 -211
- package/docs/ROADMAP.md +0 -96
- package/home.ts +0 -419
- package/page.ts +0 -782
package/dist/server.meta.json
CHANGED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# A page's own files, and the workaround that should be deleted
|
|
2
|
+
|
|
3
|
+
**Status:** the workaround shipped. It is temporary by design. This document
|
|
4
|
+
says what it works around, how to know the workaround is no longer needed, and
|
|
5
|
+
exactly what to delete.
|
|
6
|
+
|
|
7
|
+
## The bug
|
|
8
|
+
|
|
9
|
+
A page that loads its own stylesheet or data file renders correctly on
|
|
10
|
+
loopback and **renders empty for the reader on bb Connect** — the origin a
|
|
11
|
+
reader actually uses on a phone. Nothing errors. The author cannot see it from
|
|
12
|
+
the machine that wrote the page, so every fixture in `verify/` passed while the
|
|
13
|
+
feature was broken in the field.
|
|
14
|
+
|
|
15
|
+
Reported as B1 in `unife-bb-plugin/docs/FIELD-ISSUES-2026-09-08.md`, where a
|
|
16
|
+
reader saw a fully functional interface reporting that a 300-row wiki was
|
|
17
|
+
empty.
|
|
18
|
+
|
|
19
|
+
## The cause, measured
|
|
20
|
+
|
|
21
|
+
Unauthenticated GETs, no cookie, 2026-09-09, bb 0.42.1:
|
|
22
|
+
|
|
23
|
+
| Path | loopback `127.0.0.1:38886` | `bart.getbb.app` |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| `…/plugins/thread-pages/http/page?session=…` | 200 | 401 |
|
|
26
|
+
| `…/threads/<id>/thread-storage/files/index.html` | 200 | 401 |
|
|
27
|
+
| `/api/v1/health` (does not exist) | 404 | 401 |
|
|
28
|
+
| `…/plugins/nonexistent-xyz/http/page` | 404 | **401** |
|
|
29
|
+
|
|
30
|
+
The last row is the one that matters: a plugin that does not exist gets bb's
|
|
31
|
+
own 404 locally and Cloudflare's 401 remotely. **bb Connect authenticates at
|
|
32
|
+
the edge, before bb is reached at all.** The remote responses carry
|
|
33
|
+
`server: cloudflare` and a `cf-ray`, and their body is the Connect sign-in
|
|
34
|
+
gate — `apps/connect/src/worker.ts` in `get-bb/bb`, which ends its credential
|
|
35
|
+
ladder with `signInPage(...)` when no session cookie is present.
|
|
36
|
+
|
|
37
|
+
The page frame is `sandbox="allow-scripts allow-forms"`, so it has an opaque
|
|
38
|
+
origin. Its **document** request is issued by the trusted shell, whose
|
|
39
|
+
site-for-cookies is the Connect host, so the `SameSite=Lax` cookie is attached
|
|
40
|
+
and the document loads. Any **subresource** request issued from inside that
|
|
41
|
+
frame has an opaque origin in its ancestor chain, so its site-for-cookies is
|
|
42
|
+
null, the request counts as cross-site, and the Lax cookie is not attached.
|
|
43
|
+
Both Connect cookies are Lax: `apps/desktop/src/connect-desktop-session.ts`
|
|
44
|
+
hard-codes `sameSite: "lax"`, and the account cookie is better-auth's default.
|
|
45
|
+
|
|
46
|
+
The document-request half and the edge-gate half are measured. The
|
|
47
|
+
cookie-attachment rule is the specification applied to a case that cannot be
|
|
48
|
+
instrumented without devtools on the authenticated remote origin; it is the
|
|
49
|
+
only account consistent with what was observed.
|
|
50
|
+
|
|
51
|
+
### What this rules out
|
|
52
|
+
|
|
53
|
+
**Plugin prefix routes do not fix this.** The `plugin-prefix` site strategy in
|
|
54
|
+
`src/pages/site.ts` and the proposal in
|
|
55
|
+
`unife-bb-plugin/rewrite/07-bb-prefix-routes-proposal.md` move a page's files
|
|
56
|
+
from one path the edge 401s to another path the edge 401s. Prefix routes fix a
|
|
57
|
+
different bug — X17, `fetch()` of a page's own files, refused because bb core
|
|
58
|
+
routes reject `Origin: null` — and they are the substrate the real fix needs.
|
|
59
|
+
They are not the fix.
|
|
60
|
+
|
|
61
|
+
## The workaround, as shipped
|
|
62
|
+
|
|
63
|
+
`src/pages/inline.ts` resolves every relative reference in the entry document
|
|
64
|
+
against the page root **when the document is served**, and rewrites it to a
|
|
65
|
+
`data:` URL. The document is the one artifact whose request is always
|
|
66
|
+
authorised, so it carries the page's files with it.
|
|
67
|
+
|
|
68
|
+
- The URL is rewritten, not the element, so `defer`, `type="module"`, `media`,
|
|
69
|
+
`alt` and every other attribute keep their meaning — and a file containing
|
|
70
|
+
`</script>` cannot break out of the document.
|
|
71
|
+
- `url()` inside a resolved stylesheet is followed, bounded by
|
|
72
|
+
`LIMITS.inlineCssDepth`.
|
|
73
|
+
- Anything absolute, protocol-relative, already a URL, or a bare fragment is
|
|
74
|
+
left exactly as written.
|
|
75
|
+
- Anything missing, over `LIMITS.inlineFileBytes`, or over
|
|
76
|
+
`LIMITS.inlineTotalBytes` is left as written and logged by path and reason.
|
|
77
|
+
The page degrades to its pre-workaround behaviour rather than to a broken
|
|
78
|
+
document.
|
|
79
|
+
- Traversal is refused by `isSafeRelativePath` and reported as `unsafe-path`.
|
|
80
|
+
|
|
81
|
+
Wired in `src/plugin.ts` (one argument to `createPageStore`) and resolved
|
|
82
|
+
inside `PageStore.load`, so the served document, its revision, its ETag and its
|
|
83
|
+
offline copy all describe the same bytes.
|
|
84
|
+
|
|
85
|
+
### What it costs
|
|
86
|
+
|
|
87
|
+
- A page's files are inside the document, so they count against the 5 MiB
|
|
88
|
+
entry limit, and a page over 200 KiB keeps no offline copy. That drop used
|
|
89
|
+
to be silent; `page-store.ts` now logs it with the size and the limit.
|
|
90
|
+
- base64 adds a third.
|
|
91
|
+
- Files are re-read on each document load. Sidecar edits therefore reload an
|
|
92
|
+
open page, which is a better story than before — but a very large data file
|
|
93
|
+
is re-read on every revision poll that returns a body.
|
|
94
|
+
- A `data:` URL module script cannot resolve relative imports.
|
|
95
|
+
|
|
96
|
+
## When to delete it
|
|
97
|
+
|
|
98
|
+
When the host can authorise a sandboxed document's own subresource requests.
|
|
99
|
+
Concretely, when **both** of these have landed in bb:
|
|
100
|
+
|
|
101
|
+
1. **Prefix plugin HTTP routes** — `bb.http.route("GET", "/page/*", …)` with
|
|
102
|
+
`auth: "none"`, so this plugin can serve its own page directory and the
|
|
103
|
+
document URL becomes path-shaped. Branch: `feat/plugin-prefix-http-routes`.
|
|
104
|
+
2. **A Connect page grant** — a short-lived, signed, GET-only credential
|
|
105
|
+
carried as a path segment (`…/http/__grant/<token>/…`, so relative
|
|
106
|
+
references inherit it) that the Connect worker verifies and strips before
|
|
107
|
+
forwarding. Branch: `feat/connect-page-grant`.
|
|
108
|
+
|
|
109
|
+
A cookie change (`SameSite=None`) was considered and rejected: it attaches the
|
|
110
|
+
cookie to every cross-site request to the Connect domain, including subresource
|
|
111
|
+
GETs that carry no `Origin` header for bb's own origin checks to reject.
|
|
112
|
+
|
|
113
|
+
### How to verify it is no longer needed
|
|
114
|
+
|
|
115
|
+
Write a file beside `index.html`, reference it relatively, disable the
|
|
116
|
+
workaround, and read the page **over bb Connect on a phone or with devtools on
|
|
117
|
+
the remote origin** — never on loopback, where it has always worked. This is
|
|
118
|
+
the acceptance criterion `verify/` is missing.
|
|
119
|
+
|
|
120
|
+
### What to delete
|
|
121
|
+
|
|
122
|
+
1. `src/pages/inline.ts` and `test/pages/inline.test.ts`.
|
|
123
|
+
2. The `resolve` argument to `createPageStore` in `src/plugin.ts`, and the
|
|
124
|
+
`PageResolver` type, the `site` field on `LoadedPage`, and the resolve block
|
|
125
|
+
in `PageStore.load` in `src/pages/page-store.ts`.
|
|
126
|
+
3. `inlineFileBytes`, `inlineTotalBytes` and `inlineCssDepth` from
|
|
127
|
+
`src/domain/limits.ts`.
|
|
128
|
+
4. The "How this actually works" block in `ownFiles()` and the added row in
|
|
129
|
+
`limitations()` in `src/agent/guide.ts`, plus the guide tests asserting them.
|
|
130
|
+
5. This document.
|
|
131
|
+
|
|
132
|
+
Keep the offline-copy warning in `page-store.ts`. It was always right; the
|
|
133
|
+
workaround only made it matter sooner.
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Thread Pages 1.1 — for an agent that already has a page
|
|
2
|
+
|
|
3
|
+
You are reading this because your session has a page you wrote against 1.0.x.
|
|
4
|
+
Nothing you wrote has broken. Some things you were told were impossible are now
|
|
5
|
+
possible, one workaround you were told to use is no longer needed, and two
|
|
6
|
+
things in your page are worth fixing while you are here.
|
|
7
|
+
|
|
8
|
+
Run `bb thread-page guide` for the full current contract. This file is only the
|
|
9
|
+
difference.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Your page's own files work now — on the reader's phone, not just yours
|
|
14
|
+
|
|
15
|
+
**What you were told in 1.0:** subresources "load normally", and `fetch()` of
|
|
16
|
+
your own files is refused.
|
|
17
|
+
|
|
18
|
+
**What was actually true:** a file beside `index.html` loaded on loopback and
|
|
19
|
+
was **refused on any authenticated origin**, including bb Connect, which is how
|
|
20
|
+
your reader opens the page on a phone. Your page rendered; its stylesheet and
|
|
21
|
+
data did not; nothing errored. If you built anything that reads a file beside
|
|
22
|
+
`index.html`, it has probably been silently empty for your reader this whole
|
|
23
|
+
time, and you could not have seen it from your own machine.
|
|
24
|
+
|
|
25
|
+
**What is true now:** the host resolves every relative reference when it serves
|
|
26
|
+
the document and rewrites it to a `data:` URL. Write the reference; it works on
|
|
27
|
+
every origin.
|
|
28
|
+
|
|
29
|
+
<link rel="stylesheet" href="page.css">
|
|
30
|
+
<script src="data.js"></script>
|
|
31
|
+
<img src="figures/chart.png" alt="…">
|
|
32
|
+
|
|
33
|
+
`url()` inside a stylesheet you reference is followed too, so backgrounds and
|
|
34
|
+
`@font-face` survive.
|
|
35
|
+
|
|
36
|
+
### What to do about it
|
|
37
|
+
|
|
38
|
+
**If you inlined data into `index.html` because the guide told you to** — move
|
|
39
|
+
it back out. `<script src="data.js">` works, and it makes your entry document
|
|
40
|
+
small again, which makes it cheap to edit.
|
|
41
|
+
|
|
42
|
+
**If your page has a file beside it and shows zeroes** — that was this bug. It
|
|
43
|
+
should be right now; no change needed on your side.
|
|
44
|
+
|
|
45
|
+
## 2. You can publish new data without rewriting `index.html`
|
|
46
|
+
|
|
47
|
+
Changing a file beside `index.html` changes the served document, so an open page
|
|
48
|
+
reloads within about ten seconds. That is the whole live-data mechanism: write
|
|
49
|
+
`data.js`, the reader's page updates.
|
|
50
|
+
|
|
51
|
+
Two things to get right, both in the guide under *Keeping a page's data current*:
|
|
52
|
+
|
|
53
|
+
- **Make the write deterministic.** An unchanged data set must produce a
|
|
54
|
+
byte-identical file. A generated timestamp in the payload turns every rebuild
|
|
55
|
+
into a reload for every reader, and your page will look like it is flickering
|
|
56
|
+
for no reason.
|
|
57
|
+
- **Call `setDirty(true)`** while the reader is mid-edit in state the host
|
|
58
|
+
cannot see. Captured forms do this for you; your own widgets do not.
|
|
59
|
+
|
|
60
|
+
## 3. Your files now count against the document's size
|
|
61
|
+
|
|
62
|
+
Because they are carried inside the document:
|
|
63
|
+
|
|
64
|
+
| | |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| Entry document | 5 MiB, including everything it carries |
|
|
67
|
+
| Per file | 2 MiB |
|
|
68
|
+
| All files together | 3 MiB |
|
|
69
|
+
| Offline copy kept | only under 200 KiB total |
|
|
70
|
+
| base64 | adds a third to all of the above |
|
|
71
|
+
|
|
72
|
+
A file that is missing, too large or over the budget is **left exactly as you
|
|
73
|
+
wrote it** and named in the log — `bb plugin logs thread-pages`. Your page still
|
|
74
|
+
renders; that one reference does not resolve. Check the log once after you
|
|
75
|
+
publish; it is the only place this is reported.
|
|
76
|
+
|
|
77
|
+
If your page carries a large dataset and you care about it opening offline, keep
|
|
78
|
+
the document under 200 KiB. The host now warns in the log when it drops the
|
|
79
|
+
offline copy instead of dropping it silently.
|
|
80
|
+
|
|
81
|
+
## 4. `[hidden]` — fix this in your page by hand
|
|
82
|
+
|
|
83
|
+
A class rule that sets `display` outranks the user-agent rule for the `hidden`
|
|
84
|
+
attribute, so `<p class="banner" hidden>` rendered as an empty coloured bar. New
|
|
85
|
+
pages get the fix in their seeded stylesheet. **Your page carries its own copy of
|
|
86
|
+
the stylesheet and will not get it.** Add this to your `<style>`:
|
|
87
|
+
|
|
88
|
+
[hidden] { display: none !important; }
|
|
89
|
+
|
|
90
|
+
If you have ever written `hidden` on an element and been confused by a stray
|
|
91
|
+
empty bar in a screenshot, this was why.
|
|
92
|
+
|
|
93
|
+
## 5. Delete the old seed comment from your page
|
|
94
|
+
|
|
95
|
+
The 1.0 seed's authoring comment spelled HTML tags out literally — `<main>`,
|
|
96
|
+
`<style>`, `<script src="app.js">`. They are comment text, not elements, but
|
|
97
|
+
every string operation you run on your own file sees them. A structural check on
|
|
98
|
+
a healthy page reports two `<main>` elements and one unclosed `<script>`, and
|
|
99
|
+
`indexOf("<main>")` finds the comment before the real element, so the obvious
|
|
100
|
+
splice starts in the wrong place.
|
|
101
|
+
|
|
102
|
+
**If that comment is still in your `index.html`, delete it or rewrite it without
|
|
103
|
+
angle brackets.** It is costing you every time you edit your page. The current
|
|
104
|
+
seed names no tags at all.
|
|
105
|
+
|
|
106
|
+
## 6. Edit your page by rewriting it, not by splicing
|
|
107
|
+
|
|
108
|
+
There is no page-editing command and there is not meant to be one: `index.html`
|
|
109
|
+
is a file in your storage directory that you read and write with your ordinary
|
|
110
|
+
tools. **Nothing in it is reserved** — not the stylesheet, not the header, not
|
|
111
|
+
the comment it came with. Rewrite the whole document. A splice computed from
|
|
112
|
+
string indices can silently eat content; a whole-document write cannot.
|
|
113
|
+
|
|
114
|
+
This got much cheaper in 1.1: with §1 fixed, your stylesheet can live in
|
|
115
|
+
`page.css` instead of taking up 27 KB of the file you are rewriting.
|
|
116
|
+
|
|
117
|
+
## 7. If your page should stay put, it must not carry a form
|
|
118
|
+
|
|
119
|
+
A page nobody should have to rewrite — a dashboard, a console — holds no
|
|
120
|
+
captured `<form>`, because a form messages your session and something then has
|
|
121
|
+
to rewrite the page. Its buttons should call `sessions.start` and `pages.open`
|
|
122
|
+
instead. The 1.0 seed shipped a reply form, which read as an endorsement of the
|
|
123
|
+
wrong default; the current seed says to delete it.
|
|
124
|
+
|
|
125
|
+
**A page may now also be build output** — a script generating it from
|
|
126
|
+
version-controlled source is legitimate. The rule that does not bend: the page
|
|
127
|
+
still has one owning session, and that session's agent builds it the first time.
|
|
128
|
+
A page with no agent behind it is a page nobody can be asked to change.
|
|
129
|
+
|
|
130
|
+
## 8. If you call a 0.3.x method, the error now tells you the new name
|
|
131
|
+
|
|
132
|
+
Unknown capability: threads.spawn (renamed to sessions.start in 1.0; there is no alias)
|
|
133
|
+
|
|
134
|
+
The full table is in `docs/UPGRADING.md`. There are still no aliases; the old
|
|
135
|
+
name still fails.
|
|
136
|
+
|
|
137
|
+
## 9. Before you save, read it over the reader's real origin
|
|
138
|
+
|
|
139
|
+
The old checklist covered 320px, dark mode and reduced motion — all things you
|
|
140
|
+
can check locally. It missed the only axis where behaviour actually differs:
|
|
141
|
+
**authentication.** A local bb requires no credential and a remote one does.
|
|
142
|
+
Read your page once over bb Connect, not only loopback. That is what would have
|
|
143
|
+
caught §1 two days earlier.
|
|
144
|
+
|
|
145
|
+
## What is still not possible
|
|
146
|
+
|
|
147
|
+
Unchanged in 1.1, so do not spend time on them:
|
|
148
|
+
|
|
149
|
+
- `fetch("data.json")` of your own file from page script. Only references in the
|
|
150
|
+
document are resolved. Use `<script src="data.js">` or inline it.
|
|
151
|
+
- Embedding another page or site in an `<iframe>` (`frame-src 'none'`).
|
|
152
|
+
- `window.open`, `window.prompt`, `alert`, `confirm`, top-level navigation.
|
|
153
|
+
- Reading a file from the project your session belongs to.
|
|
154
|
+
- Reading or writing another agent's page, and any registry that would let one
|
|
155
|
+
page list itself on another. If two pages should look alike, read the other
|
|
156
|
+
page and copy from it.
|
|
157
|
+
- `voice.captureAndTranscribe`.
|
|
158
|
+
|
|
159
|
+
## A five-minute pass over your page
|
|
160
|
+
|
|
161
|
+
1. `bb thread-page init` — confirm it still says EXISTING and prints no warning.
|
|
162
|
+
2. Add `[hidden] { display: none !important; }` to your `<style>` (§4).
|
|
163
|
+
3. Delete the old seed comment if it is still there (§5).
|
|
164
|
+
4. If you inlined data to work around §1, move it into a file beside the page.
|
|
165
|
+
5. If the page should stay put, remove any captured `<form>` (§7).
|
|
166
|
+
6. `bb plugin logs thread-pages` — check nothing of yours failed to resolve (§3).
|
|
167
|
+
7. Read it once over bb Connect, on a phone if you can (§9).
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Upgrading
|
|
2
|
+
|
|
3
|
+
## 0.3.x → 1.0
|
|
4
|
+
|
|
5
|
+
1.0.0 was a rewrite against the specification, and it renamed the whole
|
|
6
|
+
page-facing surface at once. Nothing is aliased: an old name fails rather than
|
|
7
|
+
silently doing the right thing. A page written against 0.3.x therefore breaks
|
|
8
|
+
in several places at the same time, each of them quietly.
|
|
9
|
+
|
|
10
|
+
| 0.3.x | 1.0 |
|
|
11
|
+
| --- | --- |
|
|
12
|
+
| `thread-page.html` | `index.html` |
|
|
13
|
+
| `thread-page-assets/` | any file beside the entry document, nested paths included |
|
|
14
|
+
| `threads.spawn` | `sessions.start` |
|
|
15
|
+
| `threads.snapshot` | `sessions.snapshot` |
|
|
16
|
+
| `threads.send` | `sessions.send` |
|
|
17
|
+
| `threads.stop` | `sessions.stop` |
|
|
18
|
+
| `threads.archive` | `sessions.archive` |
|
|
19
|
+
| `threads.openPage` | `pages.open` |
|
|
20
|
+
| `threads.openBb` | `sessions.openHost` |
|
|
21
|
+
| `thread.get` | `context.get` |
|
|
22
|
+
| `thread.reply` / `threads.reply` | `session.reply` |
|
|
23
|
+
| `thread.activity` / `threads.activity` | `session.activity` |
|
|
24
|
+
| `page.storage.get` / `page.storage.set` | `storage.get` / `storage.set` |
|
|
25
|
+
| `navigation.open` | `navigation.openExternal` |
|
|
26
|
+
| `homeThreadId` (plugin setting) | `homeSessionId` (`bb thread-page status`) |
|
|
27
|
+
| `window.threadPage.assetUrl()` | removed — the API is frozen at `invoke` / `watch` / `setDirty` / `version` |
|
|
28
|
+
|
|
29
|
+
### The two that cost the most
|
|
30
|
+
|
|
31
|
+
**The entry document was renamed.** `thread-page.html` is not served and not
|
|
32
|
+
migrated. A session that had a page looks like a session that never had one.
|
|
33
|
+
`bb thread-page init` notices the old file and says so; move what you want out
|
|
34
|
+
of it by hand.
|
|
35
|
+
|
|
36
|
+
**`assetUrl()` was removed rather than deprecated**, so a page that calls it
|
|
37
|
+
throws instead of degrading. Reference files relatively instead.
|
|
38
|
+
|
|
39
|
+
### What the host tells you now
|
|
40
|
+
|
|
41
|
+
Calling a renamed method returns `unknown_method` with the replacement named:
|
|
42
|
+
|
|
43
|
+
Unknown capability: threads.spawn (renamed to sessions.start in 1.0; there is no alias)
|
|
44
|
+
|
|
45
|
+
The table above is the complete list the host recognises; see
|
|
46
|
+
`src/domain/capabilities/renamed.ts`.
|
|
47
|
+
|
|
48
|
+
### Not a rename
|
|
49
|
+
|
|
50
|
+
`sessions.snapshot` also changed behaviour in 1.0.2: it lists root sessions
|
|
51
|
+
only unless you pass `includeChildren: true`, and every session now carries
|
|
52
|
+
`unread` and `attentionAtMs`. Check `bb thread-page guide` for the current
|
|
53
|
+
shape rather than assuming the 0.3.x one.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unifedev/thread-pages",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Thread Pages for bb: every agent session gets one directly editable HTML page you can answer from, on any device.",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Thread Pages for bb: every agent session gets one directly editable HTML page you can read and answer from, on any device.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bartosz",
|
|
7
7
|
"repository": {
|
|
@@ -23,42 +23,50 @@
|
|
|
23
23
|
"type": "module",
|
|
24
24
|
"private": false,
|
|
25
25
|
"engines": {
|
|
26
|
-
"bb": ">=0.
|
|
27
|
-
"bbPluginSdk": ">=0.4.
|
|
26
|
+
"bb": ">=0.42",
|
|
27
|
+
"bbPluginSdk": ">=0.4.47"
|
|
28
28
|
},
|
|
29
29
|
"scripts": {
|
|
30
|
-
"build": "
|
|
30
|
+
"build:runtime": "node scripts/build-runtime.mjs",
|
|
31
|
+
"build": "npm run build:runtime && bb plugin build",
|
|
31
32
|
"test": "vitest run",
|
|
32
|
-
"typecheck": "tsc --noEmit"
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"check": "npm run build:runtime && npm run typecheck && npm test"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"parse5": "^8.0.1"
|
|
33
38
|
},
|
|
34
39
|
"devDependencies": {
|
|
35
|
-
"@get-bb/plugin-sdk": "0.4.47",
|
|
40
|
+
"@get-bb/plugin-sdk": "^0.4.47",
|
|
41
|
+
"@types/better-sqlite3": "^7.6.12",
|
|
42
|
+
"@types/jsdom": "^21.1.7",
|
|
36
43
|
"@types/node": "^22.10.0",
|
|
37
|
-
"bb-app": "0.
|
|
44
|
+
"bb-app": "0.42.1",
|
|
45
|
+
"better-sqlite3": "^12.0.0",
|
|
38
46
|
"cron-parser": "^5.5.0",
|
|
47
|
+
"esbuild": "^0.28.2",
|
|
48
|
+
"hono": "^4.13.7",
|
|
49
|
+
"jsdom": "^30.0.1",
|
|
39
50
|
"typescript": "^5.7.2",
|
|
40
|
-
"vitest": "^
|
|
51
|
+
"vitest": "^5.0.0",
|
|
52
|
+
"zod": "^4.3.6"
|
|
41
53
|
},
|
|
42
54
|
"bb": {
|
|
43
55
|
"name": "Thread Pages",
|
|
44
|
-
"description": "Host one directly editable HTML
|
|
56
|
+
"description": "Host one directly editable HTML page per session, served as a site the reader can answer from.",
|
|
45
57
|
"branding": {
|
|
46
58
|
"icon": "FileText"
|
|
47
59
|
},
|
|
48
60
|
"server": "./server.ts",
|
|
49
61
|
"skills": []
|
|
50
62
|
},
|
|
51
|
-
"dependencies": {
|
|
52
|
-
"parse5": "^8.0.1"
|
|
53
|
-
},
|
|
54
63
|
"files": [
|
|
55
|
-
"
|
|
56
|
-
"
|
|
64
|
+
"server.ts",
|
|
65
|
+
"src/**/*.ts",
|
|
66
|
+
"!src/**/*.test.ts",
|
|
57
67
|
"dist/server.js",
|
|
58
68
|
"dist/server.meta.json",
|
|
59
|
-
"docs
|
|
60
|
-
"ARCHITECTURE.md",
|
|
61
|
-
"PLUGIN_OVERVIEW.md",
|
|
69
|
+
"docs/*.md",
|
|
62
70
|
"README.md",
|
|
63
71
|
"tsconfig.json",
|
|
64
72
|
"package-lock.json"
|