Skip to content

feat(agents): install manifest endpoint + slug-based install#362

Merged
buremba merged 1 commit into
mainfrom
feat/install-manifest
Apr 26, 2026
Merged

feat(agents): install manifest endpoint + slug-based install#362
buremba merged 1 commit into
mainfrom
feat/install-manifest

Conversation

@buremba
Copy link
Copy Markdown
Member

@buremba buremba commented Apr 25, 2026

Summary

Replaces the env-var leak in the closed PRs (#361 + lobu-ai/owletto-web#19). Frontend now talks slugs only; the backend resolves internal IDs.

```
GET /api/install/manifest/:slug
→ { slug, name, description, botPhone, templateAgentId }

POST /api/install
body now accepts { slug } in addition to { templateAgentId }
```

Resolution

  • `slug` equals the template org's slug. We pick the canonical template agent in that org (`agents.template_agent_id IS NULL`).
  • `botPhone` comes from a per-slug server env var (e.g. `PERSONAL_FINANCE_BOT_PHONE`). Stripped to bare digits so the landing page plugs straight into `wa.me/`. Null when unset.

Public, no auth — manifests are marketing data. The install POST still requires a session.

What this kills

Net change against the closed work: drop ~430 LOC, replace 1 page, same product.

Adding a new productized template is now:

  1. Seed the org + canonical template agent (existing tooling).
  2. Set a per-slug bot phone env var if you want a wa.me link.
  3. Link to `/install/`.

Stacked on

`feat/install-identity-provisioning` (#359).

Test plan

  • Manifest 200 returns expected shape.
  • Manifest 404 for unknown slug.
  • Manifest skips orgs that only contain instance agents (template_agent_id IS NOT NULL).
  • Manifest returns `botPhone` as bare digits when env var is set; null when unset.
  • Pre-commit Biome + tsc pass.
  • Manual: `POST /api/install -d '{"slug":"personal-finance","whatsapp_phone":"+447123456789"}'` works without templateAgentId.

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@buremba
Copy link
Copy Markdown
Member Author

buremba commented Apr 25, 2026

Heads up: per docs/plans/world-model.md (on docs/world-model-plan), the env-var PERSONAL_FINANCE_BOT_PHONE slug map in install-manifest-routes.ts should go away. Bot phone becomes a metadata field on the agent_template entity (templates become entities of type agent_template in a public_catalog org). Manifest endpoint reads it from the entity, not from a hardcoded slug→env table.

The manifest endpoint itself may still be worth keeping for unauthenticated landing-page rendering, just sourced from data rather than env.

@buremba buremba force-pushed the feat/install-identity-provisioning branch from a190663 to e5b755e Compare April 26, 2026 16:39
Base automatically changed from feat/install-identity-provisioning to main April 26, 2026 16:39
Replaces the env-var leak in the previous landing-page approach. The
frontend now talks slugs only; the backend does all internal-ID
resolution.

  GET /api/install/manifest/:slug
    → { slug, name, description, botPhone, templateAgentId }
  POST /api/install
    body now accepts { slug } in addition to { templateAgentId }

Resolution rules:
  - Slug equals the template org's slug. We pick the canonical template
    agent in that org (the one with template_agent_id IS NULL — i.e.
    not itself an installed instance).
  - botPhone comes from a per-slug server env var (e.g.
    PERSONAL_FINANCE_BOT_PHONE). Stripped to bare digits in the
    response so the landing page can plug it straight into wa.me/<digits>.
    Returns null when unset; the page falls back to a "message the bot"
    instruction.

Public, no auth — manifests are marketing data. The actual install
still requires a signed-in session.

This kills the build-time VITE_PERSONAL_FINANCE_TEMPLATE_AGENT_ID and
VITE_PERSONAL_FINANCE_BOT_PHONE env-var leaks: the frontend bundle no
longer carries any agent-specific config. Adding a new productized
template (calendar, journal, …) is now: (1) seed the org + canonical
template agent, (2) add one server env var if you want a bot phone,
(3) link to /install/<new-slug>.
@buremba buremba force-pushed the feat/install-manifest branch from bfbfacb to c1fba08 Compare April 26, 2026 16:40
@buremba buremba merged commit 74d8e39 into main Apr 26, 2026
10 checks passed
@buremba buremba deleted the feat/install-manifest branch April 26, 2026 16:40
buremba added a commit that referenced this pull request Apr 26, 2026
, #359 install-half) (#372)

The install flow as built — schema-mirror clones a template's entity types /
relationship types / classifiers / watchers into each user's personal org —
was the wrong abstraction. Cross-org vocabulary (an entity in tenant org A
referencing a type defined in a public-catalog org B by FK) is the planned
direction; the mirror pipeline duplicated rows per user and added re-sync
complexity for no working installs (verified 0 rows used the mirror columns
in prod).

Removed:
- packages/owletto-backend/src/agents/install.ts (installAgentFromTemplate, resyncInstalledAgent)
- packages/owletto-backend/src/agents/install-routes.ts (POST /api/install)
- packages/owletto-backend/src/agents/install-manifest-routes.ts (GET /api/install/manifest/:slug)
- All associated integration tests
- subject-identities WhatsApp helpers (normalizePhoneE164, phoneToWhatsAppJid, linkWhatsAppToMember) + their unit tests
- db/migrations/20260425120000_add_template_mirror_tracking.sql (rolled back on prod first)
- Route registrations from src/index.ts

Kept:
- subject-identities.ts provisionMemberAndCoreIdentities — used by the signup
  hook in personal-org-provisioning.ts, orthogonal to install flow.
- #352 personal-org-on-signup, #350/#354/#355/#356 personal-finance content —
  no install dependencies.

DB state: prod migrated down via dbmate (mirror columns dropped), then
20260426120000_entities_entity_type_fk re-applied. 0 user-visible data lost.
@buremba buremba restored the feat/install-manifest branch May 12, 2026 00:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant