feat: improve framework examples and operator packaging - #428
Conversation
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.
Greptile SummaryThe PR refreshes framework examples and CLI onboarding, expands operator and sandbox support, and synchronizes generated platform SDKs with the current API contract.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| crates/alien-cli/src/commands/init.rs | Replaces network-discovered metadata with a versioned catalog and revises destination and package-manager handling. |
| examples/ai-chatbot-ts/app/seed.ts | Adds transactionally locked, stable-ID upserts that repair missing or partial demo seed data. |
| crates/alien-helm/src/generator.rs | Expands generated operator manifests with cloud identity annotations and configurable branding. |
| crates/alien-build/src/sandbox_bundle.rs | Updates sandbox artifact packaging used by the remote execution examples. |
| client-sdks/platform/typescript/src/models/renderoperatormanifestrequest.ts | Synchronizes the generated TypeScript operator-manifest request model with the platform API contract. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
Examples[Framework examples] --> Init[alien init]
Init --> Local[Local development]
Local --> Release[Release workflow]
Release --> Operator[Helm operator]
Operator --> Runtime[Remote and sandbox runtime]
API[Platform API contract] --> SDK[Generated platform SDKs]
SDK --> Init
SDK --> Release
Reviews (4): Last reviewed commit: "fix: repair partial example seeds" | Re-trigger Greptile
| }; | ||
|
|
||
| templates.push(info); | ||
| if let Some(info) = info { |
There was a problem hiding this 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
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.| 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) | ||
| } |
There was a problem hiding this 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.
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.…ork-onboarding # Conflicts: # client-sdks/platform/openapi.json # client-sdks/platform/rust/openapi-3.0.json # client-sdks/platform/rust/openapi.json # client-sdks/platform/typescript/.speakeasy/gen.lock # client-sdks/platform/typescript/docs/models/createmanagerresponsestacksettings1.md # client-sdks/platform/typescript/docs/models/createmanagerresponsestacksettings2.md # client-sdks/platform/typescript/docs/models/createmanagerresponsestacksettings3.md # client-sdks/platform/typescript/docs/models/createsetupregistrationoperationrequeststacksettings.md # client-sdks/platform/typescript/docs/models/defaults.md # client-sdks/platform/typescript/docs/models/deploymentdetailresponsestacksettings.md # client-sdks/platform/typescript/docs/models/deploymentstacksettings.md # client-sdks/platform/typescript/docs/models/importsourcestacksettings.md # client-sdks/platform/typescript/docs/models/managerretryresponsestacksettings1.md # client-sdks/platform/typescript/docs/models/managerretryresponsestacksettings2.md # client-sdks/platform/typescript/docs/models/managerretryresponsestacksettings3.md # client-sdks/platform/typescript/docs/models/newdeploymentrequeststacksettings.md # client-sdks/platform/typescript/docs/models/operations/plandeploymentcomputestacksettings.md # client-sdks/platform/typescript/docs/models/operations/preparedeploymentstackstacksettings.md # client-sdks/platform/typescript/docs/models/persistimporteddeploymentrequeststacksettings.md # client-sdks/platform/typescript/docs/models/synclistresponsestacksettings.md # client-sdks/platform/typescript/src/sdk/resources.ts # crates/alien-cli/src/commands/deploy.rs # crates/alien-cli/src/commands/deployments.rs
|
@greptile-apps please review the full PR despite the file-count limit. The previously reported template catalog and seed idempotency issues are fixed on the current HEAD. |
|
@greptile-apps please review the full PR despite the file-count limit. The partial-seed repair is fixed on the current HEAD with stable-ID upserts for every demo row. |
Summary
Make the public framework and Remote operator building blocks match the new onboarding experience.
alien initexamples around small, useful remote components and make template discovery more reliable.Validation
pnpm run generate:platform-apicargo fmt --all -- --checkcargo check -p alien-cliThe Rust check passes with existing warnings in
alien-bindings,alien-local, andalien-infra.ALIEN-524