@neocompose/cli 0.1.6 → 0.2.1

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 (167) hide show
  1. package/README.md +203 -69
  2. package/dist/neo.mjs +28486 -15261
  3. package/dist/tooling/Microsoft.CodeAnalysis.CSharp.dll +0 -0
  4. package/dist/tooling/Microsoft.CodeAnalysis.dll +0 -0
  5. package/dist/tooling/NeoCompose.Schema.Tooling.dll +0 -0
  6. package/dist/tooling/NeoCompose.Schema.Tooling.pdb +0 -0
  7. package/dist/tooling/NeoCompose.Schema.dll +0 -0
  8. package/dist/tooling/NeoCompose.Schema.pdb +0 -0
  9. package/dist/tooling/NeoCompose.Schema.xml +1055 -0
  10. package/dist/tooling/NeoCompose.SchemaCompiler.deps.json +299 -0
  11. package/dist/tooling/NeoCompose.SchemaCompiler.dll +0 -0
  12. package/dist/tooling/NeoCompose.SchemaCompiler.pdb +0 -0
  13. package/dist/tooling/NeoCompose.SchemaCompiler.runtimeconfig.json +13 -0
  14. package/dist/tooling/System.Collections.Immutable.dll +0 -0
  15. package/dist/tooling/System.Reflection.Metadata.dll +0 -0
  16. package/dist/tooling/System.Text.Encoding.CodePages.dll +0 -0
  17. package/dist/tooling/cs/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  18. package/dist/tooling/cs/Microsoft.CodeAnalysis.resources.dll +0 -0
  19. package/dist/tooling/de/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  20. package/dist/tooling/de/Microsoft.CodeAnalysis.resources.dll +0 -0
  21. package/dist/tooling/es/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  22. package/dist/tooling/es/Microsoft.CodeAnalysis.resources.dll +0 -0
  23. package/dist/tooling/fr/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  24. package/dist/tooling/fr/Microsoft.CodeAnalysis.resources.dll +0 -0
  25. package/dist/tooling/it/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  26. package/dist/tooling/it/Microsoft.CodeAnalysis.resources.dll +0 -0
  27. package/dist/tooling/ja/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  28. package/dist/tooling/ja/Microsoft.CodeAnalysis.resources.dll +0 -0
  29. package/dist/tooling/ko/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  30. package/dist/tooling/ko/Microsoft.CodeAnalysis.resources.dll +0 -0
  31. package/dist/tooling/pl/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  32. package/dist/tooling/pl/Microsoft.CodeAnalysis.resources.dll +0 -0
  33. package/dist/tooling/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  34. package/dist/tooling/pt-BR/Microsoft.CodeAnalysis.resources.dll +0 -0
  35. package/dist/tooling/reference-assemblies/netstandard2.1/Microsoft.Win32.Primitives.dll +0 -0
  36. package/dist/tooling/reference-assemblies/netstandard2.1/System.AppContext.dll +0 -0
  37. package/dist/tooling/reference-assemblies/netstandard2.1/System.Buffers.dll +0 -0
  38. package/dist/tooling/reference-assemblies/netstandard2.1/System.Collections.Concurrent.dll +0 -0
  39. package/dist/tooling/reference-assemblies/netstandard2.1/System.Collections.NonGeneric.dll +0 -0
  40. package/dist/tooling/reference-assemblies/netstandard2.1/System.Collections.Specialized.dll +0 -0
  41. package/dist/tooling/reference-assemblies/netstandard2.1/System.Collections.dll +0 -0
  42. package/dist/tooling/reference-assemblies/netstandard2.1/System.ComponentModel.Composition.dll +0 -0
  43. package/dist/tooling/reference-assemblies/netstandard2.1/System.ComponentModel.EventBasedAsync.dll +0 -0
  44. package/dist/tooling/reference-assemblies/netstandard2.1/System.ComponentModel.Primitives.dll +0 -0
  45. package/dist/tooling/reference-assemblies/netstandard2.1/System.ComponentModel.TypeConverter.dll +0 -0
  46. package/dist/tooling/reference-assemblies/netstandard2.1/System.ComponentModel.dll +0 -0
  47. package/dist/tooling/reference-assemblies/netstandard2.1/System.Console.dll +0 -0
  48. package/dist/tooling/reference-assemblies/netstandard2.1/System.Core.dll +0 -0
  49. package/dist/tooling/reference-assemblies/netstandard2.1/System.Data.Common.dll +0 -0
  50. package/dist/tooling/reference-assemblies/netstandard2.1/System.Data.dll +0 -0
  51. package/dist/tooling/reference-assemblies/netstandard2.1/System.Diagnostics.Contracts.dll +0 -0
  52. package/dist/tooling/reference-assemblies/netstandard2.1/System.Diagnostics.Debug.dll +0 -0
  53. package/dist/tooling/reference-assemblies/netstandard2.1/System.Diagnostics.FileVersionInfo.dll +0 -0
  54. package/dist/tooling/reference-assemblies/netstandard2.1/System.Diagnostics.Process.dll +0 -0
  55. package/dist/tooling/reference-assemblies/netstandard2.1/System.Diagnostics.StackTrace.dll +0 -0
  56. package/dist/tooling/reference-assemblies/netstandard2.1/System.Diagnostics.TextWriterTraceListener.dll +0 -0
  57. package/dist/tooling/reference-assemblies/netstandard2.1/System.Diagnostics.Tools.dll +0 -0
  58. package/dist/tooling/reference-assemblies/netstandard2.1/System.Diagnostics.TraceSource.dll +0 -0
  59. package/dist/tooling/reference-assemblies/netstandard2.1/System.Diagnostics.Tracing.dll +0 -0
  60. package/dist/tooling/reference-assemblies/netstandard2.1/System.Drawing.Primitives.dll +0 -0
  61. package/dist/tooling/reference-assemblies/netstandard2.1/System.Drawing.dll +0 -0
  62. package/dist/tooling/reference-assemblies/netstandard2.1/System.Dynamic.Runtime.dll +0 -0
  63. package/dist/tooling/reference-assemblies/netstandard2.1/System.Globalization.Calendars.dll +0 -0
  64. package/dist/tooling/reference-assemblies/netstandard2.1/System.Globalization.Extensions.dll +0 -0
  65. package/dist/tooling/reference-assemblies/netstandard2.1/System.Globalization.dll +0 -0
  66. package/dist/tooling/reference-assemblies/netstandard2.1/System.IO.Compression.FileSystem.dll +0 -0
  67. package/dist/tooling/reference-assemblies/netstandard2.1/System.IO.Compression.ZipFile.dll +0 -0
  68. package/dist/tooling/reference-assemblies/netstandard2.1/System.IO.Compression.dll +0 -0
  69. package/dist/tooling/reference-assemblies/netstandard2.1/System.IO.FileSystem.DriveInfo.dll +0 -0
  70. package/dist/tooling/reference-assemblies/netstandard2.1/System.IO.FileSystem.Primitives.dll +0 -0
  71. package/dist/tooling/reference-assemblies/netstandard2.1/System.IO.FileSystem.Watcher.dll +0 -0
  72. package/dist/tooling/reference-assemblies/netstandard2.1/System.IO.FileSystem.dll +0 -0
  73. package/dist/tooling/reference-assemblies/netstandard2.1/System.IO.IsolatedStorage.dll +0 -0
  74. package/dist/tooling/reference-assemblies/netstandard2.1/System.IO.MemoryMappedFiles.dll +0 -0
  75. package/dist/tooling/reference-assemblies/netstandard2.1/System.IO.Pipes.dll +0 -0
  76. package/dist/tooling/reference-assemblies/netstandard2.1/System.IO.UnmanagedMemoryStream.dll +0 -0
  77. package/dist/tooling/reference-assemblies/netstandard2.1/System.IO.dll +0 -0
  78. package/dist/tooling/reference-assemblies/netstandard2.1/System.Linq.Expressions.dll +0 -0
  79. package/dist/tooling/reference-assemblies/netstandard2.1/System.Linq.Parallel.dll +0 -0
  80. package/dist/tooling/reference-assemblies/netstandard2.1/System.Linq.Queryable.dll +0 -0
  81. package/dist/tooling/reference-assemblies/netstandard2.1/System.Linq.dll +0 -0
  82. package/dist/tooling/reference-assemblies/netstandard2.1/System.Memory.dll +0 -0
  83. package/dist/tooling/reference-assemblies/netstandard2.1/System.Net.Http.dll +0 -0
  84. package/dist/tooling/reference-assemblies/netstandard2.1/System.Net.NameResolution.dll +0 -0
  85. package/dist/tooling/reference-assemblies/netstandard2.1/System.Net.NetworkInformation.dll +0 -0
  86. package/dist/tooling/reference-assemblies/netstandard2.1/System.Net.Ping.dll +0 -0
  87. package/dist/tooling/reference-assemblies/netstandard2.1/System.Net.Primitives.dll +0 -0
  88. package/dist/tooling/reference-assemblies/netstandard2.1/System.Net.Requests.dll +0 -0
  89. package/dist/tooling/reference-assemblies/netstandard2.1/System.Net.Security.dll +0 -0
  90. package/dist/tooling/reference-assemblies/netstandard2.1/System.Net.Sockets.dll +0 -0
  91. package/dist/tooling/reference-assemblies/netstandard2.1/System.Net.WebHeaderCollection.dll +0 -0
  92. package/dist/tooling/reference-assemblies/netstandard2.1/System.Net.WebSockets.Client.dll +0 -0
  93. package/dist/tooling/reference-assemblies/netstandard2.1/System.Net.WebSockets.dll +0 -0
  94. package/dist/tooling/reference-assemblies/netstandard2.1/System.Net.dll +0 -0
  95. package/dist/tooling/reference-assemblies/netstandard2.1/System.Numerics.Vectors.dll +0 -0
  96. package/dist/tooling/reference-assemblies/netstandard2.1/System.Numerics.dll +0 -0
  97. package/dist/tooling/reference-assemblies/netstandard2.1/System.ObjectModel.dll +0 -0
  98. package/dist/tooling/reference-assemblies/netstandard2.1/System.Reflection.DispatchProxy.dll +0 -0
  99. package/dist/tooling/reference-assemblies/netstandard2.1/System.Reflection.Emit.ILGeneration.dll +0 -0
  100. package/dist/tooling/reference-assemblies/netstandard2.1/System.Reflection.Emit.Lightweight.dll +0 -0
  101. package/dist/tooling/reference-assemblies/netstandard2.1/System.Reflection.Emit.dll +0 -0
  102. package/dist/tooling/reference-assemblies/netstandard2.1/System.Reflection.Extensions.dll +0 -0
  103. package/dist/tooling/reference-assemblies/netstandard2.1/System.Reflection.Primitives.dll +0 -0
  104. package/dist/tooling/reference-assemblies/netstandard2.1/System.Reflection.dll +0 -0
  105. package/dist/tooling/reference-assemblies/netstandard2.1/System.Resources.Reader.dll +0 -0
  106. package/dist/tooling/reference-assemblies/netstandard2.1/System.Resources.ResourceManager.dll +0 -0
  107. package/dist/tooling/reference-assemblies/netstandard2.1/System.Resources.Writer.dll +0 -0
  108. package/dist/tooling/reference-assemblies/netstandard2.1/System.Runtime.CompilerServices.VisualC.dll +0 -0
  109. package/dist/tooling/reference-assemblies/netstandard2.1/System.Runtime.Extensions.dll +0 -0
  110. package/dist/tooling/reference-assemblies/netstandard2.1/System.Runtime.Handles.dll +0 -0
  111. package/dist/tooling/reference-assemblies/netstandard2.1/System.Runtime.InteropServices.RuntimeInformation.dll +0 -0
  112. package/dist/tooling/reference-assemblies/netstandard2.1/System.Runtime.InteropServices.dll +0 -0
  113. package/dist/tooling/reference-assemblies/netstandard2.1/System.Runtime.Numerics.dll +0 -0
  114. package/dist/tooling/reference-assemblies/netstandard2.1/System.Runtime.Serialization.Formatters.dll +0 -0
  115. package/dist/tooling/reference-assemblies/netstandard2.1/System.Runtime.Serialization.Json.dll +0 -0
  116. package/dist/tooling/reference-assemblies/netstandard2.1/System.Runtime.Serialization.Primitives.dll +0 -0
  117. package/dist/tooling/reference-assemblies/netstandard2.1/System.Runtime.Serialization.Xml.dll +0 -0
  118. package/dist/tooling/reference-assemblies/netstandard2.1/System.Runtime.Serialization.dll +0 -0
  119. package/dist/tooling/reference-assemblies/netstandard2.1/System.Runtime.dll +0 -0
  120. package/dist/tooling/reference-assemblies/netstandard2.1/System.Security.Claims.dll +0 -0
  121. package/dist/tooling/reference-assemblies/netstandard2.1/System.Security.Cryptography.Algorithms.dll +0 -0
  122. package/dist/tooling/reference-assemblies/netstandard2.1/System.Security.Cryptography.Csp.dll +0 -0
  123. package/dist/tooling/reference-assemblies/netstandard2.1/System.Security.Cryptography.Encoding.dll +0 -0
  124. package/dist/tooling/reference-assemblies/netstandard2.1/System.Security.Cryptography.Primitives.dll +0 -0
  125. package/dist/tooling/reference-assemblies/netstandard2.1/System.Security.Cryptography.X509Certificates.dll +0 -0
  126. package/dist/tooling/reference-assemblies/netstandard2.1/System.Security.Principal.dll +0 -0
  127. package/dist/tooling/reference-assemblies/netstandard2.1/System.Security.SecureString.dll +0 -0
  128. package/dist/tooling/reference-assemblies/netstandard2.1/System.ServiceModel.Web.dll +0 -0
  129. package/dist/tooling/reference-assemblies/netstandard2.1/System.Text.Encoding.Extensions.dll +0 -0
  130. package/dist/tooling/reference-assemblies/netstandard2.1/System.Text.Encoding.dll +0 -0
  131. package/dist/tooling/reference-assemblies/netstandard2.1/System.Text.RegularExpressions.dll +0 -0
  132. package/dist/tooling/reference-assemblies/netstandard2.1/System.Threading.Overlapped.dll +0 -0
  133. package/dist/tooling/reference-assemblies/netstandard2.1/System.Threading.Tasks.Extensions.dll +0 -0
  134. package/dist/tooling/reference-assemblies/netstandard2.1/System.Threading.Tasks.Parallel.dll +0 -0
  135. package/dist/tooling/reference-assemblies/netstandard2.1/System.Threading.Tasks.dll +0 -0
  136. package/dist/tooling/reference-assemblies/netstandard2.1/System.Threading.Thread.dll +0 -0
  137. package/dist/tooling/reference-assemblies/netstandard2.1/System.Threading.ThreadPool.dll +0 -0
  138. package/dist/tooling/reference-assemblies/netstandard2.1/System.Threading.Timer.dll +0 -0
  139. package/dist/tooling/reference-assemblies/netstandard2.1/System.Threading.dll +0 -0
  140. package/dist/tooling/reference-assemblies/netstandard2.1/System.Transactions.dll +0 -0
  141. package/dist/tooling/reference-assemblies/netstandard2.1/System.ValueTuple.dll +0 -0
  142. package/dist/tooling/reference-assemblies/netstandard2.1/System.Web.dll +0 -0
  143. package/dist/tooling/reference-assemblies/netstandard2.1/System.Windows.dll +0 -0
  144. package/dist/tooling/reference-assemblies/netstandard2.1/System.Xml.Linq.dll +0 -0
  145. package/dist/tooling/reference-assemblies/netstandard2.1/System.Xml.ReaderWriter.dll +0 -0
  146. package/dist/tooling/reference-assemblies/netstandard2.1/System.Xml.Serialization.dll +0 -0
  147. package/dist/tooling/reference-assemblies/netstandard2.1/System.Xml.XDocument.dll +0 -0
  148. package/dist/tooling/reference-assemblies/netstandard2.1/System.Xml.XPath.XDocument.dll +0 -0
  149. package/dist/tooling/reference-assemblies/netstandard2.1/System.Xml.XPath.dll +0 -0
  150. package/dist/tooling/reference-assemblies/netstandard2.1/System.Xml.XmlDocument.dll +0 -0
  151. package/dist/tooling/reference-assemblies/netstandard2.1/System.Xml.XmlSerializer.dll +0 -0
  152. package/dist/tooling/reference-assemblies/netstandard2.1/System.Xml.dll +0 -0
  153. package/dist/tooling/reference-assemblies/netstandard2.1/System.dll +0 -0
  154. package/dist/tooling/reference-assemblies/netstandard2.1/mscorlib.dll +0 -0
  155. package/dist/tooling/reference-assemblies/netstandard2.1/netstandard.dll +0 -0
  156. package/dist/tooling/ru/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  157. package/dist/tooling/ru/Microsoft.CodeAnalysis.resources.dll +0 -0
  158. package/dist/tooling/runtimes/win/lib/net6.0/System.Text.Encoding.CodePages.dll +0 -0
  159. package/dist/tooling/schema-contract.json +23 -0
  160. package/dist/tooling/tr/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  161. package/dist/tooling/tr/Microsoft.CodeAnalysis.resources.dll +0 -0
  162. package/dist/tooling/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  163. package/dist/tooling/zh-Hans/Microsoft.CodeAnalysis.resources.dll +0 -0
  164. package/dist/tooling/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  165. package/dist/tooling/zh-Hant/Microsoft.CodeAnalysis.resources.dll +0 -0
  166. package/package.json +8 -3
  167. package/skills/neocompose-cli/SKILL.md +338 -184
@@ -1,214 +1,368 @@
1
1
  ---
2
2
  name: neocompose-cli
3
3
  description: >-
4
- Edit a Neo Compose project's schema as C# files and sync bidirectionally
5
- with the server using the `neo` CLI. Use when asked to add/change/remove
6
- custom types, attributes, or enums in a Neo Compose project, to validate or
7
- evaluate NeoScript, or to batch-edit values and localized strings. The
8
- working copy lives in a `neo/` directory (neo.json + Attributes/ + Enums/);
9
- commands are run via `node cli/bin/neo.mjs` (repo) or `npm run neo`.
4
+ Edit and synchronize a Neo Compose format-v2 schema as real C# 11 plus
5
+ tracked NeoScript sidecars. Use for custom types, interfaces, attributes,
6
+ enums, templates, localization, schema-aware NeoScript, or batch content
7
+ edits. The working copy is a neo/ directory; run `neo` from the published
8
+ package or `node cli/bin/neo.mjs` in the web repository.
10
9
  ---
11
10
 
12
11
  # Neo Compose schema-as-code CLI (`neo`)
13
12
 
14
- The `neo/` working copy is a **git-like checkout** of a Neo Compose project
15
- version's schema: custom types and their attributes as one C# class per file
16
- under `Attributes/`, enums under `Enums/`. The server is the source of truth;
17
- files are a peer editor alongside the web UI. Spec:
18
- `specs/schema-as-code-cli.md`.
19
-
20
- In Unity projects, `neo.json` may set `unityConfigPath` (relative path to the
21
- game's `NeoComposeConfig.asset`) instead of `projectId`/`versionId` — the
22
- asset is then the single source of truth for both ids, and version-changing
23
- commands (`neo branch switch`, …) update the asset so the game always targets
24
- the same version as the working copy. Never re-add the ids to `neo.json` in
25
- that mode; the CLI rejects the duplication.
26
-
27
- ## Core discipline
28
-
29
- 1. `neo pull` before editing (and before any push after time has passed).
30
- 2. Edit the C# files **within the constrained subset** (see below).
31
- 3. `neo status` / `neo diff` to review, `neo push --dry-run` to preview.
32
- 4. `neo push` to commit — atomically, with compare-and-swap base hashes.
33
- 5. **Pull → push with no edits is always a no-op.** If `neo status` reports
34
- changes right after a pull, that is a bug — report it, don't push.
35
-
36
- The CLI never guesses: anything outside the subset is a file:line:column
37
- error. Conflict markers in a file make it unparseable until resolved.
38
-
39
- ## The C# subset
40
-
41
- - One top-level `class` (custom type) or `enum` per file.
42
- - Properties carry exactly one `Neo*` attribute: `NeoBool`, `NeoInt`
43
- (`Min`/`Max`), `NeoFloat` (`+DecimalPoints`), `NeoString`
44
- (`Localizable`/`SearchKey`),
45
- `NeoDictionary`/`NeoList` (entry chains), `NeoObject` (custom type),
46
- `NeoEnum`, `NeoLookup` (`CollectionId`), `NeoProperty`
47
- (`Code`, optional `SetterCode`, `RetJson`),
48
- `NeoSprite`/`NeoAudio` (`TemplateId`), `NeoFunction`, and
49
- `NeoNSFunction` (`Code`, `RetJson`, `ArgsJson`, `Deferred`).
50
- - The positional string argument is the stable record id. **Omit it to
51
- create**: `[NeoFloat(Min = 0)] public float? Weight { get; init; }` — push
52
- assigns the id and rewrites the file canonically.
53
- - Property nullability IS the `required` flag: `int?` optional, `int`
54
- required. Property name is the schema key (`Key`/`Name` args override).
55
- - Enum members: the member name is the option key (codegen symbol);
56
- `[NeoEnumEntry(Text = "...")]` carries the display/localized-text id.
57
- - `ExtraJson` holds fields the projection doesn't express — edit it as JSON,
58
- never delete it casually.
59
- - No method bodies, no initializers, no extra `using`s.
60
-
61
- ## Conflicts
62
-
63
- Concurrent edits produce git-style `<<<<<<< local / ======= / >>>>>>> server`
64
- markers at member granularity. **Edit the file to the desired final state and
65
- push — the push IS the resolution** (it supersedes both sides). `neo resolve
66
- --mine|--theirs` keeps one side wholesale. Markers break C# compilation on
67
- purpose.
68
-
69
- If push reports `base-hash-conflict`: run `neo pull` (merges or writes
70
- markers), resolve, push again. Never bypass with `--force`-style flags.
71
-
72
- If push reports `version-bump-required`: the server classified the change
73
- (e.g. `requiredBump: major` for schema changes). Re-run with
74
- `neo push --accept-bump` if the bump is intended.
75
-
76
- ## NeoScript
77
-
78
- NeoScript is C#-flavored: typed declarations (`string x = ...;`, NOT `var`),
79
- `this` = the containing type instance, `root.Assets` / `root.Save` /
80
- `root.Session` roots. Validate before storing in a `NeoProperty` `Code` or
81
- `SetterCode` arg, or invoke a stored typed NeoScript Function:
13
+ A `neo/` working copy is a Git-like checkout of one Neo Compose project
14
+ version. C# and NeoScript are peer authoring surfaces beside the web UI; the
15
+ server remains the shared source of truth. The current contract is format v2
16
+ and is documented in `specs/schema-as-code-cli.md`.
82
17
 
18
+ ## Non-negotiable workflow
19
+
20
+ 1. Run `neo pull` before editing and before pushing after time has passed.
21
+ 2. Edit real C# 11 and the tracked `.neo` sidecars. Never edit `.neo/state.json`
22
+ or `.neo/tooling`.
23
+ 3. Run `neo status` or `neo diff`, then `neo push --dry-run`.
24
+ 4. Run `neo script check --all` after a schema rename or signature change.
25
+ 5. Push one reviewed atomic change with `neo push`.
26
+
27
+ **Pull followed immediately by status/push must be a no-op.** If it reports
28
+ schema changes, stop and report a round-trip bug rather than pushing it.
29
+
30
+ The compiler reports file:line:column diagnostics and never guesses. Unknown
31
+ authorable server fields fail with “CLI contract upgrade required”; they never
32
+ hide in an opaque JSON carrier.
33
+
34
+ ## Setup and format requirement
35
+
36
+ ```sh
37
+ npm i -g @neocompose/cli
38
+ neo login [--api <url>] [--profile editor|release] [--save-project <id>]
39
+ neo init --project <id> [--version <id>] [--dir neo]
40
+ neo doctor
41
+ ```
42
+
43
+ Repository development uses `node cli/bin/neo.mjs`. Agents should always pass
44
+ explicit flags/IDs. Human terminals may show pickers and confirms; non-TTY/CI
45
+ use fails with an actionable missing-flag diagnostic rather than blocking.
46
+
47
+ `neo.json` must contain `formatVersion: 2`. A missing or different marker is
48
+ unsupported. Preserve any source you need, then create a fresh v2 working copy:
49
+
50
+ ```sh
51
+ neo init --project <id> [--version <id>] [--dir neo]
52
+ ```
53
+
54
+ `neo pull --reset` is only for an existing v2 workspace; it reconstructs
55
+ CLI-managed source from the server and refreshes the compiler SDK and analyzer.
56
+
57
+ Neo never downloads or installs .NET. Compiler host discovery is:
58
+
59
+ 1. explicit `NEO_DOTNET_HOST`;
60
+ 2. a compatible Unity 6000 runtime;
61
+ 3. a compatible system `dotnet`.
62
+
63
+ The validated selection is cached under `.neo`; `neo doctor` reports its
64
+ path, kind, runtime/Unity version, cache status, and compiler/SDK contract
65
+ compatibility. An invalid explicit override is a hard error.
66
+
67
+ In Unity projects, `neo.json` may use `unityConfigPath` instead of
68
+ `projectId`/`versionId`. The referenced `NeoComposeConfig.asset` is then the
69
+ single source of truth, and branch switches update it. Never duplicate the IDs
70
+ in `neo.json` in this mode.
71
+
72
+ ## Working-copy layout
73
+
74
+ ```text
75
+ neo/
76
+ neo.json
77
+ NeoCompose.Schema.csproj # netstandard2.1, C# 11, IDE-only
78
+ Types/ # custom classes
79
+ Interfaces/ # interface declarations
80
+ Enums/
81
+ Root.cs # [NeoRegistry] roots and loose members
82
+ Templates/ # typed texture/audio settings
83
+ Localization.cs # typed localization settings
84
+ LocalizationStatuses/*.cs # typed localization workflow statuses
85
+ Scripts/<Type>/<Member>.neo # computed properties and NeoScript methods
86
+ Migrations/*.neo
87
+ .neo/
88
+ state.json # bases/CAS hashes; never hand-edit
89
+ dotnet-host.json
90
+ tooling/ # bundled SDK, analyzer, generator, compiler
91
+ ```
92
+
93
+ The schema project is not referenced by the game. `.neo/`, `bin/`, and `obj/`
94
+ are gitignored; source and scripts are tracked.
95
+
96
+ ## Authoring real C#
97
+
98
+ Native C# carries native meaning:
99
+
100
+ - Plain, `virtual`, `abstract`, and `override` members map directly to schema
101
+ behavior. An override's base record identity comes from the resolved symbol.
102
+ - Base classes, interfaces, generic parameters/arguments, and `where`
103
+ constraints use ordinary syntax.
104
+ - Property type determines Neo kind; nullable annotation determines whether it
105
+ is optional; initializer determines its default.
106
+ - Declaration order determines schema/enum order unless an explicit typed
107
+ ordering attribute is present.
108
+ - Method parameters and return type are the function signature.
109
+ `Task`/`Task<T>` means deferred execution.
110
+ - Concrete `[NeoScript]`/`[NeoFunction]` methods are C# 11 partial
111
+ declarations. The bundled source generator adds inert compile-only bodies.
112
+ Abstract functions are ordinary abstract methods.
113
+
114
+ ```csharp
115
+ using System.Collections.Generic;
116
+ using System.Threading.Tasks;
117
+ using NeoCompose.Schema;
118
+
119
+ [NeoEnum("enum-item-type")]
120
+ public enum ItemType
121
+ {
122
+ [NeoEnumOption("option-food", Text = "Food")]
123
+ Food,
124
+ }
125
+
126
+ [NeoType("type-inventory-item", AllowedStorage = NeoAllowedStorage.Static)]
127
+ [NeoSchemaOrder(nameof(Name), nameof(Type), nameof(Tags), nameof(UsePrimary))]
128
+ public abstract partial class InventoryItem<
129
+ [NeoId("generic-stack")] TStack>
130
+ where TStack : class
131
+ {
132
+ [NeoMember("attribute-name"), NeoText(SearchKey = true)]
133
+ public virtual string Name { get; init; } = "";
134
+
135
+ [NeoMember("attribute-type")]
136
+ public abstract ItemType Type { get; init; }
137
+
138
+ [NeoMember("attribute-tags"), NeoList(Kind = NeoListKind.Unordered)]
139
+ [NeoEntries(nameof(TagEntries))]
140
+ public virtual IReadOnlyList<string> Tags { get; init; } = new List<string>();
141
+
142
+ private static readonly NeoEntrySettings[] TagEntries =
143
+ {
144
+ new()
145
+ {
146
+ Id = "entry-tag",
147
+ Path = "[]",
148
+ Kind = NeoEntryKind.String,
149
+ Text = new NeoTextSettings { Localizable = false },
150
+ },
151
+ };
152
+
153
+ [NeoMember("function-use-primary"), NeoScript]
154
+ public virtual partial Task<bool> UsePrimary(InventoryItem<TStack> target);
155
+ }
156
+ ```
157
+
158
+ Stable IDs are visible in `[NeoType]`, `[NeoInterface]`, `[NeoEnum]`,
159
+ `[NeoEnumOption]`, `[NeoId]`, and `[NeoMember]`. Omit a nullable positional ID
160
+ only when creating a record; a successful push assigns it and canonically
161
+ rewrites the source. Once assigned, preserve it through renames.
162
+
163
+ `[NeoMember]` owns identity/common options. Use narrow typed attributes for
164
+ Neo behavior: `NeoText`, `NeoNumber`, `NeoDictionary`, `NeoList`, `NeoEntries`,
165
+ `NeoIndex`, `NeoColumn`, `NeoLookup`, `NeoDialogue`, `NeoFile`, `NeoComputed`,
166
+ `NeoScript`, `NeoFunction`, `NeoSystem`, and explicit schema/generic binding
167
+ attributes. Use the typed settings classes for nested entries, template import
168
+ options, localization, and system metadata. This is intentional: every valid
169
+ option should appear in C# IntelliSense.
170
+
171
+ A bodyless `[NeoComputed]` property needs no initializer or `#pragma`. The
172
+ bundled analyzer suppresses only its sidecar-backed `CS8618`; ordinary nullable
173
+ warnings remain enabled.
174
+
175
+ Allowed values are statically analyzable literals, enum values, `nameof`,
176
+ `typeof`, arrays/collections, object initializers, approved Neo value types,
177
+ and `Neo.Ref<T>`, `Neo.Lookup<T>`, `Neo.Dialogue`, `Neo.Sprite`, `Neo.Audio`,
178
+ or `Neo.Member` references. Authored code is never executed.
179
+
180
+ Never introduce opaque carriers or identity escapes: `ExtraJson`, `DefaultJson`,
181
+ `RetJson`, `ArgsJson`, `EntryChainJson`, `SchemaKeyOrderJson`,
182
+ `GenericParamIds`, `ChainJson`, `SignatureJson`, `ExtendsId`, `isVirtual`, or
183
+ `isAbstract`.
184
+
185
+ Define each localization workflow status in
186
+ `LocalizationStatuses/<Name>.cs` using `[NeoLocalizationStatus("stable-id")]`
187
+ and a static `NeoLocalizationStatusSettings` object. The marker owns identity;
188
+ typed properties cover slug, display metadata, archive state, transition
189
+ rules, automatic transitions, and system restrictions. Keep the order in
190
+ `NeoLocalizationSettings.StatusIds`.
191
+
192
+ ## NeoScript sidecars
193
+
194
+ Scripted member bodies live at exactly
195
+ `Scripts/<DeclaringType>/<Member>.neo`.
196
+
197
+ A computed property uses one complete contextual file. The outer signature
198
+ matches the linked C# declaration's semantic result (`Task<T>` functions use
199
+ `T`) and adds the implicit `this` and `root` execution parameters:
200
+
201
+ ```neoscript
202
+ string Description(InventoryItem this, Root root) {
203
+ get {
204
+ return $"{this.Name} ({this.Type})";
205
+ }
206
+
207
+ set(string value) {
208
+ this.Name = value;
209
+ }
210
+ }
211
+ ```
212
+
213
+ A concrete `[NeoScript]` method uses the same outer contextual signature and
214
+ puts its declared arguments and executable body in a nested unit:
215
+
216
+ ```neoscript
217
+ bool UsePrimary(InventoryItem this, Root root) {
218
+ (InventoryItem target) {
219
+ return target.IsStackable;
220
+ }
221
+ }
83
222
  ```
223
+
224
+ The complete wrapper is tracked on disk and displayed identically in editors;
225
+ Monaco protects the signature/braces while leaving the getter, setter, or
226
+ function body editable. Abstract scripted members have no file.
227
+
228
+ Missing, duplicate, case-colliding, ambiguous, and orphaned sidecars are hard
229
+ diagnostics. A sidecar for an abstract member is also invalid. The stable C#
230
+ member ID lets canonical renames move the file safely; include C# and sidecar
231
+ renames in the same reviewed change.
232
+
233
+ Canonical C# places `// NeoScript: Scripts/<Type>/<Member>.neo` above the
234
+ linked declaration. Go-to-definition, references, and rename use the Roslyn
235
+ source identity plus stable member ID to navigate between C# and `.neo`.
236
+
237
+ NeoScript is C#-flavored: use typed declarations (`string name = ...;`, not
238
+ `var`); `this` is the containing instance; roots include `root.Assets`,
239
+ `root.Save`, and `root.Session`.
240
+
241
+ ```sh
242
+ neo script check --all
84
243
  neo script check --this Outpost --returns string 'return $"{this.Name}!";'
85
244
  neo script check --mode setter --attribute ComputedName 'root.Session.Name = value;'
86
245
  neo script check --mode nsfunction --attribute Outpost.RefreshUnlock 'return this.Level > 0;'
87
246
  neo script compile --mode nsfunction --attribute Outpost.RefreshUnlock 'return this.Level > 0;'
88
- neo script check --all # recompile every stored NeoScript body
89
247
  neo script eval --returns string 'return root.Assets.Outposts[0].FullDisplayText;'
90
- neo script apply --mode action '...' # prints write intents; commits nothing
91
248
  neo script eval --function Outpost.RefreshUnlock --this-value <id> --args '[3]'
92
- neo script apply --function Outpost.RefreshUnlock --this-value <id> --args '[3]'
249
+ neo script apply --mode action '...'
93
250
  ```
94
251
 
95
- `eval` runs against authored values with the same evaluator the web UI uses.
96
- NSFunction `apply` is also preview-only: it reports the return value, write
97
- intents, and created Session rows but commits nothing. Purely NeoScript
98
- deferred paths may complete inline; native suspension reports unsupported.
99
- `--json` everywhere for machine-readable output.
252
+ `eval` uses authored values and the same evaluator as the web app. `apply` is
253
+ preview-only unless its command explicitly supports a commit; it reports
254
+ return values and write intents. Prefer `--json` for automation.
100
255
 
101
- ## Content (not in files)
256
+ ## Conflicts and version bumps
102
257
 
103
- Values, dialogue, and localized text are CLI verbs, not files:
258
+ Overlapping concurrent schema edits produce explicit local/server conflict
259
+ markers. They intentionally fail compilation. Edit source to the desired final
260
+ state and push; that push is the resolution. `neo resolve --mine|--theirs` is
261
+ whole-side convenience only.
104
262
 
105
- ```
106
- neo records query [--kind <recordKind>] # every record head in the version
263
+ For `base-hash-conflict`, pull, resolve, and push again. Never seek a force
264
+ bypass. For `version-bump-required`, inspect the classification and repeat
265
+ with `neo push --accept-bump` only when intended.
266
+
267
+ Script conflicts block validation in the same way and must be resolved in the
268
+ tracked `.neo` file.
269
+
270
+ ## Content stays in commands
271
+
272
+ Values, dialogue instances, localized text, and project files are records, not
273
+ schema source files:
274
+
275
+ ```sh
276
+ neo records query [--kind <recordKind>]
107
277
  neo records get <kind> <id>
108
- neo values list [attributeId] / get <valueId> / set <valueId> '<json>'
109
- neo loc locales / list / set <textId> <locale> "text"
278
+ neo values list [attributeId]
279
+ neo values get <valueId>
280
+ neo values set <valueId> '<raw-json-value>'
281
+ neo loc locales
282
+ neo loc list
283
+ neo loc set <textId> <locale> "text"
110
284
  ```
111
285
 
112
- Every `set` verb accepts a JSON-array batch on stdin or `--file` (e.g.
113
- `[{"textId":"...","locale":"de-DE","value":"..."}]`) — use batches when
114
- editing many records.
286
+ Write verbs accept a JSON-array batch on stdin or `--file`; use one batch when
287
+ edits must be atomic. A `values set` payload is the raw value, not
288
+ `{"value": ...}`. For collection rows use `values add-entry` on the live
289
+ container value; an attribute's default container ID may not be an instance's
290
+ container.
115
291
 
116
- ## Branches, merges, releases, migrations
292
+ ### Dialogue authoring
117
293
 
118
- ```
119
- neo branch list / create <name> [--from <ref>] / switch <nameOrId>
120
- neo merge <branch> [--dry-run] # field-level 3-way; conflicts reject with per-record+field payload
121
- neo release cut [--bump ...] [--dry-run] # bump floor DERIVED from transaction history; raise-only
122
- neo migrate new <name> --target <Type> # creates Migrations/NNNN-name.neo
123
- neo migrate list / check / run [--dry-run] [--skip-invalid]
124
- ```
294
+ Always run `neo dialogue dryrun [ref]` after editing dialogue. It traverses
295
+ option paths from a fresh save and applies the runtime's mutation-ownership
296
+ rules. Exit 1 means the authored graph would fail on device.
125
297
 
126
- Branches are copy-on-write forks (cheap; edits isolated until merged).
127
- Landing a branch into its fork parent auto-archives it (refreshes don't);
128
- archived versions hide under the picker's "Archived" submenu and behind
129
- `neo branch restore <name>`.
130
- Migrations are NeoScript actions in `.neo` files: `/// @migration <id>`,
131
- `/// @target <Type|project>` headers, then the action body; `this` = each
132
- instance of the target type. The v1 runner applies `this.<Field> = ...`
133
- assignments as one atomic CAS transaction and marks `appliedAt` per version
134
- (idempotent, per-branch). Sparse instances abort unless `--skip-invalid`.
298
+ `neo dialogue export <ref>` and `neo dialogue apply <spec.json> [--dry-run]`
299
+ round-trip a whole dialogue. `neo dialogue compile` compiles condition/action
300
+ blocks with their dialogue/node context. Localized node fields hold text IDs;
301
+ create/edit those records through `neo loc` with their links.
135
302
 
136
- ## Setup (once per machine/repo)
303
+ Lookup collection mutation is a common trap: mutating a collection through a
304
+ lookup may resolve to an authored asset collection and be forbidden. The
305
+ dialogue dry run exists to catch this and related save/session ownership bugs.
137
306
 
138
- ```
139
- npm i -g @neocompose/cli # or run from the web repo: node cli/bin/neo.mjs
140
- neo login [--api <url>] [--profile editor|release] [--save-project <id>]
141
- neo init --project <id> [--version <id>] [--dir neo]
142
- neo dev [--push] # live: auto-pull on server change; 'p' push, 's' status
307
+ ## Branches, releases, and migrations
308
+
309
+ ```sh
310
+ neo branch list
311
+ neo branch create <name> [--from <ref>]
312
+ neo branch switch <nameOrId>
313
+ neo merge <branch> [--dry-run] [--migrate]
314
+ neo release cut [--bump major|minor|patch] [--dry-run]
315
+
316
+ neo migrate new <name> --target <Type>
317
+ neo migrate list
318
+ neo migrate check
319
+ neo migrate run [--dry-run] [--skip-invalid]
143
320
  ```
144
321
 
145
- Agents run non-interactively: always pass explicit flags/ids. (In a human
146
- terminal the same commands prompt with pickers and confirms; with no TTY the
147
- CLI never blocks on a prompt — missing arguments raise an error that names
148
- the flag to pass, and confirms fall back to the pre-prompt behavior.)
149
-
150
- Tokens land in the macOS Keychain when available (0600 file elsewhere;
151
- `NEO_COMPOSE_TOKEN` / `--token-stdin` for CI). `--save-project` adds a
152
- narrow per-project save-read scope for `script eval --save`.
153
-
154
- ## Dialogue validation & batch authoring
155
-
156
- - **ALWAYS run `neo dialogue dryrun [ref]` after authoring or editing
157
- dialogues.** It walks every option path from a fresh save, executes every
158
- action/condition through the real evaluator, and applies the Unity
159
- runtime's mutation-ownership rules (save/session clone-on-write,
160
- lookup-resolution). Exit 1 = the runtime would throw on device. Known
161
- trap it catches: `root.Save.Inventory.Add(...)` — collection mutations
162
- THROUGH Lookup attributes resolve into the referenced asset collection
163
- and always fail at runtime.
164
- - `neo dialogue apply <spec.json> [--dry-run]` authors a whole dialogue
165
- from one declarative file: nodes with `say`/`options`/`do` (NeoScript
166
- `code` compiled server-side, `bind` overrides the action's `this`),
167
- `group`/`start`/`linkedValueId`; strings minted in one transaction.
168
- `neo dialogue export <ref>` round-trips an existing dialogue into the
169
- same shape (actions surface compiled `ir`). Workflow: export → edit →
170
- apply → dryrun.
171
- - Cross-outpost writes need authored OutpostSaveMap entries for every
172
- outpost (fresh saves seed from authored values) — `values add-entry` on
173
- the save-map dict with `key=<outpost value id>`.
174
-
175
- ## Content authoring (dialogues, items, strings)
176
-
177
- - `neo dialogue create '<IDialogueBase json>'` writes a whole dialogue (node
178
- graph + trigger) in one call; `edit`/`delete` manage the record. Node text
179
- fields hold localized-text IDS — mint the strings afterwards with
180
- `neo loc create '{"id":<textId>,"value":"...","links":[...]}'` using
181
- `dialogue-node-text` / `dialogue-choice-text` links (recordKind
182
- `dialogue-node`). `localizedTextEdits` on node create/edit only EDITS
183
- existing texts.
184
- - `neo dialogue compile '{"code":...,"target":0|1|2,"dialogue":{},"node":{"primaryLinkedValueId":...}}'`
185
- returns wire-ready compiled logic (0=condition, 1=action, 2=text variable).
186
- Actions bind `this` to the NODE's primaryLinkedValueId — to unlock another
187
- outpost, bind the action node to THAT outpost's value id. Lambdas don't
188
- compile inside actions; lookup adds accept entry ids:
189
- `root.Save.Inventory.Add("<entryValueId>")`.
190
- - Collection rows: `neo values add-entry <containerValueId>
191
- '{"entryAttributeId":...}'` (server mints the entry tree; find the LIVE
192
- container by querying which list value contains existing entries — an
193
- attribute's `valueId` may be its DEFAULT container, not the instance).
194
- `neo values set <leafId> '<raw json value>'` — raw value, NOT wrapped in
195
- `{"value":...}`.
196
- - `neo script eval --returns "string[]"` etc. accept `T[]`/`T?` suffixes;
197
- `neo script compile` prints compiled getter/action IR.
198
-
199
- ## Implementation notes agents should know
200
-
201
- - The CLI talks to **Convex directly** with typed `api.*` calls; pushes go
202
- through the session-gated `commitFromSession` (same scope gates + CAS as
203
- the web). `--json` is available on status/diff/branch list/migrate
204
- list/script/records/values/loc.
205
- - The working copy also projects `Templates/*.cs`, `Localization.cs`, and
206
- `Migrations/*.neo`. Migration pushes **pin compiled IR** on the record;
207
- `migrate run` replays the pinned IR (rename-proof). `migrate run --server`
208
- executes in the server runner; `neo merge --migrate` chains migrations at
209
- merge, and `release cut` refuses while any migration is pending.
210
- - Pull short-circuits on the sync-signal head ("Already up to date") when
211
- nothing changed server-side and the copy is clean.
212
-
213
- The editor profile cannot publish releases; that requires `--profile release`
214
- at login (server-enforced scopes — ZERO TRUST).
322
+ Branches are copy-on-write forks. Releases are immutable snapshots; their bump
323
+ floor is derived from transaction history and may only be raised. Release
324
+ operations require the release login profile.
325
+
326
+ Migrations remain NeoScript action files under `Migrations/`, with stable
327
+ headers and pinned compiled IR. The server runner tracks per-branch applied
328
+ state; merge may chain pending migrations before validation.
329
+
330
+ ## Editor and implementation contract
331
+
332
+ The browser-safe `neoscript-language` service is shared by the compiler, CLI,
333
+ web Monaco editor, and VS Code LSP. Do not add language intelligence directly
334
+ to an environment adapter.
335
+
336
+ Monaco's existing highlighting, comments/interpolation, bracket behavior,
337
+ protected scaffolds, context-aware completion/hover, and accurate diagnostics
338
+ are a release-blocking compatibility floor. V2 adds recovery completion,
339
+ signature help, C# and script definitions, references, rename, document
340
+ symbols, semantic tokens, quick fixes, formatting, richer diagnostics,
341
+ contextual ranking, and incremental analysis. Project updates must refresh
342
+ context without accumulating stale providers.
343
+
344
+ The VS Code extension consumes the same service and grammar/token spec. Its
345
+ LSP supports the same diagnostics, completion, hover, signature, navigation,
346
+ rename, symbols, semantic tokens, and formatting. The VSIX is built in-repo;
347
+ marketplace publication is separate.
348
+
349
+ ## Agent implementation notes
350
+
351
+ - The Node CLI talks directly to Convex through typed `api.*` calls and uses
352
+ the same session-gated CAS commit path as the web app.
353
+ - `SchemaManifestV2` is the only C# source/document boundary. The contract
354
+ registry classifies authored, derived, and volatile fields; derived server
355
+ fields come from the pulled base and absent/null equivalents normalize.
356
+ - The npm package bundles the Roslyn app, dependencies, SDK, analyzer, and
357
+ generator under `dist/tooling`; it does not bundle a runtime.
358
+ - The schema compiler does static analysis only. Never execute an authored
359
+ assembly to obtain settings.
360
+ - A change is incomplete until typecheck/tests/builds, package-content and
361
+ contract-version checks, Monaco parity/browser-bundle suites, VSIX
362
+ packaging, Unity sample tests, live `neowyn` no-op verification, and final
363
+ `npm run doctor` succeed.
364
+
365
+ Tokens use the macOS Keychain/OS credential store when available, a protected
366
+ file only as fallback, and `NEO_COMPOSE_TOKEN` or `--token-stdin` in CI. The
367
+ editor profile cannot publish releases; server-enforced scopes are the
368
+ security boundary.