Skip to content

Restore in-app order authoring: a free-form dotrain editor that can deploy without a registry #2820

Description

@thedavidmeister

Decision

We want in-app order authoring back: paste or write a .rain and deploy it, without publishing to a registry first. This answers the open design question in #1664.

What we lost, and when

The free-form dotrain editor lived at tauri-app/src/routes/orders/add/+page.svelte and was deleted wholesale in 2a319034 ("chore: remove Tauri desktop application", 2026-01-28, closes #2417). Today the webapp's only order-creation path is registry-driven — deploy/[orderName][deploymentKey] — and the only free-text input in that entire flow is a registry URL (InputRegistryUrl.svelte). There is no route on main that mounts a dotrain editor.

The good news: the backend already supports this

Raw dotrain → deployable calldata is alive and wasm-exported. No registry required:

  • RaindexOrderBuilder.newWithDeployment(dotrain: string, settings, deploymentKey, cb)crates/js_api/src/raindex_order_builder/mod.rs:123-150. First parameter is a complete dotrain string.
  • Static helpers, all taking raw dotrain: getDeploymentKeys, getOrderDetails, getDeploymentDetails, getDeploymentDetail.
  • generateAddOrderCalldata, generateDepositAndAddOrderCalldatas, getDeploymentTransactionArgs(owner)order_operations.rs.
  • DotrainOrder.create(dotrain) + composeScenarioToRainlang / composeDeploymentToRainlang for preview.
  • handleAddOrder.ts is builder-agnostic — it accepts any RaindexOrderBuilder, so a raw-dotrain-constructed builder drops into the existing deploy flow unchanged.

One shape constraint worth designing around up front: new_with_deployment requires the dotrain frontmatter to carry a builder: section with deployments: (OrderBuilderCfg::parse_deployment_keys), and prepare_calldata_generation runs check_select_tokens + check_field_values. So "paste any dotrain" is really "paste builder-shaped dotrain" — a plain orders/scenarios/deployments dotrain with no builder: block has no JS path to calldata, because AddOrderArgs is not wasm-exported. Either we accept that constraint (and say so in the UI), or we expose a non-builder path.

What survives on the frontend

  • CodeMirrorDotrain.svelte — the editor component itself, intact, exported from lib/index.ts:59, tested, and lint-wired: it imports openLintPanel from @codemirror/lint and force-opens the lint panel on mount. It is orphaned — nothing on main mounts it. It is a shell: it takes a fully-constructed RawRainlangExtension as a required prop and builds no diagnostics itself.
  • CodeMirrorRainlang.svelte — live, but mounted read-only in OrderDetail.svelte. Its editable path (codeMirrorDisabled={false} + onSave, incl. the blur/strip-whitespace behaviour) is tested but has no production caller.
  • codeMirrorThemes.ts (light/dark, wired to darkMode.ts), ComposedRainlangModal.svelte, and the deps codemirror-rainlang 3.0.13, svelte-codemirror-editor, thememirror.

What has to be rebuilt

  1. The page — a route hosting the editor, plus a document store (the old globalDotrainFile / storesGeneric/textFileStore are gone).

  2. Diagnostics — the biggest gap. crates/common/src/dotrain_add_order_lsp.rs still exists and is declared in lib.rs (DotrainAddOrderLsp::{new, hover, completion, problems}), but:

    • it has no #[wasm_bindgen] / #[wasm_export] anywhere and no caller in the repo — it was reachable only through the deleted tauri commands;
    • problems() is gated #[cfg(not(target_family = "wasm"))], i.e. compiled out of the wasm artifact the webapp consumes, and it depends on parse_rainlang_on_fork which is gated the same way.

    So in-browser diagnostics cannot work through this type as it stands. Either the fork-parse path gets a wasm-compatible implementation, or diagnostics route through a different API. Nothing else in the restore is this open-ended — worth settling first.

  3. The RawRainlangExtension diagnostics closure that feeds CodeMirrorDotrain, and its transport to whatever answers 2.

Suggested phasing

  1. Decide the diagnostics story (2) and the builder: frontmatter constraint — both are design calls that shape everything else.
  2. Minimal editor route: mount CodeMirrorDotrain with syntax highlight only, feed the text to newWithDeployment, reuse the existing deploy flow. This alone restores "paste a .rain and deploy" (Should there be an option to paste in a .rain and deploy, instead of having to use a registry URL? #1664) with no LSP work.
  3. Layer diagnostics back on once 2 is settled, which is what re-enables the lint-dependent backlog.

Issues this unblocks

A survey of all 1180 issues found 36 that depend on this surface — 35 open, 1 closed. They are currently unactionable, and several have been sitting in the close-candidate queue because the editor is gone. They should be tracked as dependencies of this issue rather than closed as obsolete.

Editor screen: #519 (prefill a skeleton), #528 (cmd+s to save), #525 (paste doesn't clear prior state), #522 (spurious "undefined deployer address"), #661 (select tab when clicking Words), #969 (Words tab errors for nested scenarios), #2174 (invalid stack values in strategy studio), #184 (frontmatter lint doesn't underline the offending text), #402, #211, #218, #495, #575, #1965, #442, #649, #1728, #850

Chart/plot yaml + elided bindings: #527 (docs links beside the yaml), #531 (compose_to_rainlang errors on elided bindings), #529, #462, #543, #470, #471, #472, #473, #675, #367, #450, #513, #504, #493, #417, #1311

Closed on editor-gone grounds, to reopen: #183 (disable the Add Order button when linting finds problems). Note its successor #2817 — the current deploy button not disabling on invalid config — stands independently.

Related

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions