Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .dagger/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,10 @@ export class AtomicServer {
this.source.directory('plugin-runtime'),
)
.withDirectory('/code/wasm', this.source.directory('wasm'))
.withDirectory(
'/code/integrations/localthought/syncables',
this.source.directory('integrations/localthought/syncables'),
)
.withDirectory('/code/server', this.source.directory('server'))
.withDirectory('/code/cli', this.source.directory('cli'))
.withDirectory('/code/desktop', this.source.directory('desktop'))
Expand Down Expand Up @@ -713,6 +717,10 @@ export class AtomicServer {
.withDirectory('/code/cli', this.source.directory('cli'))
.withDirectory('/code/desktop', this.source.directory('desktop'))
.withDirectory('/code/wasm', this.source.directory('wasm'))
.withDirectory(
'/code/integrations/localthought/syncables',
this.source.directory('integrations/localthought/syncables'),
)
.withDirectory(
'/code/plugin-examples',
this.source.directory('plugin-examples'),
Expand Down Expand Up @@ -1127,7 +1135,9 @@ export class AtomicServer {
// Surfaces /app/dev-drive and /app/prunetests in the production
// build the e2e tests run against. See `devRoutesEnabled()` in
// data-browser/src/config.ts.
buildContainer = buildContainer.withEnvVariable('VITE_E2E', 'true');
buildContainer = buildContainer
.withEnvVariable('VITE_E2E', 'true')
.withEnvVariable('VITE_INTEGRATION_PROXY_URL', 'http://127.0.0.1:19090');
}

return buildContainer.withExec(['pnpm', 'run', 'build']);
Expand Down Expand Up @@ -1182,6 +1192,10 @@ export class AtomicServer {
.withDirectory('/code/cli', source.directory('cli'))
.withDirectory('/code/desktop', source.directory('desktop'))
.withDirectory('/code/wasm', source.directory('wasm'))
.withDirectory(
'/code/integrations/localthought/syncables',
source.directory('integrations/localthought/syncables'),
)
.withDirectory(
'/code/plugin-examples',
source.directory('plugin-examples'),
Expand Down Expand Up @@ -1380,6 +1394,10 @@ export class AtomicServer {
.withDirectory('/code/cli', source.directory('cli'))
.withDirectory('/code/desktop', source.directory('desktop'))
.withDirectory('/code/wasm', source.directory('wasm'))
.withDirectory(
'/code/integrations/localthought/syncables',
source.directory('integrations/localthought/syncables'),
)
.withDirectory(
'/code/plugin-examples',
source.directory('plugin-examples'),
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pets-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: LocalThought API plugins E2E

on:
push:
branches: [feat/api-plugins, codex/localthought-api-plugins]
branches: [feat/api-plugins, codex/localthought-api-plugins, codex/browser-integrations]

permissions:
contents: read
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ members = [
"plugin-runtime",
"tools/cargo-bin",
]
exclude = ["flutter/rust"]
exclude = ["flutter/rust", "integrations/localthought/syncables"]

# Debuginfo dominates target/ size: with ~1460 deps (tauri, actix, iroh) the
# default `debug = true` produces a multi-GB tree per build flavor, and this
Expand Down
49 changes: 46 additions & 3 deletions TESTING_COVERAGE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
# Testing coverage map

LocalThought browser migration: `integrations/localthought/browser.test.ts`
covers tenant HMAC, actor/drive ownership, rotation before dispatch, pagination,
uncertain-response refusal and cross-origin pagination refusal. The real generated
WASM bundle is exercised by `wasm-smoke.mjs` for pagination, typed ontology,
timestamps and provider failures. `browser-smoke.mjs` exercises the complete
mock consent/import/review/OPFS/reload journey with AtomicServer unavailable
(verified locally). Local installation/schema lookup tests reject missing or
incomplete local databases rather than inferring permission to create duplicates.
The companion Syncables branch has 142 passing native tests and a wasm32 build;
the companion proxy branch has 39 passing tests including CORS preflight and
exposed headers. Live OAuth on the browser path still requires deployment of
the companion proxy CORS change and is not yet verified.

`browser/e2e/tests/devonian-issue-sync.spec.mts` exercises tenant-secret entry,
proxy consent, direct HTTP writes and local OPFS storage for two-way issue
creation, comments, close/reopen and reload without duplicate resources. Its
stateful HTTP mock isolates repositories and consumes/rotates connection codes;
it does not substitute the in-page sample transport.

The browser-only Devonian issue tracker demo has focused tests under
`integrations/github-issues/devonian`: real Devonian lenses with deterministic
connectors exercise bidirectional issue/comment creation and edits, close/reopen,
distinct identical resources, conflicts, missing records and restart/replay.
Transport fixtures cover pagination, label preservation, scoped comment links,
rotating connection codes and refusal to resend uncertain writes. The native
OPFS browser flow was manually verified for creation and comments on both sides,
closing from Atomic, reopening from the sample GitHub side and reloading without
duplicate issues/comments. Live proxy OAuth,
GitHub writes and a guided uncertain-write recovery UI remain unverified/unbuilt;
proxy v40 CORS and browser OAuth are verified, but its GitHub credential returns 404 for the private sandbox.

What is tested, at which layer, and — the part that matters — **what is not**.

This exists because the protocol is far better tested than the glue around it,
Expand Down Expand Up @@ -65,12 +96,12 @@ return to the same drive, rotating connection codes, two-page Syncables fetch,
review/apply, and five displayed records with integer/boolean/float/timestamp
properties. Dagger starts the mock for E2E; local runs opt in with
`ATOMIC_MOCK_INTEGRATION_PROXY=1` and the README configuration.
`integration_proxy` Rust tests cover actor/drive binding, tenant HMAC,
`browser.test.ts` and the real WASM smoke cover actor/drive binding, tenant HMAC,
Syncables pagination/ontology and duplicate-page refusal. The mock's Node test
covers invalid tenant proofs and replayed/rotated codes. The mapping tests cover
typed proposals, missing identities, repeat imports, local edits and duplicates.
Live catalog OAD endpoints currently return 404 (integration-proxy #25), so live
OAuth and GitHub data fetching are not yet certified.
The historical server path was live-verified for GitHub and Google Calendar.
The new browser path awaits deployment of the companion proxy CORS change.
Run it against a production build to catch missing translation catalog entries:
Vite dev extracts them automatically and can hide blank production labels.
The GitHub setup flow also covers opting into assistant-led automation creation:
Expand Down Expand Up @@ -1053,3 +1084,15 @@ cancelled on teardown. Old plugin-name grants are deliberately not migrated.
commit. It failed with the server signer before `Resource::destroy_as` was used;
installation deletion must use the same selected identity as create/update.
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).

Google Calendar one-way projection: `integrations/localthought/calendar.test.ts`
covers all-day/timed start dates, offset boundaries, exclusive end preservation,
feature notes (including WASM-normalized field names), cancellations without
start data, invalid active events, namespace isolation and repeat import/local
field preservation. `browser/e2e/tests/google-calendar-import.spec.mts` uses the
shared HTTP mock integration-proxy with a paginated Google Calendar, tenant
secret entry and OAuth consent. It covers browser WASM fetching, local
schema/proposal/apply, Calendar display, provider updates, OPFS reload and
stable identities while AtomicServer HTTP/WebSockets are unavailable. Missing
rows in a bounded snapshot are retained, not interpreted as deletions.
Live-provider browser OAuth verification remains separate from this fixture test.
Loading
Loading