Skip to content

feat: expand framework onboarding examples - #428

Open
alongubkin wants to merge 14 commits into
mainfrom
alon/alien-524-framework-onboarding
Open

feat: expand framework onboarding examples#428
alongubkin wants to merge 14 commits into
mainfrom
alon/alien-524-framework-onboarding

Conversation

@alongubkin

@alongubkin alongubkin commented Aug 17, 2026

Copy link
Copy Markdown
Member

What changed

Alien's onboarding examples now reflect the ways teams actually use the framework:

  • Added a private-data agent backed by customer-hosted Postgres.
  • Added a customer-controlled keys example showing remote key access and tenant-scoped encryption.
  • Improved alien init so it skips invalid example directories and includes reliable fallback metadata.
  • Added the new customer-focused examples to the examples workspace.

How to test

  • cargo check -p alien-cli
  • Run Biome against the changed TypeScript files.
  • Build @alienplatform/core and @alienplatform/bindings.
  • Run the customer-keys example typecheck.

ALIEN-524

ItamarZand88 and others added 13 commits August 16, 2026 22:44
A streaming chatbot container that answers questions about a private Postgres through a SQL tool run on read-only sessions. No API keys and no database credentials in the app: the AI binding routes through the gateway's ambient cloud identity, and the Postgres password resolves at runtime from the cloud secret store via postgres("db").connection().

Both alien packages stay serverExternalPackages — their native halves (napi addon, gateway binary) resolve with dynamic requires the bundler cannot see — and the per-platform prebuild packages are traced into the standalone output explicitly for the same reason. The image base is glibc because the bindings addon ships no musl prebuild.
The gateway forwards each model to its own upstream wire format rather than translating, so an OpenAI-compatible client reaches the OpenAI-protocol models only, and picking Claude in the model picker failed. Select the client from the model id, so every model the binding lists is usable through the one connection.
… route

The container is publicly reachable, so an unauthenticated route that dropped and recreated the demo tables let anyone who found the URL reset them. Seed on the first question instead, creating and filling only what is missing, so there is no write endpoint to reach and a real table is never dropped.

The model writes the SQL the tool runs, and read-only sessions stop writes but not a pg_sleep or a runaway scan holding a pool connection. Add a statement timeout and move the row cap into SQL, where a client-side slice still buffered every row the database returned.

Register the template in the init fallback list so alien init ai-chatbot-ts still resolves when GitHub discovery is unavailable.
An answer is more convincing next to the rows it came from, so a drawer over the chat reads the demo tables through the same read-only pool the model's tool uses. Lifting that pool into app/db.ts keeps both readers on one connection with the same bounds.

A native modal dialog carries the drawer: the top layer puts it above the background's full-viewport layers, and Escape, the backdrop, and focus containment come with it.
The runtime stage ran as root, so a compromised server held root inside the container; it now drops to the base image's node account.

Seeding wrote its two inserts as separate autocommits, so a failure between them left customers with no orders, which the count check then read as already seeded. One transaction makes it all-or-nothing, and an advisory lock keeps concurrent replicas from racing on create-if-not-exists.

Reads go through a shared helper that reseeds once on undefined_table, so a database emptied behind a running container recovers on the next request instead of failing until restart.

Refs greptile review on #271
The session default was reversible from inside the statement it was meant to bound: `select set_config('default_transaction_read_only','off',false)` passes the single-SELECT check, and a later `WITH ... INSERT ... RETURNING` on the same pooled connection then writes. Reproduced against a real database, row written; a read-only transaction cannot be reopened for writing, and the same sequence now fails with `cannot execute ... in a read-only transaction`.

Refs greptile review on #271
The tool now takes a question name and a couple of enum filters, and
app/queries.ts owns the statement each one runs with the model's
arguments bound as parameters. Nothing the model sends reaches the
database as SQL, so the session settings, the system catalogs, and the
tables outside the demo schema are all out of reach by construction
rather than by validation.

The seed connection also gets a statement timeout, so a container that
dies holding the advisory lock can no longer park every other seed.
`alien init` offers ai-quickstart-ts and ai-chatbot-ts, but neither
appeared in the table, so the README undersold what the CLI can scaffold.
The trade-off was only stated in the README, which is not where someone
reading the route or the stack definition will look for it.
Biome 2 parses CSS, and @plugin / @theme are Tailwind extensions it
rejects unless told to expect them.
@greptile-apps

greptile-apps Bot commented Aug 17, 2026

Copy link
Copy Markdown

Greptile Summary

Alien expands its onboarding catalog with customer-managed key and private-data chatbot examples while adjusting template discovery to list only directories with valid metadata.

  • Adds deployable TypeScript examples for tenant-scoped customer keys and an AI chatbot backed by private Postgres.
  • Updates the examples workspace, documentation, formatting configuration, and lockfile.
  • Extends the CLI fallback catalog and changes remote template metadata handling.

Confidence Score: 3/5

The PR is not yet safe to merge because template metadata failures still hide scaffoldable examples and the chatbot seed still leaves persistent databases with incomplete order data.

Partial template metadata failures continue to return a successful but incomplete catalog, while the seed path checks only customer presence before skipping both datasets; both previously reported behaviors remain reachable on the current HEAD.

Files Needing Attention: crates/alien-cli/src/commands/init.rs; examples/ai-chatbot-ts/app/seed.ts

Important Files Changed

Filename Overview
crates/alien-cli/src/commands/init.rs Expands fallback metadata and changes template discovery to omit directories whose metadata cannot be fetched or parsed.
examples/ai-chatbot-ts/app/seed.ts Creates and lazily seeds the chatbot's persistent customer and order demo tables.
examples/ai-chatbot-ts/app/api/chat/route.ts Adds model selection, bounded database tooling, and streamed AI responses through the deployment binding.
examples/customer-keys-ts/src/vendor.ts Implements the example's remote customer-key retrieval and tenant-scoped cryptographic operations.
examples/pnpm-workspace.yaml Registers the new customer-focused examples in the examples workspace.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Init["alien init"] --> Listing["Fetch examples directory"]
  Listing --> Metadata["Fetch each template.toml"]
  Metadata --> Catalog["Build selectable template catalog"]
  Catalog --> Scaffold["Download and scaffold selected example"]
  Chat["AI chatbot container"] --> Gateway["Ambient AI gateway"]
  Chat --> Database["Private Postgres"]
  Keys["Customer-keys example"] --> Vendor["Remote customer key service"]
  Keys --> Ciphertext["Tenant-scoped encryption"]
Loading

Reviews (2): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

Comment on lines 164 to +166
};

templates.push(info);
if let Some(info) = info {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Partial metadata failures hide templates

When the directory listing succeeds but an individual template.toml request or parse fails, this branch silently omits that valid template while returning the remaining catalog as successful, causing it to disappear from interactive selection and explicit template-name matching instead of activating the fallback catalog.

Knowledge Base Used: Developer CLI and Deploy CLI

Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/alien-cli/src/commands/init.rs
Line: 164-166

Comment:
**Partial metadata failures hide templates**

When the directory listing succeeds but an individual `template.toml` request or parse fails, this branch silently omits that valid template while returning the remaining catalog as successful, causing it to disappear from interactive selection and explicit template-name matching instead of activating the fallback catalog.

**Knowledge Base Used:** [Developer CLI and Deploy CLI](https://app.greptile.com/alien/-/custom-context/knowledge-base/alienplatform/alien/-/docs/developer-cli.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex

Comment on lines +76 to +80
const { rows } = await client.query("select count(*)::int as count from customers")
if (rows[0].count === 0) {
await client.query(CUSTOMERS)
await client.query(ORDERS)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Customer count masks incomplete seeds

If the persistent live database contains customers but its orders table is empty or partially populated, this single count check skips both seed inserts, leaving the order-related tools and data drawer with incomplete demo results until the database is manually reset.

Prompt To Fix With AI
This is a comment left during a code review.
Path: examples/ai-chatbot-ts/app/seed.ts
Line: 76-80

Comment:
**Customer count masks incomplete seeds**

If the persistent live database contains customers but its orders table is empty or partially populated, this single count check skips both seed inserts, leaving the order-related tools and data drawer with incomplete demo results until the database is manually reset.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex

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.

2 participants