lecodes-cli 0.20.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/README.md +56 -57
  2. package/dist/index.js +11052 -7592
  3. package/package.json +14 -8
  4. package/runtime/materials/decal-relief.mat +12 -1
  5. package/runtime/materials/decal.mat +17 -3
  6. package/runtime/materials/lightmap.mat +117 -138
  7. package/runtime/materials/particles-quad.mat +6 -2
  8. package/runtime/materials/terrain-lightmap.mat +123 -0
  9. package/runtime/materials/terrain.mat +36 -55
  10. package/runtime/sdk-types.json +1 -1
  11. package/runtime/web/VERSION.json +5 -0
  12. package/runtime/web/assets/camera-5XOM8eHl.js +1 -0
  13. package/runtime/web/assets/creator-2d-D9WKYM6h.js +1 -0
  14. package/runtime/web/assets/creator-2d-ukvEmNEp.wasm +0 -0
  15. package/runtime/web/assets/creator-full-BBXzQlhq.js +1 -0
  16. package/runtime/web/assets/creator-full-D2dSDdDj.wasm +0 -0
  17. package/runtime/web/assets/creator-full.js-BYswGsqR.symbols +8124 -0
  18. package/runtime/web/assets/creator-ui-DIc92ion.wasm +0 -0
  19. package/runtime/web/assets/creator-ui-_1Z_AX2M.js +1 -0
  20. package/runtime/web/assets/geolocation-BjTKN9_P.js +1 -0
  21. package/runtime/web/assets/inspect-C7x78PNs.js +2 -0
  22. package/runtime/web/assets/map-CyBxOSV0.js +1 -0
  23. package/runtime/web/assets/map-XzoOFt0E.js +2 -0
  24. package/runtime/web/assets/mapImpl-bxvQ2h1Z.js +823 -0
  25. package/runtime/web/assets/maplibre-gl-worker-B7LXXUkR.js +8 -0
  26. package/runtime/web/assets/materials-uri4FvPE.bin +0 -0
  27. package/runtime/web/assets/materials-world-CQWt8TAm.bin +0 -0
  28. package/runtime/web/assets/qr-scanner-CK_cYoJR.js +1 -0
  29. package/runtime/web/assets/uberarchive-DLH-kBhM.bin +0 -0
  30. package/runtime/web/index.html +36 -0
  31. package/runtime/web/player.js +21 -0
  32. package/runtime/web-page/index.html +41 -0
  33. package/runtime/web-page/page.css +1 -0
  34. package/runtime/web-page/page.js +31 -0
  35. package/src/api.ts +1 -302
  36. package/src/cli/args.ts +37 -0
  37. package/src/cli/command.ts +113 -0
  38. package/src/cli/errors.ts +13 -0
  39. package/src/cli/help.ts +158 -0
  40. package/src/cli/index.ts +7 -0
  41. package/src/cli/output.ts +102 -0
  42. package/src/cli/run.ts +106 -0
  43. package/src/commands/{appAndroid.ts → app/android.ts} +454 -43
  44. package/src/commands/{appDesktop.ts → app/desktop.ts} +64 -33
  45. package/src/commands/{appDesktopMac.ts → app/desktopMac.ts} +34 -27
  46. package/src/commands/{appIcon.ts → app/icon.ts} +11 -8
  47. package/src/commands/{app.ts → app/index.ts} +400 -290
  48. package/src/commands/{appShared.ts → app/shared.ts} +43 -44
  49. package/src/commands/{appTemplatesAndroid.ts → app/templates/android.ts} +72 -39
  50. package/src/commands/{appTemplatesGradlew.ts → app/templates/gradlew.ts} +1 -1
  51. package/src/commands/{appTemplates.ts → app/templates/ios.ts} +2 -2
  52. package/src/commands/assets.ts +23 -21
  53. package/src/commands/clone.ts +48 -51
  54. package/src/commands/compile.ts +76 -89
  55. package/src/commands/create.ts +46 -47
  56. package/src/commands/design/comments.ts +361 -0
  57. package/src/commands/design/context.ts +101 -0
  58. package/src/commands/design/index.ts +391 -0
  59. package/src/commands/design/snapshot.ts +134 -0
  60. package/src/commands/{designTemplates.ts → design/templates.ts} +4 -3
  61. package/src/commands/desktop.ts +94 -82
  62. package/src/commands/dev.ts +260 -182
  63. package/src/commands/diff.ts +39 -51
  64. package/src/commands/index.ts +64 -0
  65. package/src/commands/{init.ts → init/index.ts} +195 -191
  66. package/src/commands/{projectTemplates.ts → init/templates.ts} +64 -21
  67. package/src/commands/install.ts +80 -67
  68. package/src/commands/lightmap.ts +543 -252
  69. package/src/commands/link.ts +87 -94
  70. package/src/commands/login.ts +25 -23
  71. package/src/commands/navmesh.ts +169 -139
  72. package/src/commands/plugin.ts +46 -0
  73. package/src/commands/pn.ts +201 -244
  74. package/src/commands/pull.ts +49 -56
  75. package/src/commands/push.ts +48 -54
  76. package/src/commands/render.ts +176 -111
  77. package/src/commands/scene.ts +63 -55
  78. package/src/commands/serve.ts +58 -0
  79. package/src/commands/{shaders.ts → shaders/index.ts} +61 -42
  80. package/src/commands/{shadersNew.ts → shaders/new.ts} +3 -3
  81. package/src/commands/shared.ts +79 -0
  82. package/src/commands/status.ts +22 -26
  83. package/src/commands/test.ts +94 -63
  84. package/src/commands/thumbs.ts +185 -175
  85. package/src/commands/update/index.ts +226 -0
  86. package/src/commands/{types.ts → update/types.ts} +31 -22
  87. package/src/compile/collect.ts +5 -5
  88. package/src/compile/collectLocal.ts +3 -3
  89. package/src/compile/designCompile.ts +4 -4
  90. package/src/compile/headlessBundle.ts +16 -12
  91. package/src/compile/nativeStack.ts +1 -1
  92. package/src/compile/projectCompile.ts +12 -4
  93. package/src/compile/sceneCompile.ts +14 -26
  94. package/src/compile/screenEntry.ts +123 -127
  95. package/src/compile/shaders.ts +3 -3
  96. package/src/{lecodes-3d-editor.d.ts → declarations/lecodes-3d-editor.d.ts} +4 -0
  97. package/src/{lecodes-assets.d.ts → declarations/lecodes-assets.d.ts} +1 -1
  98. package/src/{lecodes-renderer.d.ts → declarations/lecodes-headless.d.ts} +3 -3
  99. package/src/dev/androidDev.ts +1 -1
  100. package/src/dev/clientTemplates.ts +18 -14
  101. package/src/dev/devServer.ts +78 -41
  102. package/src/dev/iosDev.ts +180 -0
  103. package/src/dev/webRunner.ts +83 -15
  104. package/src/{cmgenTool.ts → hosts/cmgenTool.ts} +2 -2
  105. package/src/{desktopRenderer.ts → hosts/desktopRenderer.ts} +104 -32
  106. package/src/{desktopScript.ts → hosts/desktopScript.ts} +151 -36
  107. package/src/{distRoot.ts → hosts/distRoot.ts} +9 -5
  108. package/src/{matcTool.ts → hosts/matcTool.ts} +2 -2
  109. package/src/{peerInstall.ts → hosts/peerInstall.ts} +7 -7
  110. package/src/{peers.ts → hosts/peers.ts} +2 -2
  111. package/src/{releases.ts → hosts/releases.ts} +1 -1
  112. package/src/index.ts +35 -480
  113. package/src/platform/api.ts +302 -0
  114. package/src/{browserAuth.ts → platform/browserAuth.ts} +1 -1
  115. package/src/{config.ts → platform/config.ts} +1 -1
  116. package/src/{serverDiff.ts → platform/serverDiff.ts} +3 -3
  117. package/src/plugin/contract.ts +438 -0
  118. package/src/plugin/emitKotlin.ts +357 -0
  119. package/src/plugin/emitSdk.ts +259 -0
  120. package/src/plugin/emitSwift.ts +336 -0
  121. package/src/plugin/emitWeb.ts +383 -0
  122. package/src/plugin/generate.ts +157 -0
  123. package/src/plugin/lines.ts +28 -0
  124. package/src/plugin/lower.ts +231 -0
  125. package/src/plugin/manifest.ts +192 -0
  126. package/src/{projectEnv.ts → project/env.ts} +33 -2
  127. package/src/{ignore.ts → project/ignore.ts} +164 -163
  128. package/src/{localFiles.ts → project/localFiles.ts} +1 -1
  129. package/src/{manifest.ts → project/manifest.ts} +1 -1
  130. package/src/{project.ts → project/materialize.ts} +2 -2
  131. package/src/project/paths.ts +20 -0
  132. package/src/{textDiff.ts → project/textDiff.ts} +1 -1
  133. package/src/{types.ts → project/types.ts} +0 -0
  134. package/runtime/materials/lightmap-baked-lite.mat +0 -175
  135. package/runtime/materials/lightmap-baked.mat +0 -176
  136. package/runtime/scene-harness.json +0 -1
  137. package/runtime/web/assets/__vite-browser-external-BIHI7g3E.js +0 -1
  138. package/runtime/web/assets/basis-C64VHDVD.js +0 -1
  139. package/runtime/web/assets/basis_transcoder-VXdx5NbI.wasm +0 -0
  140. package/runtime/web/assets/createViewerLite-Ct_PZdof.js +0 -852
  141. package/runtime/web/assets/draco-BiISTFcR.js +0 -118
  142. package/runtime/web/assets/draco_decoder-DsQ12WqX.wasm +0 -0
  143. package/runtime/web/assets/index-BMt7AnC5.js +0 -2
  144. package/runtime/web/assets/mapViewImpl-B2JcES8l.js +0 -810
  145. package/runtime/web/assets/maplibre-gl-worker-CJfwIrte.js +0 -8
  146. package/runtime/web/assets/worker-Caf-yYEI.js +0 -2
  147. package/runtime/web/embed.html +0 -32
  148. package/runtime/web/embed.js +0 -171
  149. package/src/commands/design.ts +0 -846
  150. package/src/commands/update.ts +0 -211
  151. package/src/util.ts +0 -146
  152. /package/src/{lecodes-design.d.ts → declarations/lecodes-design.d.ts} +0 -0
  153. /package/src/{qrcode-terminal.d.ts → declarations/qrcode-terminal.d.ts} +0 -0
  154. /package/src/{designMeta.ts → project/designMeta.ts} +0 -0
package/README.md CHANGED
@@ -1,10 +1,21 @@
1
1
  # lecodes-cli
2
2
 
3
- Clone, edit and push [LeCodes](https://le.codes) projects from your machine, with full TypeScript
4
- IntelliSense for the platform API in your editor.
3
+ Build, run and ship [LeCodes](https://le.codes) projects from your machine: local projects with
4
+ hot reload on a device, the desktop and the browser; headless render / flow tests; the design and
5
+ scene editors; native iOS / Android / desktop shells; and the clone / push loop against the platform,
6
+ with full TypeScript IntelliSense for the SDK in your editor.
5
7
 
6
8
  The package is `lecodes-cli`; the command it installs is **`lecodes`**.
7
9
 
10
+ ```
11
+ lecodes --help # every command, grouped
12
+ lecodes <command> --help # that command's options, subcommands and examples
13
+ ```
14
+
15
+ The full reference is [docs/commands.md](docs/commands.md) — generated from the command
16
+ definitions, so it always matches `--help`. How the code is organised and how to add a command:
17
+ [CONTRIBUTING.md](CONTRIBUTING.md).
18
+
8
19
  ## Install
9
20
 
10
21
  ```sh
@@ -15,37 +26,25 @@ npx lecodes-cli <command>
15
26
 
16
27
  ### Optional peers
17
28
 
18
- Some commands live in separate packages the CLI loads on demand:
29
+ Some commands live in separate packages the CLI installs **on first use** into `~/.lecodes/peers`
30
+ (after a prompt; `--yes` / `LECODES_YES=1` skips it):
19
31
 
20
32
  | Package | Needed by |
21
33
  |---|---|
22
- | [`lecodes-renderer`](https://www.npmjs.com/package/lecodes-renderer) (`>= 0.2.0`) + `@napi-rs/canvas` for PNG | `render`, `test`, `design`'s screen previews |
23
- | [`lecodes-design`](https://www.npmjs.com/package/lecodes-design) | `design` |
24
- | [`lecodes-3d-editor`](https://www.npmjs.com/package/lecodes-3d-editor) | `scene` |
25
- | `lecodes-assets` | `assets` (FBX → GLB, doctor, retarget) |
26
-
27
- ```sh
28
- npm install -g lecodes-renderer @napi-rs/canvas
29
- ```
30
-
31
- **Install them the same way you installed the CLI.** A peer is loaded by a bare `import`, which
32
- resolves upward from the CLI's own file — so a globally installed `lecodes` sees only *globally*
33
- installed peers, and a `npm i -D` copy in your project is invisible to it. If instead you keep
34
- `lecodes-cli` in a project's `devDependencies`, install the peers there too.
34
+ | `lecodes-renderer` (pinned to the CLI's own version) + `@napi-rs/canvas` for PNG | `render`, `test`, `design snapshot` |
35
+ | `lecodes-design` | `design` |
36
+ | `lecodes-3d-editor` | `scene`, `thumbs` |
37
+ | `lecodes-assets` | `assets` |
35
38
 
36
- Under `npx` neither placement is visible; name every package in one invocation:
37
-
38
- ```sh
39
- npx -p lecodes-cli -p lecodes-assets lecodes assets convert hero.fbx -o hero.glb
40
- ```
41
-
42
- The **standalone build** below resolves nothing outside its own bundle, so `render` / `design` /
43
- `scene` / `assets` need the npm install of the CLI.
39
+ A copy you installed yourself (`npm install -g lecodes-renderer`, or in a project's
40
+ `devDependencies` next to a local `lecodes-cli`) wins over the prefix. `lecodes --version` shows
41
+ each peer's version and where it came from.
44
42
 
45
43
  **Standalone build** (the release archive, no Node/Bun needed): unpack it and run `./lecodes install`
46
44
  to copy the bundle to a library folder and put `lecodes` on your PATH — per-user by default, or
47
- `--system` for all users on Linux/macOS. (This archive ships the `lecodes` binary alongside the
48
- `chisel` bundler and a `runtime/` folder; keep them together, or let `install` place them for you.)
45
+ `--system` for all users on Linux/macOS. The archive ships the `lecodes` binary alongside the `chisel`
46
+ bundler and a `runtime/` folder; keep them together, or let `install` place them for you. The
47
+ standalone build resolves no npm packages, so the peer-backed commands need the npm install.
49
48
 
50
49
  ## Quick start
51
50
 
@@ -56,8 +55,10 @@ lecodes init myapp # scaffold a local project (starter + types
56
55
  cd myapp
57
56
  # …edit main.ts in VS Code (IntelliSense works out of the box)…
58
57
  lecodes dev # run it on a device with hot reload (scan the QR)
59
- lecodes dev --web # …and in the browser (Web Lite host; camera/map plugins have web twins)
60
- lecodes compile -o app.js # compile to a self-contained bundle for LeCodes Desktop
58
+ lecodes dev --web # …and in the browser (Web Lite host)
59
+ lecodes dev --desktop # …and in the native desktop host
60
+ lecodes render --png shot.png # a headless screenshot; `lecodes test` runs tests/*.flow.json
61
+ lecodes compile -o app.js # one self-contained bundle for LeCodes Desktop
61
62
  ```
62
63
 
63
64
  Or work against a project **on the platform**:
@@ -68,39 +69,37 @@ lecodes clone <project-uuid> myapp # download files + types into ./myapp
68
69
  cd myapp
69
70
  # …edit files in VS Code…
70
71
  lecodes status # see what changed
71
- lecodes push -m "Tweak the menu" # push as a new checkpoint
72
+ lecodes push -m "Tweak the menu" # push as a new checkpoint (--publish deploys it live)
72
73
  ```
73
74
 
74
- ## Commands
75
-
76
- | Command | What it does |
77
- | --- | --- |
78
- | `init [dir]` | Scaffold a new **local** project (no login, no server): a starter `main.ts`, the SDK types + a `tsconfig.json` for IntelliSense, and a `.lecodesignore`. Run it with `dev`, or compile it with `compile`. `dir` defaults to the current folder. Idempotent — existing files are kept. |
79
- | `install` | **Standalone build only.** Install the unpacked release bundle so `lecodes` is on your PATH: copies the `lecodes`+`chisel`+`runtime/` bundle to a library folder, then (Linux/macOS) symlinks it into a `bin` dir. PATH itself is edited only with `--modify-path` (appends `export PATH=…` to your shell rc on Linux/macOS, or adds the folder to your user PATH on Windows); otherwise it prints how to finish. Per-user by default; `--system` installs to `/usr/local` (needs sudo, and `/usr/local/bin` is already on PATH). `--dir <path>` overrides the library folder, `--bin <path>` the symlink folder. Refuses when run from an npm/source install (there, install globally with your package manager). |
80
- | `login` | Authorize in the browser; stores an access token in `~/.lecodes/config.json`. `--token <pat>` to use a token created in the web UI instead, `--api <url>` for the API origin (default `https://le.codes`), `--web <url>` for the app origin. |
81
- | `clone <uuid\|url> [dir]` | Download a project's file tree + binary resources, plus `.d.ts` types and a `tsconfig.json` for IntelliSense. `--no-types` to skip types. |
82
- | `link [dir]` | **Connect an existing local folder to the platform** — the reverse of `clone`, for a project started with `init`. Creates a project on the server (`--name`, `--team`), writes `.lecodes/manifest.json` and refreshes the types from the server; nothing is uploaded until you `push`, so `status` shows what would go up first. `--project <uuid\|url>` adopts an **existing** project instead: the manifest is built from its server tree and the command prints exactly what your next push would create/update/delete there before linking (then `push` to let local win, or `pull` to take the server's version). `--push [-m <msg>]` links and pushes in one step (`--publish` also deploys), `--force` re-links an already-linked folder, `--no-types` skips the type refresh. |
83
- | `status` | Show added / modified / moved / deleted files vs the last sync. |
84
- | `pull` | Overwrite local files with the project's current remote state. `--force` to discard local edits. |
85
- | `push` | Push all local changes as **one** new checkpoint. `-m`/`--message` for the message, `--force` to override the "server moved on" guard. |
86
- | `dev` | Run the project **on a device straight from your machine, with hot reload** — no login or server needed. Starts a LAN dev server and prints a QR code; scan it with the LeCodes app (or pass the URL to the desktop host with `?t=poll`). Every save recompiles and hot-swaps the running app in place (errors roll back to the last good version); the device's `console.log` and errors stream back to the terminal. Assets are served from the working tree; custom shaders still need a prior `push` (their artifacts compile server-side). `--port <n>` (default 4499), `--host <ip>` to override the auto-detected LAN address, `--entry <path>`, `--no-qr`. The URL stays stable across runs (token in `.lecodes/dev.json`). |
87
- | `compile` | Compile the project to a single JS bundle, printed to **stdout** (pipeable). Works on a cloned/created project (binary asset URLs resolved from the server) **or a local `init` project** (no login — `asset()` resources resolve on the host via `fetchLocal`, so the bundle is self-contained for LeCodes Desktop). `-o`/`--out <file>` to write a file, `--entry <path>` to override the entrypoint, `--no-header` to omit the metadata header, `--no-minify` to keep the bundle readable (skips chisel's compress + mangle — larger output, real identifier names), `--no-sourcemap` to skip the inlined source map (smaller output; runtime errors then report generated positions only), `--public-url <url>` to resolve assets from a URL prefix instead. Diagnostics go to stderr. Formerly `preview`, which still works as an alias. |
88
- | `design [serve]` | **LeCodes Design** — a live canvas of screens for AI-driven prototyping (needs the optional `lecodes-design` package). Works inside a cloned project **or standalone in any folder** (no login/project needed). Starts a dev server + browser board showing every `design/screens/*.ts` as a working prototype with the `meta.json` flow edges; screens hot-reload as files change. Drag an unselected screen anywhere to move it, click to select it — a selected screen is interactive (tap, scroll, type; arrow keys nudge it). The canvas edits `meta.json` directly: drag the connect handle onto another screen to draw an edge, click an edge to edit its label/activator (with a dropdown of the source screen's named elements) or delete it, click the header note to edit a description. Double-click any rendered text to edit it in place — the string literal is rewritten in the screen's source file (dynamic text is declined safely). Double-click an image (or drop an image file from your OS onto it) to replace it: the file is stored in `design/assets/` and the `asset()` path is rewritten. Hint mode (`H`) outlines interactive elements, editable texts and replaceable images; selecting or hovering an edge highlights its activator element on the source screen — and hovering that element highlights the edge. Middle-drag or scroll pans from anywhere; ctrl+wheel/pinch zooms. `--port <n>` (default 4477), `--dir <folder>` (default `design/`), `--no-open`. |
89
- | `design init` | Scaffold the design folder: `screens/`, `shared/`, `meta.json`, and a `CLAUDE.md` documenting the conventions for AI assistants. |
90
- | `design snapshot [screen…]` | Render design screens headless (needs `lecodes-renderer`). One screen → semantic JSON to stdout; otherwise JSON files in `design/.snapshots/`; `--png` also rasterizes PNGs (needs `@napi-rs/canvas`); `--out-dir <dir>`, `--logs`. |
91
- | `scene [path]` | **LeCodes Scene Editor** — visually edit a `.scene.ts` 3D scene (needs the optional `lecodes-3d-editor` package). Works inside a cloned project **or standalone in any folder**. Starts a local editor server + browser app: a scene tree, a per-node inspector, and a move/rotate/scale gizmo; add mesh/light/camera/model/aspect nodes; edits are written straight back to the `.scene.ts`, and external (IDE) edits hot-reload over SSE. Registers an MCP server in `.mcp.json` so Claude Code can call `scene_state` (scenes + models + aspect classes with field hints) and `check_scene` (compile status) — `--no-mcp` to skip. `path` is a folder or a `.scene.ts` to host (default: the current folder / enclosing project). `--port <n>` (default 4488), `--no-open`. |
92
- | `render [file]` | Render the local project (**UI + 2D**). By default emits a semantic JSON description (great for AI/automated checks) to stdout or `-o`/`--out <file>`; `--png [file]` rasterizes a PNG (default `screenshot.png`, `--scale <n>` for DPR). Naming a **screen module** (`lecodes render design/screens/login.ts`, or the bare id `login` for a `design/screens/` file) renders that one screen instead of the launched app — any file that `export default`s a `UIScreen`, or a `(state) => UIScreen` function whose branch `--state <name>` picks. It compiles as part of the project (imports and `asset()` files resolve normally), a design screen picks up its `meta.json` board frame, and the whole flag set applies — `--png`, `--clip`, `--device`, `--script`, `--desktop`. A creator-2d scene is composited **under** the UI; `--time <ms>` advances its physics/animation. `asset('./x.png')` resources (images, sprite textures) load from the local working tree by default — use `--remote-assets` (or an explicit `--public-url`) to fetch them from the server instead (which then needs `--wait-network`). `--width`/`--height` set the viewport (default 390×844). Requires the optional `lecodes-renderer` package (`npm install -g lecodes-renderer@^0.2.0`); PNG also needs `@napi-rs/canvas`. 3D scenes aren't rendered. |
93
- | `pn` | **Push notifications** for the project (`pn send` / `pn devices` / `pn keys`). `pn send --title "Order shipped" --user u42` sends through the le.codes relay **on your login — no push key needed to test** (`--to <pa_…>` targets addresses instead; `--body`, `--url`, `--badge`, `--data '{…}'` fill the payload; comma-separate multiple targets). `pn devices` lists the devices that actually called `Push.register()` — the first thing to check when a notification doesn't arrive (`--user <id>` to filter). `pn keys` manages the `lecodes_pk_…` keys you deploy in **your own server's** env: the server generates them, so `pn keys new [name]` prints the value exactly once — `--env` writes it straight into `.env` as `LECODES_PUSH_KEY` and gitignores the file. `pn keys revoke <id>` deletes one (owner only for both). |
94
- | `types [dir]` | Re-materialize the IDE type surface (`.lecodes/types/` + `tsconfig.json`). Fetches `GET /api/types` from the server by default — so a project scaffolded offline by `init` picks up the SDK the platform actually runs — falling back to the copy bundled in this CLI when the server is unreachable. `--local` to use that bundled copy outright (fully offline), `--check` to report drift without writing (exits non-zero when stale — handy in CI), `--api <url>` for the server. IDE-only: the compiler always uses the SDK vendored in the CLI, and the command warns when the two disagree. |
75
+ A local project joins the platform later with `lecodes link` (create) or
76
+ `lecodes link --project <uuid>` (adopt an existing one — it shows what your next push would change
77
+ there before connecting anything).
78
+
79
+ ## Commands at a glance
80
+
81
+ | Group | Commands |
82
+ |---|---|
83
+ | Project | `init` `create` `clone` `link` `status` `diff` `pull` `push` `login` |
84
+ | Run & test | `dev` `compile` `render` `test` `desktop` |
85
+ | Editors | `design` `scene` `thumbs` |
86
+ | Content | `assets` `shaders` `lightmap` `navmesh` |
87
+ | Native apps | `app` (ios / android / desktop shells) `pn` (push notifications) |
88
+ | Maintenance | `update` `install` |
95
89
 
96
90
  ## How it works
97
91
 
98
- - Project metadata and the path → asset map live in `.lecodes/` (commit it or not — it's like `.git`).
92
+ - Project metadata and the path → asset map live in `.lecodes/` (per-checkout state, like `.git`;
93
+ keep it out of the project's own git — `init` / `clone` write the `.gitignore` line).
99
94
  - A **push** sends your whole working tree to the server, which atomically rebuilds the project's
100
95
  file tree (adds, edits, deletes, renames and moves all at once) and freezes a single checkpoint.
101
- Renames/moves keep their history; unchanged binaries are never re-uploaded.
102
- - Types are fetched from the server on `clone`/`pull`, so they always match the deployed runtime.
103
- A local `init` project starts with the copy bundled in the CLI instead; `lecodes types` refreshes
104
- either kind on demand.
105
-
106
- Config can also be supplied via the `LECODES_API` and `LECODES_TOKEN` environment variables (useful in CI).
96
+ Renames / moves keep their history; unchanged binaries are never re-uploaded. `push` refuses to
97
+ overwrite a server that moved on; `diff` shows the conflict, `pull` takes the server's version,
98
+ `push --force` yours.
99
+ - Types are fetched from the server on `clone` / `pull` / `link`, so they match the deployed runtime.
100
+ A local `init` project starts with the copy bundled in the CLI; `lecodes update` refreshes
101
+ either kind (and the desktop host, matc, the shader compiles, the native shell pins and the
102
+ optional peers).
103
+ - Config lives in `~/.lecodes/config.json`; `LECODES_API` / `LECODES_TOKEN` override it (CI). A
104
+ `.env` next to `app.json` is read at startup for `LECODES_*` / `CREATOR_*` keys — the shell's own
105
+ environment wins, `./` paths resolve against the project, and the file is never pushed.