diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4c30cf8..d99e7fd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,20 @@ on: pull_request: jobs: + changes: + name: Detect changed paths + runs-on: ubuntu-latest + outputs: + playground: ${{ steps.filter.outputs.playground }} + steps: + - uses: actions/checkout@v4 + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + playground: + - 'tools/playground/**' + reference-go: name: Build reference/ + validate conformance fixtures runs-on: ubuntu-latest @@ -31,3 +45,22 @@ jobs: # catches a wrong implementation. # TODO: once Resolve/Progress are implemented, extend go test's # coverage to conformance/{resolve,progress}/ the same way. + + playground-web: + name: Build tools/playground/ + needs: changes + if: needs.changes.outputs.playground == 'true' + runs-on: ubuntu-latest + defaults: + run: + working-directory: tools/playground + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + cache-dependency-path: tools/playground/package-lock.json + - run: npm ci + - run: npm run typecheck + - run: npm run build diff --git a/CLAUDE.md b/CLAUDE.md index 6e4d703..c73a6f4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -37,7 +37,7 @@ built out: nothing needs them yet. | `bindings/` | Per-language wrappers around `reference/`. Placeholders — don't build speculatively. | | `examples/` | Real `.owl` programs, for reading. | | `docs/` | User-facing tutorials. Not written yet. | -| `tools/playground/` | Web REPL. Not built yet, low priority. | +| `tools/playground/` | Browser IDE for OWL projects (file tree, tabs, split view). MVP scaffold — no compiler wired in yet. | | `grammar/` | Deliberately empty — no parser-generator artifact, since `reference/` hand-writes its parser. | ## `reference/` — where the actual code lives @@ -66,6 +66,25 @@ A hand-written recursive-descent parser is the deliberate choice over a parser generator (ANTLR/pigeon/etc.) — `grammar.ebnf`'s productions don't need one, and it keeps the toolchain to just Go. +## `tools/playground/` — workout IDE (MVP) + +A React + TypeScript + Vite browser app: file tree, tabs (opening a +`.md` file shows two tabs — source and rendered preview), and up to +three resizable split panes. State lives in React and is mirrored to +the browser's `localStorage`, so a project survives closing and +reopening the tab — but it's per-browser only, nothing syncs across +devices yet. **No compiler is wired in** — `.json` files are just +files a user creates, not the output of compiling an `.owl` file. A +new project's file tree starts empty; there is deliberately no seeding +from this repo's `examples/`. + +The top bar has two intentionally non-functional stubs — "Publish" +(future: push the project to a not-yet-built marketplace) and "Send to +Phone" (future: hand the project to the phone app via a QR code) — so +their UI shape exists ahead of the backend work they depend on. See +[`tools/playground/README.md`](tools/playground/README.md) for the +full current scope and how to run it. + ## Building and testing ```sh diff --git a/tools/playground/.gitignore b/tools/playground/.gitignore new file mode 100644 index 0000000..e5537be --- /dev/null +++ b/tools/playground/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +dist/ +*.local diff --git a/tools/playground/README.md b/tools/playground/README.md index fc9b3a3..671035c 100644 --- a/tools/playground/README.md +++ b/tools/playground/README.md @@ -1,13 +1,79 @@ # tools/playground/ -A web REPL: paste an OWL program, see it parsed, compiled to canonical -form, and (given some `state`) resolved into a session. - -**Lower priority given the chosen architecture.** The product doesn't -need a browser-side compiler — compilation happens server-side in Go (see -[`../../reference/README.md`](../../reference/README.md)) and the phone -just receives JSON. If built, this would most simply be a small static -page that calls a local instance of the `owlc` CLI's HTTP-server mode (or -a thin dev-only endpoint) rather than compiling in-browser via WASM — no -need for Go's `js/wasm` target unless client-side compilation becomes a -real requirement later. +A browser-based IDE for authoring OWL workout projects: a file tree, +tabbed editing, and up to three side-by-side panes. React + TypeScript ++ Vite. + +## Current scope (MVP) + +- **File tree** (left sidebar) — flat list of in-memory files, each an + `.owl`, `.json`, or `.md` file. A new project starts **empty**; use + "+ New File" to create files (extension determines kind). Files + support rename (double-click) and delete. +- **Tabs** — clicking a file opens it in the focused pane. `.owl` and + `.json` files open as a single source tab; `.md` files open as + **two** tabs, "name.md" (raw source, editable) and "name.md + (Preview)" (rendered markdown, via `react-markdown` + `remark-gfm`). +- **Split view** — 1 to 3 vertical panes ("Split" / "Close Pane" in + each pane's tab bar). Any file can be opened independently in any + pane. +- **Editing** — plain monospace `