Lenso

Connect a React/Vite frontend

Start from signed knowledge-base source content and connect typed React calls to a prepared local App.

Development preview · Not a published framework version

This page does not substitute for an unavailable published version. Check an exact version

Locale
en
Content revision
sha256:188682c76bfcf79c5b9feb6d919637fd15ac55087c9922065f601b3474b3eaab
简体中文

The signed Knowledge Base Starter 0.1.0 contains editable Rust, Bun and React source. Preview and copy its exact archive with the signed source-content workflow. Use @lenso/cli@0.17.4 with native CLI 0.6.4 built from published Rust source ab09878c1d07235812a193c97b081686ff0d0943, Rust/Cargo, Bun and a disposable PostgreSQL database. Provider setup and credentials remain explicit App inputs. Use --marketplace with the exact starter version, --content-id, a new --content-destination, and --content-preview first. The CLI verifies the current catalog and archive without manual trust files; copying the source does not configure providers or grant build permission.

The reference App needs a built linked Web Host that admits its Bun Excerpt Plugin. A Process-only precompiled Host cannot run that Bun Plugin. A signed source template does not supply or activate a Host.

The local Web App quickstart proves one greeting. This follow-up shows how a normal React page calls an App's public API with generated types. Lenso starts Vite for a prepared source App; a separate Vite build writes static assets for the built Host. Backend Plugins still own authentication and authorization.

1. Identify the inputs before starting

The starter archive is the fixture's project/ tree; after copying, its root contains app/ and frontend/. Read the exact source revision's fixtures/vnext-knowledge-base-app/README.md for provider configuration and the separate fixture verifier.

Public package inputs include @lenso/web-client 0.1.0, @lenso/knowledge-excerpt 0.1.2, Auth API-token 0.1.2, Jobs 0.1.8 and Secrets Env 0.1.7. Check each exact archive and signed identity before adoption. Registry presence does not prove that a provider has a current signed directory record.

The original project/frontend/bun.lock names a local vendor/lenso-web-client.tgz whose bytes differ from the public npm archive. For a copied App, select the public version and review the resulting App-owned manifest and lock change:

cd frontend
bun add --exact @lenso/web-client@0.1.0 --ignore-scripts
bun install --frozen-lockfile --ignore-scripts
bun run generate && bun run typecheck

The original fixture verification path below keeps its matching local tarball and explicit source or signed .crate provider inputs. Its verifier creates schemas and leaves them available for inspection; it does not reset the database afterward. This interactive credential handoff requires POSIX no-follow file APIs; it is not a Windows path.

A clean fixture checkout is not ready for lenso app dev: the provider Plugins, their operator setup, credentials, and database configuration have not been prepared. The fixture README explains both source and signed-package input modes. Use the current signed records and public archive digests for package adoption; the historical test-signed candidates in AGENT_INPUT.md are separate inputs.

2. Run the fixture verification alternative

After reviewing the candidate source and arranging an isolated local build environment, the fixture verifier can prepare a temporary App, build the React page from the supplied tarball, issue short-lived test credentials, build the Host, and exercise the real HTTP listener:

cd /path/to/lenso-examples/fixtures/vnext-knowledge-base-app
HANDOFF_DIR="$(mktemp -d)" # Private mode-0700 directory; keep it outside the checkout.
LENSO_REFERENCE_DATABASE_URL='postgresql://.../disposable_db' \
  python3 verify.py \
  --cli /absolute/path/to/lenso \
  --web-client-package /absolute/path/to/lenso-web-client.tgz \
  --framework-source /absolute/path/to/lenso-rust-checkout \
  --tool-provider-source /absolute/path/to/lenso-capability-agent-tool-provider \
  --auth-source /absolute/path/to/lenso-auth-plugin/crates/lenso-auth-api-token-plugin \
  --jobs-source /absolute/path/to/lenso-jobs-plugin/crates/lenso-jobs-plugin \
  --secrets-source /absolute/path/to/lenso-secrets-plugin/crates/lenso-secrets-env-plugin \
  --browser-handoff "$HANDOFF_DIR/browser-handoff.json"
rmdir "$HANDOFF_DIR" # Only after the verifier exits and the handoff file is gone.

Provider and App builds can execute package build scripts; run unreviewed inputs only in a network-disabled, resource-limited sandbox. The verifier exclusively creates the handoff file at mode 0600 in that private directory and rejects a pre-existing file or symlink. It contains a live test token and URL. While the verifier waits (at most ten minutes), open that URL, enter the token, select Load workspace, create a note, and confirm its excerpt appears after processing. Upload a small file to that note and confirm the stored-file status. Delete the handoff file when finished so the verifier can perform its restart checks. The final rmdir removes only that empty private directory after the verifier exits. On timeout or Ctrl-C, the verifier attempts inode-checked cleanup; when the handoff runs on the POSIX main thread, it also temporarily handles SIGTERM for that purpose. This is best effort: the check and name-based deletion are not atomic against a same-UID writer, and SIGKILL, a process crash, or power loss may leave the file. Keep the 0700 directory private. If a file remains, stop the verifier and manually remove it only after confirming the path still names the handoff, not a replacement. Do not reuse, commit, or share the token.

A successful run verifies a built, source-deleted candidate App. With --web-client-package, the verifier builds the React page from the supplied tarball before that App build; without it, the checked-in static page remains. Neither path proves a published package, a deployed Site, or production support.

3. Edit the React page in a prepared App

For an App already prepared with those providers, schema operators, credentials, excerpt Plugin, and database settings, put the exact tarball at the fixture's locked local dependency path. From the fixture directory, use the matching CLI and the fixture's exact local tarball:

LENSO_CLI=/absolute/path/to/lenso
mkdir -p project/frontend/vendor
cp /absolute/path/to/lenso-web-client.tgz project/frontend/vendor/lenso-web-client.tgz
(cd project/frontend && bun install --frozen-lockfile && bun run generate && bun run typecheck)
"$LENSO_CLI" app dev --root project

project/frontend/lenso.dev.toml selects bun run dev on http://127.0.0.1:5173/. Engine supplies LENSO_API_URL_FILE, pointing to the current Host URL in project/.lenso/dev-backend-url. The Vite middleware reads that file for each allowed public request and exposes GET /__lenso/backend as a readiness handshake. A missing or invalid URL file returns 503; a successful Host rebuild may change its port without restarting Vite. The proxy only forwards the fixture's public notes, settings, jobs, and attachment routes. It does not expose Host administration or internal Capabilities. Open the Vite page after app dev reports readiness.

After editing React, stop the dev loop and rebuild the Plugin-owned static assets for a new App distribution:

(cd project/frontend && bun run build)
"$LENSO_CLI" app build --root project --out dist-react-review
"$LENSO_CLI" app check --root dist-react-review
"$LENSO_CLI" app show --root dist-react-review/intent --json
"$LENSO_CLI" app start --from dist-react-review --check

bun run generate projects the selected openapi.json into src/generated/api.ts. The page in src/main.tsx creates createLensoWebClient<paths> with a Bearer token callback and uses typed GET/POST/PUT calls. unwrap turns API failures into LensoApiError; type generation does not make server input trusted or grant access to an internal Capability. The backend verifies the actor and resource permissions on each request. See Auth Plugin for the provider boundary.

project/frontend/vite.config.ts writes the build to project/app/notes-web/public/. Vite HMR does not update a previously built App. The verifier's private browser handoff separately checks the built, source-deleted Host rather than the editable development page.

Use a new output directory each time; app build refuses to overwrite one. app start --check validates readiness and shuts down; it does not perform the browser request. Completion means the verifier's browser request succeeds with an issued token, a note can be read back, an unauthorized user cannot read it, and the built App passes check and show. This Site page describes that check; it does not claim those steps have been run for your checkout.

Give an agent the same task

Use the signed knowledge-base source template and an isolated disposable
database. Verify the published CLI, exact provider inputs and npm archives.
For the original fixture workflow, retain its matching local tarball and
source revision rather than substituting public bytes into the old lock. Run the fixture
verifier with a private browser handoff; exercise token verification, note creation,
readback, and upload in a real browser, and inspect the verifier's cross-user
denial result. For a separately prepared App, run the frozen frontend install,
generate/typecheck, and app dev; after an edit, rebuild static assets and run
app build/check/show/start --check. Report exact
revisions, package digest, commands, browser URL, result, and missing inputs.
Do not turn candidate proof into a published or deployed claim.

The agent and a human use the same App and verification boundary. A missing provider or tarball is a blocked candidate step, not permission to bypass the Plugin Root or expose a private Capability through the browser.

On this page