Repository navigation
Description
Hi all, while building a research app with Agent Drafter (PREVENT UCSF Risk Calculator, session 20261002_4, Biorouter desktop on macOS, Node 24, esbuild not installed) we hit five platform issues. Details and evidence below; we can share logs (no patient data) and the package.
-
Built apps > Open returns 403. The link points to /apps//?t= on the desktop app's internal port, which is served by the Biorouter Electron process, not by biorouterd. That port answers 403 to every browser request, including /status and a fresh one-time link. The same app opened through the exported launcher (run.sh, daemon on :3000) works: the token returns 200 and sets the cookie, and reusing it returns 401 as expected.
-
The exported launcher's daemon has no user-action key. Its log says: "no user-action key: stdin closed without one ... it will refuse every request that raises a session's privacy capability". So the only path that currently opens the app cannot use sensitive-data features.
-
App agents cannot load a user-installed stdio extension. The manifest written by Agent Drafter declares agent.extensions: ["ucsfomopagent"]. When the app's agent runs, the daemon logs: "add_extension failed: invalid config: Unknown builtin extension: ucsfomopagent". The extension is installed and enabled in config.yaml (type stdio) and works in normal chats. What is the supported way for an app to declare such an extension, portably (no local paths or credentials in the manifest)?
-
Without esbuild, the fallback bundler produces a broken bundle. dist/app.js started with "Agent Drafter fallback bundle (no esbuild present)". It (a) included only src/sdk.ts and src/main.ts and dropped the local modules ./prevent and ./preventData, and (b) removed "key: Value" pairs whose value starts with a capital letter: { omop_rules: OMOP_RULES, required_outputs: Object.keys(patient) } became { omop_rules , required_outputs , ... }, so the file does not parse. Node 22.6+ ships module.stripTypeScriptTypes; a 40-line build script based on it bundled the same sources correctly.
-
The exported index.html gets injected twice. The export already contains the theme, the app config (with a fixed ws endpoint and no wsToken) and <script src="dist/app.js">. After install, the daemon injects them again: the page has two configs (the SDK reads the first, which has no token) and the script runs twice.
Related: the build agent reported the app as built, launched and tested, although the page could not run. A minimal smoke test that loads the page and checks for script errors would have caught issues 1, 4 and 5 (the Playwright smoke test is optional and was not installed).
Thanks!
Activity
Broccolito commentedon Oct 13, 2026
The fixes from #392 and the follow-ups in #396 are now on main. Here is the verdict for each reported item.
Built apps > Open returned 403 — fixed. The desktop and
biorouter apps openmint the one-time link through the authenticated API but send the browser to the daemon's own listener. The in-chat preview follows the same origin rule.The exported launcher started a second daemon without the desktop's user-action key — service reuse added where supported. macOS/Linux shell and Node launchers now prefer the running service for the same configuration profile, verifying its private metadata, Unix socket and instance identity. They keep authenticated requests on that private socket and leave the reused service running when the launcher exits. Explicit daemon settings retain precedence. Standalone fallback remains when the desktop is absent. Windows has no secure shared-service discovery transport in this build, so it continues to use explicit daemon configuration or standalone startup.
The app page still cannot supply a person's approval proof. Its agent permissions remain governed by the existing app, permission and privacy rules; reusing a service does not give authored page code the desktop's human approval authority.
App agents could not load an installed stdio extension — fixed.
agent.extensionscan name an extension installed and enabled on the running machine. The daemon uses that machine's saved command, arguments and credential keys; a manifest cannot provide those or override a disabled switch. Platform/frontend entries and unknown names are refused. The SDK reference documents this supported behavior. Manually configured extensions that are absent from the installed-bundle catalog remain unavailable to strict drafter catalog validation.The fallback bundler produced a broken bundle — fixed. Desktop and Linux packages ship a pinned, checksum-verified esbuild. The limited fallback refuses imports and TypeScript forms it cannot safely handle, preserves the reported object-literal values, and never overwrites a proper bundle. The reporter's exact input is a regression fixture. Generated JavaScript is now checked before installation using the compiled-in parser; the existing compiler/Node checks provide additional syntax validation where available.
Exported index.html was injected twice — fixed. Exports carry authored HTML. Serving removes earlier generated injections before adding one current config island and bundle tag, healing an older doubly injected entry on its next load.
The build agent reported success for a broken page — default quality checks added. Build, launch, serving and export now check the entry, declared local scripts/styles and JavaScript structure without opening a browser, fetching external URLs or executing app code. A proven defect produces an actionable failure naming its file. Static checks do not establish runtime behavior: a passing result says that explicitly, and the separate real-browser smoke check remains available for execution coverage. Advisory lint warnings and the person-only lint override remain distinct from hard page defects.
Merged through #396 at 989dc747. Validation passed 23,449 local UI/library/integration tests (13 UI skips and 10 Rust ignores), the complete
just check-everythinggate, 57 real-daemon page-quality assertions, and 30 real macOS launcher assertions. Independent source and evidence review is clear. Exact-main CI is green: Rust on Ubuntu/macOS/Windows, Frontend, Apps smoke, commit checks, and website checks/deployment.