@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.
Files changed (95) hide show
  1. package/README.md +77 -129
  2. package/dist/server.js +11779 -11801
  3. package/dist/server.meta.json +2 -2
  4. package/docs/B1-OWN-FILES.md +133 -0
  5. package/docs/FOR-PAGE-AUTHORS-1.1.md +167 -0
  6. package/docs/UPGRADING.md +53 -0
  7. package/package.json +26 -18
  8. package/server.ts +3 -2175
  9. package/src/agent/cli.ts +193 -0
  10. package/src/agent/guide.ts +450 -0
  11. package/src/agent/instruction.ts +59 -0
  12. package/src/agent/seed/seed.ts +73 -0
  13. package/{theme.ts → src/agent/seed/theme-css.ts} +9 -11
  14. package/src/agent/starter-hub.ts +217 -0
  15. package/src/bb/activity.ts +59 -0
  16. package/src/bb/bb-host.ts +280 -0
  17. package/src/bb/public-origin.ts +45 -0
  18. package/src/config/settings.ts +82 -0
  19. package/src/domain/capabilities/contract.ts +48 -0
  20. package/src/domain/capabilities/index.ts +10 -0
  21. package/src/domain/capabilities/protocol.ts +113 -0
  22. package/src/domain/capabilities/registry.ts +48 -0
  23. package/src/domain/capabilities/renamed.ts +34 -0
  24. package/src/domain/capabilities/schema.ts +198 -0
  25. package/src/domain/capabilities/specs.ts +479 -0
  26. package/src/domain/eligibility.ts +43 -0
  27. package/src/domain/errors.ts +116 -0
  28. package/src/domain/html/document.ts +109 -0
  29. package/src/domain/html/escape.ts +16 -0
  30. package/src/domain/ids.ts +37 -0
  31. package/src/domain/json/canonical.ts +19 -0
  32. package/src/domain/json/strict-json.ts +139 -0
  33. package/src/domain/limits.ts +98 -0
  34. package/src/domain/rate-limit.ts +64 -0
  35. package/src/domain/revision.ts +27 -0
  36. package/src/domain/submissions/idempotency.ts +59 -0
  37. package/src/domain/submissions/message.ts +42 -0
  38. package/src/domain/submissions/parse.ts +105 -0
  39. package/src/domain/tokens/action-token.ts +52 -0
  40. package/src/domain/tokens/confirmation.ts +99 -0
  41. package/src/domain/tokens/mac.ts +50 -0
  42. package/src/generated/kernel-runtime.ts +3 -0
  43. package/src/generated/shell-runtime.ts +3 -0
  44. package/src/host/contract.ts +65 -0
  45. package/src/host/types.ts +89 -0
  46. package/src/pages/inline.ts +277 -0
  47. package/src/pages/layout.ts +65 -0
  48. package/src/pages/page-store.ts +170 -0
  49. package/src/pages/site.ts +36 -0
  50. package/src/plugin.ts +81 -0
  51. package/src/runtime/kernel/anchors.ts +45 -0
  52. package/src/runtime/kernel/api.ts +15 -0
  53. package/src/runtime/kernel/bridge-client.ts +148 -0
  54. package/src/runtime/kernel/dirty.ts +51 -0
  55. package/src/runtime/kernel/forms.ts +114 -0
  56. package/src/runtime/kernel/install.ts +156 -0
  57. package/src/runtime/kernel/labels.ts +98 -0
  58. package/src/runtime/kernel/main.ts +6 -0
  59. package/src/runtime/kernel/readonly.ts +75 -0
  60. package/src/runtime/shared/protocol.ts +125 -0
  61. package/src/runtime/shell/confirm.ts +70 -0
  62. package/src/runtime/shell/install.ts +79 -0
  63. package/src/runtime/shell/main.ts +12 -0
  64. package/src/runtime/shell/navigate.ts +64 -0
  65. package/src/runtime/shell/poll.ts +125 -0
  66. package/src/runtime/shell/relay.ts +185 -0
  67. package/src/serving/action-request.ts +32 -0
  68. package/src/serving/bridge/dispatcher.ts +112 -0
  69. package/src/serving/bridge/handler.ts +37 -0
  70. package/src/serving/bridge/handlers/index.ts +26 -0
  71. package/src/serving/bridge/handlers/navigation.ts +43 -0
  72. package/src/serving/bridge/handlers/reads.ts +186 -0
  73. package/src/serving/bridge/handlers/writes.ts +175 -0
  74. package/src/serving/bridge/selection-store.ts +58 -0
  75. package/src/serving/bridge-route.ts +23 -0
  76. package/src/serving/context.ts +34 -0
  77. package/src/serving/document-route.ts +37 -0
  78. package/src/serving/home-route.ts +23 -0
  79. package/src/serving/responses.ts +81 -0
  80. package/src/serving/routes.ts +26 -0
  81. package/src/serving/session-access.ts +22 -0
  82. package/src/serving/shell-html.ts +77 -0
  83. package/src/serving/shell-route.ts +51 -0
  84. package/src/serving/signing-key.ts +25 -0
  85. package/src/serving/submit-route.ts +47 -0
  86. package/src/serving/upload-route.ts +46 -0
  87. package/tsconfig.json +10 -6
  88. package/ARCHITECTURE.md +0 -230
  89. package/PLUGIN_OVERVIEW.md +0 -83
  90. package/authoring.ts +0 -368
  91. package/bridge.ts +0 -1721
  92. package/docs/MODEL.md +0 -211
  93. package/docs/ROADMAP.md +0 -96
  94. package/home.ts +0 -419
  95. package/page.ts +0 -782
@@ -3,9 +3,9 @@
3
3
  "sdkVersion": "0.4.47",
4
4
  "artifactFormatVersion": 1,
5
5
  "pluginId": "thread-pages",
6
- "pluginVersion": "0.3.2",
6
+ "pluginVersion": "1.1.0",
7
7
  "builtWith": {
8
- "bbVersion": "0.40.0",
8
+ "bbVersion": "0.42.1",
9
9
  "pluginSdkVersion": "0.4.47"
10
10
  }
11
11
  }
@@ -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": "0.3.2",
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.40",
27
- "bbPluginSdk": ">=0.4.21"
26
+ "bb": ">=0.42",
27
+ "bbPluginSdk": ">=0.4.47"
28
28
  },
29
29
  "scripts": {
30
- "build": "bb plugin 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.40.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": "^3.0.0"
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 mini-app for each thread.",
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
- "*.ts",
56
- "!*.test.ts",
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"