Skip to content

Add the BXL formula Specs on Pret UI - #829

Merged
richardhjtan merged 5 commits into
mainfrom
cs-13687-bxl-for-catalog-type-check
Oct 12, 2026
Merged

richardhjtan merged 5 commits into
mainfrom
cs-13687-bxl-for-catalog-type-check

Conversation

@richardhjtan

@richardhjtan richardhjtan commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

Important

Merge order: cardstack/boxel#6627, then this.
Merge cardstack/boxel#6627 first, then this right after. Until it lands, the catalog type-check can't resolve @cardstack/bxl.

Merges after: cardstack/boxel#6627

Background and Goal

The BXL formula blocks move from the matrix realm into the catalog on Pret UI (CS-13687). They were left out of the shared fields and tools wave because they import @cardstack/bxl, which the catalog type-check resolves only once cardstack/boxel#6627 adds the dependency.

  • Fields: Expression (fields/expression/) holds a BXL expression as data; Formula (fields/formula/) pairs a reader's label with an Expression and evaluates it against the owning card.
  • Command: Evaluate Expression (commands/) evaluates an expression against a card and returns the result as JSON.
  • Helper: utils/bxl-input.ts builds the expression's input from a card.
  • Example: Formula Sandbox (fields/formula/example/), whose instance evaluates ROUND(IF(Recurring, Amount * 12, Amount) * (1 + Rate), 2) to 3450 (250 a month, recurring, with 15% tax).

The first commit is the move and the second is the Pret UI pass.

Key decisions and non-obvious mechanics

  • Links outside a render: Evaluate Expression fetches its subject by id, and bxl-input reads the subject's own links by their stored id, so a link that hasn't loaded still reaches the expression as { id } rather than null.
  • Pret UI: Formula's status is a StatePill (Empty slate, Compiles blue, Error red; Compiles isn't proven against a subject, so it doesn't read as success), and the sandbox's inputs are a KeyValue with the field components as values. Styles read contract tokens without fallbacks, with -ink tokens for error and success text.
  • Not adopted: the expression source stays a <code> block; Pret Token is sized for short identifiers, not a formula.

🤖 Generated with Claude Code

richardhjtan and others added 2 commits October 9, 2026 16:23
Expression and Formula fields, the Evaluate Expression command, the
bxl-input helper and the Formula Sandbox example, with their Specs. The
command fetches its subject by id, and the helper reads the subject's
links by their stored id, since links may not have loaded outside a
render.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Formula's status is a StatePill, the sandbox's inputs are a KeyValue, and
the styles read contract tokens without fallbacks, with -ink tokens for
error and success text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Staging Submissions Preview

This PR's content is pushed to the staging submissions realm: https://realms-staging.stack.cards/submissions/

Changed folders:

  • Spec/
  • commands/
  • fields/
  • utils/

Updated at 2026-10-12 06:46:00 UTC for commit bacb9ee. Shared realm: only this PR's changed files are pushed; files touched by multiple PRs reflect whichever pushed last, and deleted files are not removed.

NumberField's standard display rounds to whole numbers unless decimals are
configured, so the 0.15 rate read as 0. The rate field now shows two
decimals, and the example formula applies it as tax:
ROUND(IF(Recurring, Amount * 12, Amount) * (1 + Rate), 2) = 3450.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@lucaslyl lucaslyl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[Claude Code 🤖] Scope: read the full diff (9 files) against the checked-out head, traced cardToBxlInput, the link helpers and evaluateBxlSafe/prepareBxlSafe in the bxl package, and ran Burcu's UI review procedure (steps 0 to 9) over the added .gts templates and <style scoped> blocks. Contrast was judged by token pairing only (--destructive-ink, --success-ink, --muted-foreground on the card surface), not measured. Nothing was rendered or executed, so the evaluation results (including the sandbox's 3450), the live link behavior and both themes are unverified.

Bottom line: safe to approve. No blocking issues; the open items are non-blocking.

Open items (all non-blocking):

  1. Nested links take a different path from the documented { id } shape (inline on utils/bxl-input.ts).
  2. Deprecated --boxel-sp-xxs token name (inline on expression-field.gts).
  3. Repeated provider declarations and rem literals off the type ladder (inline on formula-sandbox.gts).
  4. Hand-rolled fitted view where FittedCard applies (inline on formula-sandbox.gts).
  5. Two copies of the evaluate-and-wrap logic (inline on the command).

Red check: Lint fails only on TS2307 Cannot find module '@cardstack/bxl' in evaluate-expression-command.gts and expression-field.gts. That is the dependency this PR's Merges after: line waits on; the paired platform PR is open, targets main, and names this PR back under Merges before:. Ignore it until that PR merges, then re-run Lint; any other lint error would show alongside it, and ESLint and template lint both passed.

Pre-existing in the touched files (optional follow-ups): every file is new, so none. Optional: 24 of the 42 catalog fields have no co-located .test.gts, so this is not a blocker, but the link-id handling in bxl-input, the depth cutoff and the ok: false paths of the command are the logic a render test or command test would pin.

Comment thread utils/bxl-input.ts Outdated
Comment thread fields/expression/expression-field.gts Outdated
Comment thread fields/formula/example/formula-sandbox.gts Outdated
Comment thread fields/formula/example/formula-sandbox.gts
Comment thread commands/evaluate-expression-command.gts Outdated
richardhjtan and others added 2 commits October 12, 2026 14:43
Read nested links by stored id, delegate the command to ExpressionField,
use FittedCard for the sandbox's fitted view, and move literal sizes and
deprecated spacing onto tokens.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…log-type-check

# Conflicts:
#	utils/linked-id.ts
@richardhjtan
richardhjtan merged commit 11a406d into main Oct 12, 2026
5 checks passed
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