Skip to content

Commit d24722b

Browse files
michielbdejongMichiel de Jong
andauthored
Run LocalThought integrations entirely in the browser (#1401)
* Run LocalThought integrations entirely in the browser * Run focused Pets E2E on the browser integration branch * Add browser Devonian issue tracker sync demo (#1399) * Add browser Devonian issue tracker sync demo * Use browser tenant connections and test two-way issue sync * Record live proxy OAuth verification and repository access blocker * Run one-way Google Calendar sync entirely in the browser (#1398) * Show one-way Google Calendar imports in a calendar view * Verify browser-only Calendar sync through shared mock proxy --------- Co-authored-by: Michiel de Jong <michielbdejong@ontola.io> --------- Co-authored-by: Michiel de Jong <michielbdejong@ontola.io> --------- Co-authored-by: Michiel de Jong <michielbdejong@ontola.io>
1 parent 0ac45b6 commit d24722b

95 files changed

Lines changed: 10660 additions & 1049 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dagger/src/index.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,10 @@ export class AtomicServer {
636636
this.source.directory('plugin-runtime'),
637637
)
638638
.withDirectory('/code/wasm', this.source.directory('wasm'))
639+
.withDirectory(
640+
'/code/integrations/localthought/syncables',
641+
this.source.directory('integrations/localthought/syncables'),
642+
)
639643
.withDirectory('/code/server', this.source.directory('server'))
640644
.withDirectory('/code/cli', this.source.directory('cli'))
641645
.withDirectory('/code/desktop', this.source.directory('desktop'))
@@ -713,6 +717,10 @@ export class AtomicServer {
713717
.withDirectory('/code/cli', this.source.directory('cli'))
714718
.withDirectory('/code/desktop', this.source.directory('desktop'))
715719
.withDirectory('/code/wasm', this.source.directory('wasm'))
720+
.withDirectory(
721+
'/code/integrations/localthought/syncables',
722+
this.source.directory('integrations/localthought/syncables'),
723+
)
716724
.withDirectory(
717725
'/code/plugin-examples',
718726
this.source.directory('plugin-examples'),
@@ -1127,7 +1135,9 @@ export class AtomicServer {
11271135
// Surfaces /app/dev-drive and /app/prunetests in the production
11281136
// build the e2e tests run against. See `devRoutesEnabled()` in
11291137
// data-browser/src/config.ts.
1130-
buildContainer = buildContainer.withEnvVariable('VITE_E2E', 'true');
1138+
buildContainer = buildContainer
1139+
.withEnvVariable('VITE_E2E', 'true')
1140+
.withEnvVariable('VITE_INTEGRATION_PROXY_URL', 'http://127.0.0.1:19090');
11311141
}
11321142

11331143
return buildContainer.withExec(['pnpm', 'run', 'build']);
@@ -1182,6 +1192,10 @@ export class AtomicServer {
11821192
.withDirectory('/code/cli', source.directory('cli'))
11831193
.withDirectory('/code/desktop', source.directory('desktop'))
11841194
.withDirectory('/code/wasm', source.directory('wasm'))
1195+
.withDirectory(
1196+
'/code/integrations/localthought/syncables',
1197+
source.directory('integrations/localthought/syncables'),
1198+
)
11851199
.withDirectory(
11861200
'/code/plugin-examples',
11871201
source.directory('plugin-examples'),
@@ -1380,6 +1394,10 @@ export class AtomicServer {
13801394
.withDirectory('/code/cli', source.directory('cli'))
13811395
.withDirectory('/code/desktop', source.directory('desktop'))
13821396
.withDirectory('/code/wasm', source.directory('wasm'))
1397+
.withDirectory(
1398+
'/code/integrations/localthought/syncables',
1399+
source.directory('integrations/localthought/syncables'),
1400+
)
13831401
.withDirectory(
13841402
'/code/plugin-examples',
13851403
source.directory('plugin-examples'),

.github/workflows/pets-e2e.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: LocalThought API plugins E2E
22

33
on:
44
push:
5-
branches: [feat/api-plugins, codex/localthought-api-plugins]
5+
branches: [feat/api-plugins, codex/localthought-api-plugins, codex/browser-integrations]
66

77
permissions:
88
contents: read

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ members = [
1414
"plugin-runtime",
1515
"tools/cargo-bin",
1616
]
17-
exclude = ["flutter/rust"]
17+
exclude = ["flutter/rust", "integrations/localthought/syncables"]
1818

1919
# Debuginfo dominates target/ size: with ~1460 deps (tauri, actix, iroh) the
2020
# default `debug = true` produces a multi-GB tree per build flavor, and this

TESTING_COVERAGE.md

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,36 @@
11
# Testing coverage map
22

3+
LocalThought browser migration: `integrations/localthought/browser.test.ts`
4+
covers tenant HMAC, actor/drive ownership, rotation before dispatch, pagination,
5+
uncertain-response refusal and cross-origin pagination refusal. The real generated
6+
WASM bundle is exercised by `wasm-smoke.mjs` for pagination, typed ontology,
7+
timestamps and provider failures. `browser-smoke.mjs` exercises the complete
8+
mock consent/import/review/OPFS/reload journey with AtomicServer unavailable
9+
(verified locally). Local installation/schema lookup tests reject missing or
10+
incomplete local databases rather than inferring permission to create duplicates.
11+
The companion Syncables branch has 142 passing native tests and a wasm32 build;
12+
the companion proxy branch has 39 passing tests including CORS preflight and
13+
exposed headers. Live OAuth on the browser path still requires deployment of
14+
the companion proxy CORS change and is not yet verified.
15+
16+
`browser/e2e/tests/devonian-issue-sync.spec.mts` exercises tenant-secret entry,
17+
proxy consent, direct HTTP writes and local OPFS storage for two-way issue
18+
creation, comments, close/reopen and reload without duplicate resources. Its
19+
stateful HTTP mock isolates repositories and consumes/rotates connection codes;
20+
it does not substitute the in-page sample transport.
21+
22+
The browser-only Devonian issue tracker demo has focused tests under
23+
`integrations/github-issues/devonian`: real Devonian lenses with deterministic
24+
connectors exercise bidirectional issue/comment creation and edits, close/reopen,
25+
distinct identical resources, conflicts, missing records and restart/replay.
26+
Transport fixtures cover pagination, label preservation, scoped comment links,
27+
rotating connection codes and refusal to resend uncertain writes. The native
28+
OPFS browser flow was manually verified for creation and comments on both sides,
29+
closing from Atomic, reopening from the sample GitHub side and reloading without
30+
duplicate issues/comments. Live proxy OAuth,
31+
GitHub writes and a guided uncertain-write recovery UI remain unverified/unbuilt;
32+
proxy v40 CORS and browser OAuth are verified, but its GitHub credential returns 404 for the private sandbox.
33+
334
What is tested, at which layer, and — the part that matters — **what is not**.
435

536
This exists because the protocol is far better tested than the glue around it,
@@ -65,12 +96,12 @@ return to the same drive, rotating connection codes, two-page Syncables fetch,
6596
review/apply, and five displayed records with integer/boolean/float/timestamp
6697
properties. Dagger starts the mock for E2E; local runs opt in with
6798
`ATOMIC_MOCK_INTEGRATION_PROXY=1` and the README configuration.
68-
`integration_proxy` Rust tests cover actor/drive binding, tenant HMAC,
99+
`browser.test.ts` and the real WASM smoke cover actor/drive binding, tenant HMAC,
69100
Syncables pagination/ontology and duplicate-page refusal. The mock's Node test
70101
covers invalid tenant proofs and replayed/rotated codes. The mapping tests cover
71102
typed proposals, missing identities, repeat imports, local edits and duplicates.
72-
Live catalog OAD endpoints currently return 404 (integration-proxy #25), so live
73-
OAuth and GitHub data fetching are not yet certified.
103+
The historical server path was live-verified for GitHub and Google Calendar.
104+
The new browser path awaits deployment of the companion proxy CORS change.
74105
Run it against a production build to catch missing translation catalog entries:
75106
Vite dev extracts them automatically and can hide blank production labels.
76107
The GitHub setup flow also covers opting into assistant-led automation creation:
@@ -1053,3 +1084,15 @@ cancelled on teardown. Old plugin-name grants are deliberately not migrated.
10531084
commit. It failed with the server signer before `Resource::destroy_as` was used;
10541085
installation deletion must use the same selected identity as create/update.
10551086
LocalThought: Rust handler tests cover connection binding, request signing, duplicate-page rejection, typed paginated previews, and Calendar UTC date-range validation. Live Calendar OAuth, bounded fetch, review/apply and event table display were verified against proxy v39 (54 records).
1087+
1088+
Google Calendar one-way projection: `integrations/localthought/calendar.test.ts`
1089+
covers all-day/timed start dates, offset boundaries, exclusive end preservation,
1090+
feature notes (including WASM-normalized field names), cancellations without
1091+
start data, invalid active events, namespace isolation and repeat import/local
1092+
field preservation. `browser/e2e/tests/google-calendar-import.spec.mts` uses the
1093+
shared HTTP mock integration-proxy with a paginated Google Calendar, tenant
1094+
secret entry and OAuth consent. It covers browser WASM fetching, local
1095+
schema/proposal/apply, Calendar display, provider updates, OPFS reload and
1096+
stable identities while AtomicServer HTTP/WebSockets are unavailable. Missing
1097+
rows in a bounded snapshot are retained, not interpreted as deletions.
1098+
Live-provider browser OAuth verification remains separate from this fixture test.

0 commit comments

Comments
 (0)