@neocompose/cli 0.87.1 → 0.88.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 (40) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +14 -0
  3. package/dist/neo-runtime.mjs +3789 -1141
  4. package/dist/test-worker.mjs +2450 -116
  5. package/package.json +1 -1
  6. package/skills/neocompose-cli/SKILL.md +95 -279
  7. package/skills/neocompose-cli/references/cli-development.md +101 -117
  8. package/skills/neocompose-cli/references/declarations/annotations-and-storage.md +112 -0
  9. package/skills/neocompose-cli/references/declarations/constructors.md +164 -0
  10. package/skills/neocompose-cli/references/declarations/declarations.md +103 -0
  11. package/skills/neocompose-cli/references/declarations/initializers.md +100 -0
  12. package/skills/neocompose-cli/references/declarations/member-kinds.md +107 -0
  13. package/skills/neocompose-cli/references/declarations/overloads.md +50 -0
  14. package/skills/neocompose-cli/references/dialogues.md +145 -0
  15. package/skills/neocompose-cli/references/neoscript/collections.md +98 -0
  16. package/skills/neocompose-cli/references/neoscript/control-flow.md +123 -0
  17. package/skills/neocompose-cli/references/neoscript/delegates-and-listeners.md +107 -0
  18. package/skills/neocompose-cli/references/neoscript/math-and-random.md +114 -0
  19. package/skills/neocompose-cli/references/neoscript/neoscript.md +112 -0
  20. package/skills/neocompose-cli/references/neoscript/strings.md +47 -0
  21. package/skills/neocompose-cli/references/neoscript/testing-and-migrations.md +73 -0
  22. package/skills/neocompose-cli/references/neoscript/types-and-narrowing.md +111 -0
  23. package/skills/neocompose-cli/references/sync/branches-and-history.md +69 -0
  24. package/skills/neocompose-cli/references/sync/conflicts-and-recovery.md +68 -0
  25. package/skills/neocompose-cli/references/sync/sync.md +96 -0
  26. package/skills/neocompose-cli/references/sync/unity-export.md +47 -0
  27. package/skills/neocompose-cli/references/values/defaults-and-localization.md +86 -0
  28. package/skills/neocompose-cli/references/values/files.md +71 -0
  29. package/skills/neocompose-cli/references/values/identities.md +97 -0
  30. package/skills/neocompose-cli/references/values/references.md +151 -0
  31. package/skills/neocompose-cli/references/values/values.md +110 -0
  32. package/skills/neocompose-cli/references/world/animation.md +133 -0
  33. package/skills/neocompose-cli/references/world/grids-and-cell-patterns.md +55 -0
  34. package/skills/neocompose-cli/references/world/variants.md +112 -0
  35. package/skills/neocompose-cli/references/world/world.md +105 -0
  36. package/skills/neocompose-cli/references/animation-and-world-authoring.md +0 -582
  37. package/skills/neocompose-cli/references/commands-and-sync.md +0 -408
  38. package/skills/neocompose-cli/references/declarations-and-construction.md +0 -773
  39. package/skills/neocompose-cli/references/neoscript.md +0 -990
  40. package/skills/neocompose-cli/references/values-identities-and-references.md +0 -421
@@ -1,408 +0,0 @@
1
- # Commands and synchronization
2
-
3
- Use this reference for workspace synchronization, conflicts, repair commands,
4
- branches, releases, history, and authentication.
5
-
6
- ## Contents
7
-
8
- - Pull, inspect, and push
9
- - Conflicts and files
10
- - Localization operations
11
- - Branches, releases, and history
12
- - Authentication and automation
13
-
14
- ## Pull, inspect, and push
15
-
16
- `neo doctor` fails on malformed records in the last-pulled document. Pull first to audit the current
17
- head. After a reviewed `neo doctor --fix`, pull and check again.
18
-
19
- Use the high-level source workflow:
20
-
21
- ```sh
22
- neo pull
23
- neo status
24
- neo doctor
25
- neo diff
26
- neo dialogue dryrun <dialogue-ref>
27
- neo push --dry-run
28
- neo push
29
- neo push --dry-run --force-recompile
30
- ```
31
-
32
- `neo status` reports invalid constructor parameters at their `.neo` file, line,
33
- and column. Fix the reported parameter type before pushing.
34
- A failed class or constructor declaration blocks candidate preparation.
35
-
36
- Constructor-created values keep references to their effective sibling rows when
37
- replayed. An unchanged project stays clean after push and pull, including nested
38
- constructor values with reference arguments; it does not need another push before
39
- export. Animation validation uses the project's registered files and texture
40
- templates, including when constructors supply sprite defaults.
41
-
42
- Use `neo pull --regenerate-source-names` to replace generated default dialogue
43
- names with readable ones. It keeps chosen names and rewrites references. Use
44
- `--reset` to regenerate canonical source and managed binaries. Reset retains
45
- declaration file grouping already recorded by the workspace, while
46
- declarations with no prior placement use the canonical per-declaration layout. Use `--force` only to discard local edits for the server
47
- version. Normal pulls persist a transaction cursor and fetch only changed
48
- records. Dictionary string keys, including Unicode, `_id`, `$name`, and `__proto__`,
49
- round-trip through full and incremental reads. String keys may be empty or contain
50
- whitespace; enum keys must name a live enum option. If the remote head is unchanged, pull preserves the local source
51
- without compiling it; use `neo status` to inspect local edits and diagnostics.
52
- Pull ignores records whose hashes already match the saved server baseline,
53
- including echoes of this checkout's last push, and advances its cursor without
54
- compiling or rewriting source. Later remote edits still count as changes.
55
- An undo/reset metadata change invalidates the cursor and causes a safe
56
- full-snapshot fallback.
57
-
58
- After a compiler upgrade, run `neo pull` with `.neo/state.json` intact. Pull
59
- refreshes every cached record whose remote change touches only compiler-owned
60
- bodies or timestamps before local compilation, even when the same pull merges
61
- other changes. When nothing else changed, it leaves authored files and managed
62
- binaries untouched. Added or deleted records, authored changes, and unresolved
63
- conflicts take the normal merge path. Status, push, and pull refuse a baseline
64
- holding a compiled body this CLI rejects and name the record. If `neo pull`
65
- cannot refresh it, back up local edits and run `neo pull --force`.
66
-
67
- If a push commits but source rewriting fails, `neo pull` resumes its saved
68
- result before checking the remote head. The recovery journal in `.neo/state.json`
69
- retains committed identities and any prepared file replacements. Interrupted
70
- file writes resume without parsing a partially rewritten checkout. If a file
71
- was edited again after that plan was saved, recovery stops and names the file;
72
- preserve that edit separately before restoring the expected content and retrying.
73
- `--reset` and `--force` explicitly discard local edits and can bypass recovery.
74
-
75
- Keep `.neo/state.json`: it holds the merge baseline and source placements.
76
- Normal pull refuses existing production sources without that baseline. To
77
- deliberately replace a checkout whose state is gone, back it up first and use
78
- `neo pull --force`; the CLI recovers custom paths from the remaining declarations.
79
- The force pull replaces local source with the server version.
80
-
81
- Pull downloads up to eight managed image or audio files concurrently and reuses
82
- matching local bytes. It verifies all downloads before replacing binaries or
83
- updating conflict artifacts. A failed transfer leaves existing files intact;
84
- retry the pull after resolving the reported download error.
85
-
86
- Full document pulls size pages against Convex resource limits and fetch
87
- independent remaining ranges concurrently. Pull pins every page and snapshot
88
- batch to one published generation and logical revision. If either changes during assembly, the CLI discards the attempt and
89
- restarts. Upgrade the CLI together with the P83 server read protocol.
90
-
91
- Treat `neo push --dry-run` as a full local commit rehearsal: source emission,
92
- in-memory pending-ID assignment, transport shapes, hashes, and repeat
93
- verification all run. It also runs the preparation a real push ships —
94
- compilation, schema-commit materialization, seeded structural rows, and
95
- whole-graph validation — so a rejection reports before anything is sent. It
96
- does not prompt, upload, commit, or rewrite source.
97
-
98
- Removing a class or collection declaration also deletes its hidden collection
99
- entry members, including nested lists and dictionaries. Replacing a collection
100
- with a scalar deletes its abandoned entries too. Entries used by surviving
101
- declarations are retained. If a member is deleted locally before pulling remote
102
- instance values, pull retains those values in the deletion plan; the next push
103
- removes them with the member. Review these derived deletions in `neo status` or
104
- `neo diff` before pushing.
105
-
106
- Dry-run also compares the CLI's derived-edge extractor with the server version
107
- saved by the last pull. Run `neo pull` after upgrading the CLI or when an older
108
- workspace lacks that metadata. A newer server extractor requires a CLI
109
- upgrade; a newer CLI extractor requires the server watermark to be repaired.
110
-
111
- Normal preparation follows typed compiler dependencies and recompiles only
112
- bodies affected by changed declarations. Use `--force-recompile` with either a
113
- dry run or a real push only when diagnosing stale derived IR: it retains the
114
- exhaustive project-wide body sweep and is intentionally slower.
115
-
116
- Changed member bodies and migration bodies share one schema projection and its
117
- indexes throughout push preparation, so a batch of scripted changes does not
118
- rebuild the whole schema for every body. Each changed body compiles once for
119
- local evaluation and once more, against minted ids, in the preparation the push
120
- ships.
121
-
122
- Interactive status, diff, pull, and test commands report workspace loading and
123
- preparation phases. Spinners continue animating during synchronous compilation;
124
- `NO_COLOR` removes color without stopping the animation. JSON reporters and
125
- piped status/test output contain no terminal animation.
126
-
127
- Interactive pushes report the active preparation phase before workspace
128
- discovery, lowering, compilation, source hashing, and validation begin.
129
- A normal push prepares that transport once before confirmation and reuses it
130
- after confirmation; it does not run a second local preparation pass. JSON and
131
- non-TTY output remain structured and do not emit that terminal-only spinner.
132
-
133
- A clean dry-run does not promise a clean push. The workspace holds its
134
- last-pulled state, so the server still grades the live head: the project-head
135
- check, per-change CAS bases, authorization, row shapes, project-file staging,
136
- admission, chunk planning, and finalization. A push whose head moved fails as
137
- `non-fast-forward`. Pull again before pushing if time has passed.
138
-
139
- Durable preparation is selected from the semantic record workload, not the
140
- size of the project-wide source identity. Its storage artifact carries one
141
- copy of the prepared transaction, and resumable staging reads one plan per
142
- bounded batch while preserving an atomic write boundary per physical chunk.
143
- The complete source stays local. Normal push hashes the exact authored source
144
- inputs already read during preparation, including file paths and formatting,
145
- without regenerating canonical source. The same source bytes and workspace base
146
- retain reconnect identity across candidate UUID allocation. A formatting or path
147
- change produces a new identity. Dry-run uses the same authored hash and separately
148
- rehearses the complete canonical source round trip. A lowering mismatch can
149
- therefore surface on the next canonical pull; dry-run is the opt-in full
150
- source-to-record proof.
151
-
152
- When a transaction commits, its status response carries the first bounded result
153
- page. The CLI downloads further pages when needed and validates the full result
154
- count before advancing its base. Result application rechecks source bytes,
155
- managed binaries, and the workspace base before reusing local preparation; edits
156
- made while waiting trigger fresh analysis and the existing merge behavior.
157
-
158
- One accepted push atomically commits records, main-locale text, stored bindings,
159
- and staged file metadata under CAS. Pending durable IDs and source rewrites
160
- become real only after acceptance.
161
-
162
- ## Conflicts and files
163
-
164
- Conflict resolution accepts LF, CRLF, and mixed line endings. It retains the
165
- selected source lines and their existing line endings. Choosing a deleted side
166
- removes the source file; deletion placeholders are display text, not authored
167
- source. Empty files and ordinary comment-only files remain files.
168
-
169
- Resolve source conflicts by editing the final intended source. Use
170
- `neo resolve --mine` or `neo resolve --theirs` only for a deliberate whole-side
171
- choice. Pull, inspect, dry-run, and retry; there is no force-CAS path.
172
-
173
- One record is one conflict, however many files declare it. A member declared by
174
- more than one class is marked in every declaring file, and `neo resolve`
175
- settles those files together; it refuses a record whose declarations are only
176
- partly resolved rather than settling the rest to the other side and leaving the
177
- declarations disagreeing.
178
-
179
- Compiled initializer IR is server-owned and does not participate in authored
180
- three-way merge decisions. Either `neo resolve` side adopts the server side as
181
- the new base for every conflict it settles — `--theirs` then reads clean, and
182
- `--mine` keeps the local text as an ordinary update on top of that base. That
183
- includes metadata-only conflict bookkeeping left by an older pull when no
184
- source marker exists; adopting the server base never overwrites tracked
185
- source.
186
-
187
- A `value-base-desync` error means the workspace base no longer names value
188
- rows its own file projection holds, so the plan would delete live server rows.
189
- Nothing is planned in that state; run `neo pull` and retry. The same message
190
- as a warning reports the inconsistency without blocking.
191
-
192
- When pull conflicts with a server-side deletion, keeping the authored record
193
- restores it as an explicit create guarded by an absent-record CAS check;
194
- removing it from the resolved source accepts the deletion without sending a
195
- write. Pull also warns immediately when a conflicted record's retained local
196
- base strands newly downloaded descendant value rows. Resolve that conflict
197
- with `neo resolve --mine` or `neo resolve --theirs` before pushing.
198
-
199
- For `base-hash-conflict`, pull and merge. For `version-bump-required`, inspect
200
- the classification and use `neo push --accept-bump` only when the bump is
201
- intended.
202
-
203
- Add, replace, or remove managed binaries and their typed registry declarations
204
- in tracked source. `neo push` stages their metadata and verified bytes with the
205
- source transaction. Keep local bytes during binary conflict resolution and
206
- inspect the server copy under `.neo/conflicts/files/<file-id>/`.
207
-
208
- ## Localization operations
209
-
210
- Main-locale strings are authored in `.neo` and `.neoflow`, but those files do
211
- not represent the full localization record. Use `neo loc` for other locales,
212
- statuses, comments, archives, and targeted localization repair:
213
-
214
- ```sh
215
- neo loc locales
216
- neo loc list
217
- neo loc set <textId> <locale> "text"
218
- neo loc status-set <textId> <locale> <statusId>
219
- neo loc comment-set <textId> <locale> "comment"
220
- neo loc archive <textId>
221
- neo loc restore <textId>
222
- ```
223
-
224
- Pass a JSON-array batch on stdin or `--file` where supported. Localization
225
- commands do not rewrite local project source. Run `neo pull` after any
226
- `neo loc` or web mutation before further source edits or push.
227
-
228
- ## Branches, releases, and history
229
-
230
- ```sh
231
- neo branch list
232
- neo branch create <name> [--from <ref>]
233
- neo branch switch <nameOrId>
234
- neo branch refresh [--dry-run]
235
- neo merge <branch> [--dry-run] [--migrate]
236
- neo release cut [--bump major|minor|patch] [--dry-run]
237
- neo history inspect
238
- neo history log
239
- neo history prune [--project <id|@latest|@current>]
240
- neo history flatten [--project <id|@latest|@current>] --version <id|@latest|@current>
241
- neo history apply --plan <plan-id> [--confirm-scope <project-id>[/<version-id>]]
242
- neo history status --run <run-id>
243
- neo history resume --run <run-id>
244
- ```
245
-
246
- Branch switching requires a clean working copy. Unpushed source or binary
247
- changes, unresolved conflicts, source errors, and pending push recovery stop the
248
- switch before it changes the selected version or baseline. Push or back up edits
249
- first; use `neo pull --force` only when discarding them is intended.
250
-
251
- Treat branches as copy-on-write forks and releases as immutable snapshots. The
252
- server derives the minimum compatibility bump; a caller may only raise it.
253
- Require the release login profile for release operations.
254
- Branch creation waits for the durable copy to publish before reporting success.
255
- The source stays readable while copying; the destination becomes readable only
256
- after verification and publication.
257
-
258
- History rewrites require project owner or admin authority. `prune` and
259
- `flatten` create immutable plans without deleting anything. `apply` starts the
260
- destructive run after the plan has sealed. Production also requires the exact
261
- scope confirmation shown by the plan. CLI
262
- tokens issued before 0.36.12 do not hold the history write grant, so run
263
- `neo logout` followed by `neo login` once after upgrading.
264
-
265
- ## Authentication and automation
266
-
267
- ```sh
268
- neo login [--api <url>] [--profile editor|release] [--save-project <id>]
269
- neo doctor
270
- ```
271
-
272
- `login`, `whoami`, and `logout` use the current workspace's `apiBaseUrl` when
273
- run beneath a `neo.json`. An explicit `--api` takes priority. Outside a
274
- workspace, they use the CLI build's default API origin. Login prints the
275
- selected origin before it requests or stores a credential.
276
-
277
- `neo doctor` checks authoring contracts (format, compiler, extension cache, source,
278
- files) and the last pull's document integrity. Malformed records fail the command.
279
- The partition audit follows ownership: a lookup can reference a value stored in a
280
- different partition without moving it into the lookup's partition. The document
281
- audit also reports base rows no emitted file projects and no record names; these
282
- rows are invisible to `neo status`.
283
- `neo doctor --json` carries a `repair` entry per finding, which is what a
284
- targeted repair is handed instead of scanning a project to rediscover them.
285
- `neo doctor --fix` consumes those entries for the `unprojected-value-row`
286
- findings: it lists each orphan root with the number of rows it owns, confirms,
287
- then deletes them. Two guards make a stale audit fail the commit rather than
288
- delete a row that has since gained an owner: every row carries the CAS base the
289
- last pull recorded, and every transaction expects the version head the previous
290
- one produced, starting from the head that pull left. Adopting an orphan writes
291
- its new owner rather than the row itself, so only the head guard sees that, and
292
- a workspace with no recorded head is refused rather than written blind. More
293
- rows than one transaction budgets for go up in batches sized from the shared
294
- cost model against the immediate commit path. `--yes` answers the confirmation
295
- for scripted runs, and `--fix` has no `--json` form. No other finding kind has
296
- an automatic repair.
297
-
298
- The Node CLI talks directly to authenticated Convex APIs through the
299
- session-gated CAS boundary. Tokens use the OS credential store when available
300
- and a protected file only as fallback. Use `NEO_COMPOSE_TOKEN` or
301
- `--token-stdin` in CI. The CLI automatically re-mints its short-lived Convex
302
- JWT before expiry during long-running commands; the stored device session
303
- remains the credential. The editor profile cannot publish releases; server
304
- scopes remain the security boundary.
305
-
306
- `neo logout [--api <url>]` deletes the stored credential for exactly one API
307
- origin (keychain entry and credentials-file row) and revokes the server
308
- session best-effort. It never clears other origins or the whole store.
309
-
310
- Isolated environments (P53 agent rigs) set `NEO_COMPOSE_CONFIG_HOME` (an
311
- absolute directory replacing `$XDG_CONFIG_HOME/neo-compose` for Neo state
312
- only) and `NEO_COMPOSE_CREDENTIAL_NAMESPACE` (scopes the OS-keychain account)
313
- so concurrent environments sharing one OS user cannot read, overwrite, or
314
- delete each other's tokens. Login, logout, and authenticated commands all
315
- honor both variables.
316
-
317
- Boolean flags are switches: pass `--dry-run` or `--help` without a value.
318
- Values such as `--dry-run=true` are rejected before a command runs.
319
- `--dry-run` is supported by push, merge, refresh, branch refresh, release cut,
320
- and migrate run. Other commands reject it before taking action. Branch options
321
- are scoped to their subcommands; branch create does not support dry-run.
322
-
323
- Pass explicit project/version IDs and flags in automation. Prefer `--json` for
324
- machine-readable output and do not depend on interactive pickers or confirms.
325
-
326
- ## Unity export
327
-
328
- `neo export` builds the Unity export from the working copy, offline, and writes
329
- it into the directories the Unity project's `NeoComposeConfig` asset names:
330
- `project.json` with a partition index, `Partitions/*.json` holding value rows
331
- by storage partition, localization files, and generated C# under
332
- `<generatedTypesDirectory>/Generated/`. It writes only files whose bytes
333
- changed, skips codegen when its schema inputs are unchanged, and writes
334
- `Library/NeoCompose/export.json` last for Unity to ingest. Exports remember
335
- recent results by their exact inputs, so a repeated export, an undo, or a revert
336
- to earlier content reuses that result after verifying output bytes; changed or
337
- missing outputs are regenerated. Edited content is validated
338
- even when C# generation is skipped. After a CLI code-generation fix, run
339
- `neo export` again; generator revision changes invalidate cached C# output.
340
- Generated animation clip targets and reference lookup factories retain constructed
341
- generic arguments, including supported forwarded bindings. Clip getters use the
342
- declared target type when the owner is a derived class. Export reports an error
343
- when a clip target does not match the owner or one of its constructed base types.
344
- Inherited collection interface getters preserve supported detached temporaries.
345
- Constructed entries such as `Frame<T>` use the interface's generic argument
346
- family for both their collection type and value converters.
347
- New instances that reuse existing member-localized text retain its shared ID
348
- and translations in the export.
349
-
350
- - A clean working copy exports the pulled head. Diagnostic location differences
351
- alone, including line shifts after push inserts ids, do not make it local.
352
- Local edits, `Files/` bytes
353
- included, make the export local: `project.json` gets
354
- `metadata.localExport`, Unity fails player builds and keeps saves under
355
- `NeoCompose/LocalExport`, and a push or a clean export ends it.
356
- - Ids minted for local declarations are kept in `.neo/export.json`'s
357
- `identityLedger`, so the push commits the ids Unity already saw. A push
358
- re-exports into the Unity project a local export went to.
359
- - `neo dev` watches before its initial export and batches relevant source,
360
- binary, ignore-rule, workspace-state, and config changes. It waits for a
361
- 20 ms quiet period, capped at 250 ms, and processes edits made during an
362
- export in the next batch. It never pulls or pushes.
363
- - Pull, push, branch, merge, resolve, init and export take turns through
364
- `.neo/workspace.lock`; a lock whose process died is taken over.
365
-
366
- - The Unity project comes from `unityConfigPath`. Without it, an interactive
367
- export offers to link the one config asset naming this project; scripts get
368
- an error with the line to add.
369
- - `--unity-project <dir>` exports into another Unity project without linking
370
- it. Agent rigs use it.
371
- - A source error, a file conflict, a `download` file action, an error
372
- diagnostic, or an unchanged project file whose bytes differ from the pulled
373
- file stops the export before anything is written.
374
- - `NeoGeneratedFiles.json` keeps `.meta` GUIDs across type renames. Keep it
375
- with the generated files.
376
-
377
- ## Push timing diagnostics
378
-
379
- Set `NEO_COMPOSE_TRACE_PERFORMANCE=1` when measuring a push. It writes
380
- `neo-performance` JSON lines to stderr for workspace loading, local candidate
381
- preparation, file uploads, submission, authentication, live transaction completion,
382
- result download, and local result application. `startedMs` is relative to the
383
- CLI process and `durationMs` covers the named operation. Nested spans overlap;
384
- do not add all durations. Normal command JSON remains on stdout.
385
-
386
- Each command opens one Convex websocket, authenticated with the scoped
387
- session's refreshing JWT, and runs every query, mutation, and subscription over
388
- it. Push sends compressed JSON through `clientCommits.commit` when the request
389
- has no staged files and decodes to at most 512 KiB; otherwise it streams chunks
390
- through `begin`, `appendChunks`, and `seal`, and subscribes to completion. The
391
- CLI pins the deployment through the authenticated app origin before sending it
392
- a session token.
393
- Results pin the workspace to that transaction's hash, so a concurrent later commit still
394
- requires a pull before another push.
395
-
396
- ## Test execution
397
-
398
- `neo test` compiles unpushed production source and validates the candidate graph.
399
- It does not perform the additional source serialization round trip that
400
- `neo push --dry-run` uses. Invalid production source still stops test execution.
401
- Unchanged project and spec inputs reuse content-addressed local caches.
402
-
403
- Spec files run in parallel using up to four available CPU workers. Set
404
- `test.maxWorkers` in `neo.json`, override it with `neo test --maxWorkers <n>`,
405
- or use `neo test --runInBand` to run serially. Each file preserves hook and test
406
- order; fixtures and mocks stay isolated. Reports retain discovery order.
407
- Parallel test work is summed across workers and can exceed elapsed execution;
408
- JSON `timings.executeMs` and `timings.workerStartupMs` give elapsed phase times.