You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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
The page — a route hosting the editor, plus a document store (the old globalDotrainFile / storesGeneric/textFileStore are gone).
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.
The RawRainlangExtension diagnostics closure that feeds CodeMirrorDotrain, and its transport to whatever answers 2.
Suggested phasing
Decide the diagnostics story (2) and the builder: frontmatter constraint — both are design calls that shape everything else.
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
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.
Decision
We want in-app order authoring back: paste or write a
.rainand 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.svelteand was deleted wholesale in2a319034("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.getDeploymentKeys,getOrderDetails,getDeploymentDetails,getDeploymentDetail.generateAddOrderCalldata,generateDepositAndAddOrderCalldatas,getDeploymentTransactionArgs(owner)—order_operations.rs.DotrainOrder.create(dotrain)+composeScenarioToRainlang/composeDeploymentToRainlangfor preview.handleAddOrder.tsis builder-agnostic — it accepts anyRaindexOrderBuilder, so a raw-dotrain-constructed builder drops into the existing deploy flow unchanged.One shape constraint worth designing around up front:
new_with_deploymentrequires the dotrain frontmatter to carry abuilder:section withdeployments:(OrderBuilderCfg::parse_deployment_keys), andprepare_calldata_generationrunscheck_select_tokens+check_field_values. So "paste any dotrain" is really "paste builder-shaped dotrain" — a plain orders/scenarios/deployments dotrain with nobuilder:block has no JS path to calldata, becauseAddOrderArgsis 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 fromlib/index.ts:59, tested, and lint-wired: it importsopenLintPanelfrom@codemirror/lintand force-opens the lint panel on mount. It is orphaned — nothing on main mounts it. It is a shell: it takes a fully-constructedRawRainlangExtensionas a required prop and builds no diagnostics itself.CodeMirrorRainlang.svelte— live, but mounted read-only inOrderDetail.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 todarkMode.ts),ComposedRainlangModal.svelte, and the depscodemirror-rainlang3.0.13,svelte-codemirror-editor,thememirror.What has to be rebuilt
The page — a route hosting the editor, plus a document store (the old
globalDotrainFile/storesGeneric/textFileStoreare gone).Diagnostics — the biggest gap.
crates/common/src/dotrain_add_order_lsp.rsstill exists and is declared inlib.rs(DotrainAddOrderLsp::{new, hover, completion, problems}), but:#[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 onparse_rainlang_on_forkwhich 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.
The
RawRainlangExtensiondiagnostics closure that feedsCodeMirrorDotrain, and its transport to whatever answers 2.Suggested phasing
builder:frontmatter constraint — both are design calls that shape everything else.CodeMirrorDotrainwith syntax highlight only, feed the text tonewWithDeployment, 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.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 (
Wordstab 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, #850Chart/plot yaml + elided bindings: #527 (docs links beside the yaml), #531 (
compose_to_rainlangerrors on elided bindings), #529, #462, #543, #470, #471, #472, #473, #675, #367, #450, #513, #504, #493, #417, #1311Closed 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