Varendo

Knowledge example

Search content, read an article, navigate between results, and render a consumer-owned custom presentation.

The Knowledge example shows extension beyond tables and cards: the app registers its own request kind and article view. No core package is edited.

Run it

  1. 1

    Open the scenario

    Open Knowledge in the playground. You should see searchable synthetic articles.

  2. 2

    Run the scenario steps

    Choose Search articles, Read article, then Security topic. You should see matched articles, a registered reading view, and the output of a custom request kind.

  3. 3

    Inspect the custom request

    After Security topic, choose Inspect. You should see the custom request (demo.knowledge.by-topic) compile through the same validator as the built-in kinds.

  4. 4

    Run it locally

    Choose More → Export project, unzip the download, then run pnpm install and pnpm dev. You should see a local browse view and the status renderer-ready.

What it exercises

  • Search article titles, summaries, and content through a browse request.
  • Render a registered custom view (demo.knowledge-article) for reading.
  • Send a namespaced custom request that compiles into the normal pipeline.
  • Keep the custom request and renderer bound to their registered contracts.

Make it yours

  • Swap the synthetic articles for your data adapter.
  • Read permissions from your real app state.
  • Register your own view or request kind — same contract, no core edits.
  • Dispose the app when the host removes the surface.

When it fails

An unknown field or view returns a diagnostic and keeps the last permitted view. A denied permission read returns no data. Fix the contract or the trusted policy, then send the request again.

Local browse starter source

The exported project renders one browse view. The additional Playground steps above require their resource meanings, forms/actions, or custom registrations; they are not bundled in this minimal starter. Follow Connect your data to add those contracts.

package.json · compiled export source
{
  "name": "aeliqo-knowledge-example",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc --noEmit && vite build"
  },
  "dependencies": {
    "@varendo/core": "0.1.0",
    "@varendo/runtime": "0.1.0",
    "@varendo/web": "0.1.0",
    "zod": "4.5.4"
  },
  "devDependencies": {
    "typescript": "7.0.2",
    "vite": "8.2.2"
  }
}
tsconfig.json · compiled export source
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "lib": [
      "ES2022",
      "DOM"
    ],
    "types": [
      "vite/client"
    ],
    "strict": true,
    "noEmit": true
  },
  "include": [
    "src/**/*.ts"
  ]
}
index.html · compiled export source
<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Knowledge articles · Varendo</title></head><body><main><h1>Knowledge articles</h1><p id="status" role="status">Loading…</p><div id="app"></div></main><script type="module" src="/src/main.ts"></script></body></html>
src/main.ts · compiled export source
import {defineResource} from '@varendo/core';
import {createQueryFunctionRegistry} from '@varendo/core/expressions';
import {createLocalDataService} from '@varendo/runtime/data';
import {createAeliqoApp} from '@varendo/web/app';
import {z} from 'zod';
import './style.css';

const resource = defineResource({
  id: 'articles', revision: 'articles-1', label: 'Knowledge articles', identity: ['id'],
  schema: z.object({id: z.string(), title: z.string(), topic: z.string(), excerpt: z.string()}),
  fields: {title: {label: 'Title'}, topic: {label: 'Topic', role: 'dimension'}, excerpt: {label: 'Summary'}},
  presentation: {allowedViews: ["table","cards"]},
});

const functions = createQueryFunctionRegistry({version: '2'});
if (!functions.ok) throw new Error(functions.diagnostics[0].message);
const data = createLocalDataService({
  snapshot: {catalog: resource.catalog, sourceRevision: 'synthetic-1', records: {articles: [
  {
    "id": "kb-1",
    "title": "Rotate an API token safely",
    "topic": "Security",
    "excerpt": "Replace and revoke credentials safely."
  },
  {
    "id": "kb-2",
    "title": "Understand workspace roles",
    "topic": "Access",
    "excerpt": "Assign the smallest useful role."
  }
]}},
  functionRegistry: functions.value,
  sourceLimits: {rows: 1_000, bytes: 1_000_000},
  authorize: () => ({ok: true, value: {scopeDigest: 'local-demo', policyRevision: 'policy-1'}}),
});

const app = createAeliqoApp({
  resources: [{resource, data}],
  authority: {read: () => ({ok: true, value: {
    principalKey: 'local-user', scopeDigest: 'local-demo', policyRevision: 'policy-1',
    experienceRevision: 'web-1', grants: ['task.evaluate', 'result.inspect', 'experience.commit'],
    readContext: {principal: 'local-user'},
  }})},
});

const target = document.querySelector<HTMLElement>('#app');
if (target === null) throw new Error('The app target is missing.');
const mounted = app.mount({target, regionId: 'main', resourceId: resource.id});
if (!mounted.ok) throw new Error(mounted.diagnostics[0].message);
const receipt = await app.render({regionId: 'main', intent: {
  version: '1', id: 'articles-browse', kind: 'browse', resource: resource.id,
  fields: ["title","topic","excerpt"],
}});
document.querySelector('#status')!.textContent = receipt.status;
window.addEventListener('pagehide', () => app.dispose(), {once: true});
src/style.css · compiled export source
:root{font-family:Inter,ui-sans-serif,system-ui;color:#202033;background:#f7f7fb}body{margin:0}main{inline-size:min(72rem,calc(100% - 2rem));margin:3rem auto}#app{container-type:inline-size;min-block-size:20rem}
README.md · compiled export source
# Knowledge articles · Varendo 0.1.0

Synthetic source project exported from the Varendo playground. Install requires the pinned 0.1.0 packages to be published to npm.

```sh
pnpm install
pnpm dev
```

The application works without an AI provider. Replace the local snapshot and authority adapter with application-owned implementations before using real data.