@neocompose/cli 0.23.2 → 0.24.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.
- package/CHANGELOG.md +56 -0
- package/README.md +59 -3
- package/dist/neo.mjs +12867 -8048
- package/package.json +10 -3
- package/skills/neocompose-cli/SKILL.md +14 -6
- package/skills/neocompose-cli/references/animation-and-world-authoring.md +43 -18
- package/skills/neocompose-cli/references/cli-development.md +6 -2
- package/skills/neocompose-cli/references/values-identities-and-references.md +5 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neocompose/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.1",
|
|
4
4
|
"description": "Neo Compose native project-source CLI with bidirectional sync.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -35,10 +35,17 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@inquirer/prompts": "^8.5.2",
|
|
38
|
-
"convex": "^1.40.0"
|
|
38
|
+
"convex": "^1.40.0",
|
|
39
|
+
"ignore": "^7.0.6"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
42
|
"esbuild": "^0.28.1",
|
|
42
|
-
"prettier": "^3.9.5"
|
|
43
|
+
"prettier": "^3.9.5",
|
|
44
|
+
"uuid": "^14.0.1"
|
|
45
|
+
},
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "git+https://github.com/ryanbliss/neo-compose.git",
|
|
49
|
+
"directory": "cli"
|
|
43
50
|
}
|
|
44
51
|
}
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
name: neocompose-cli
|
|
3
3
|
description: >-
|
|
4
4
|
Edit, validate, and synchronize Neo Compose format-4 projects with the `neo`
|
|
5
|
-
CLI. Use when working in a `neo/` checkout or with `.neo`/`.neoflow` source:
|
|
5
|
+
CLI. Use when working in a `neo/` checkout or with `.neo`/`.neoflow`/`.spec.neo` source:
|
|
6
6
|
schema declarations, constructors, values and references, world objects and
|
|
7
7
|
animation, dialogue, NeoScript, localization, migrations, managed image or
|
|
8
8
|
audio files, branches and releases, or batch repair. Run `neo` from
|
|
9
9
|
`@neocompose/cli` or `node cli/bin/neo.mjs` in the neo-compose repository.
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
<!-- reviewed-through-cli: 0.
|
|
12
|
+
<!-- reviewed-through-cli: 0.24.1 -->
|
|
13
13
|
|
|
14
14
|
# Neo Compose CLI
|
|
15
15
|
|
|
@@ -24,11 +24,12 @@ Those are not part of format 4.
|
|
|
24
24
|
## Follow the safe workflow
|
|
25
25
|
|
|
26
26
|
1. Run `neo pull` before editing. Pull again before pushing if time has passed.
|
|
27
|
-
2. Edit tracked `.neo`, `.neoflow`, and managed binary files only. Never edit
|
|
27
|
+
2. Edit tracked `.neo`, `.neoflow`, `.spec.neo`, and managed binary files only. Never edit
|
|
28
28
|
`.neo/state.json`, analysis caches, or `.neo/conflicts` as source.
|
|
29
29
|
3. Run `neo status` and `neo diff`. Review every change, including changes that
|
|
30
30
|
existed before the task began.
|
|
31
|
-
4. Run `neo dialogue dryrun <ref>` after
|
|
31
|
+
4. Run `neo test` after NeoScript changes and `neo dialogue dryrun <ref>` after
|
|
32
|
+
dialogue changes.
|
|
32
33
|
5. Run `neo push --dry-run` before every real push. It performs the full local
|
|
33
34
|
source emission, ID-assignment, transport-shape, hash, and repeat-verification path,
|
|
34
35
|
then rehearses the server's preparation phase — schema-commit
|
|
@@ -49,8 +50,12 @@ opaque JSON or guessed syntax.
|
|
|
49
50
|
values, files, or other records. `@system` is reserved for platform-owned
|
|
50
51
|
system records; authoring it can make the record uneditable.
|
|
51
52
|
- Preserve existing `@id` annotations through rename, reorder, and file moves.
|
|
53
|
+
- Omit `@id` on new ordinary declarations and nested rows unless a same-push
|
|
54
|
+
structural reference genuinely requires an explicit UUID. A successful push
|
|
55
|
+
assigns the durable IDs and rewrites source.
|
|
52
56
|
- Do not add a second `@id` to a root or static member initializer. The member
|
|
53
|
-
ID owns that stored binding.
|
|
57
|
+
ID owns that stored binding. Existing nested class/list rows retain their
|
|
58
|
+
inline IDs; new rows normally omit them until push.
|
|
54
59
|
- Treat `.neo/` as private state and tracked Neo source as the authorable input.
|
|
55
60
|
- Never seek a force-CAS bypass. Pull, resolve, review, and retry.
|
|
56
61
|
|
|
@@ -100,10 +105,13 @@ neo/
|
|
|
100
105
|
DialogueGroups/
|
|
101
106
|
Dialogues/*.neoflow
|
|
102
107
|
Migrations/*.neo
|
|
108
|
+
**/*.spec.neo
|
|
103
109
|
.neo/{state.json,conflicts/}
|
|
104
110
|
```
|
|
105
111
|
|
|
106
|
-
|
|
112
|
+
Production `.neo`/`.neoflow` files and supported managed binaries are tracked.
|
|
113
|
+
Colocated `.spec.neo` files are test-only and never enter status, source hashes,
|
|
114
|
+
pull/reset, or push.
|
|
107
115
|
Normal pull preserves declaration placement and spelling by stable ID when it
|
|
108
116
|
can. Force/reset may regroup source into the canonical layout.
|
|
109
117
|
|
|
@@ -109,9 +109,12 @@ override replaces the whole leaf.
|
|
|
109
109
|
Frame overrides may change `Enabled`, `FlipX`, and `SortingOrder`; they may
|
|
110
110
|
not add, remove, or reorder `Children`.
|
|
111
111
|
|
|
112
|
-
Address direct children
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
Address direct children through selector delegates. A selector should implement
|
|
113
|
+
the project's own stable identity contract, such as an immutable `Name`, slug,
|
|
114
|
+
or semantic position; do not turn a mutable object-row ID back into identity by
|
|
115
|
+
returning `Reference<T>(id: "...")`. Missing optional child slots are skipped
|
|
116
|
+
with diagnostics when the authored slot is absent, while stale pre-provenance
|
|
117
|
+
placements may still fail closed.
|
|
115
118
|
|
|
116
119
|
A placement row carries its `assetClassId` binding and optional `assetValueId`
|
|
117
120
|
override beside its schema keys. They are row provenance, not declared schema:
|
|
@@ -127,8 +130,8 @@ sprite specialization is `NeoSpriteAnimationSegment`, whose
|
|
|
127
130
|
|
|
128
131
|
Use one polymorphic `NeoAnimationClip.Tracks` list:
|
|
129
132
|
|
|
130
|
-
- `NeoAnimationChildTrack` schedules
|
|
131
|
-
`
|
|
133
|
+
- `NeoAnimationChildTrack` schedules `ClipKey` on the child returned by its
|
|
134
|
+
`Selector` delegate.
|
|
132
135
|
- A project subclass of
|
|
133
136
|
`NeoAnimationSegmentTrack<TChild, TValue>` schedules a segment onto one
|
|
134
137
|
target member. Implement its abstract `Segment` member as a stored value,
|
|
@@ -137,32 +140,54 @@ Use one polymorphic `NeoAnimationClip.Tracks` list:
|
|
|
137
140
|
`NeoSpriteAnimationSegmentTrack<TChild extends NeoSpriteObject>` pairing
|
|
138
141
|
targets `NeoSpriteObject.Sprite`.
|
|
139
142
|
|
|
140
|
-
Declare a concrete project track by implementing `Segment`,
|
|
141
|
-
|
|
143
|
+
Declare a concrete project track by implementing `Segment`, expose a compatible
|
|
144
|
+
selector function on the owning object, then pass that function to each row:
|
|
142
145
|
|
|
143
146
|
```neo
|
|
144
147
|
class StoredPantsTrack : NeoSpriteAnimationSegmentTrack<PantsSprite> {
|
|
145
148
|
public override NeoSpriteAnimationSegment Segment = new();
|
|
146
149
|
}
|
|
147
150
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
class LegPart : NeoObject {
|
|
152
|
+
public PantsSprite SelectPants() {
|
|
153
|
+
var child = this.Children.FirstOrDefault((candidate) => {
|
|
154
|
+
return candidate.Name == "Pants";
|
|
155
|
+
});
|
|
156
|
+
if (child is PantsSprite pants) {
|
|
157
|
+
return pants;
|
|
158
|
+
}
|
|
159
|
+
throw "Pants child is missing or has the wrong type";
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public NeoAnimationClip<LegPart> Walk = new NeoAnimationClip<LegPart> {
|
|
163
|
+
Tracks = [
|
|
164
|
+
new StoredPantsTrack(selector: this.SelectPants) {
|
|
165
|
+
StartFrame = 0,
|
|
166
|
+
Direction = .Reverse,
|
|
167
|
+
OffsetEndIndex = 3,
|
|
168
|
+
},
|
|
169
|
+
]
|
|
170
|
+
};
|
|
171
|
+
}
|
|
156
172
|
```
|
|
157
173
|
|
|
174
|
+
Selectors may also be compatible inline closures. Prefer a named function when
|
|
175
|
+
the identity rule is reused or deserves an explicit failure message. Never use
|
|
176
|
+
a selector merely to wrap `Reference<T>(id: "...")`; that recreates the
|
|
177
|
+
row-ID coupling selectors were introduced to remove. For new track rows, omit
|
|
178
|
+
`@id` and let the successful push assign it. Preserve IDs already present on
|
|
179
|
+
pulled rows.
|
|
180
|
+
|
|
158
181
|
Each track has `StartFrame`, `Direction` (`.Forward` or `.Reverse`), and a
|
|
159
182
|
crop window `OffsetStartIndex`/`OffsetEndIndex`. Crop before reversing, then
|
|
160
183
|
schedule on the owning clip. Content beyond the owning clip truncates. Reject
|
|
161
184
|
empty/inverted crop windows and tracks that can never enter the clip.
|
|
162
185
|
|
|
163
|
-
Treat track target selection as
|
|
164
|
-
compatible with `TChild
|
|
165
|
-
|
|
186
|
+
Treat track target selection as project-authored identity logic, not row data.
|
|
187
|
+
The selector return type must be compatible with `TChild`; the segment value
|
|
188
|
+
must be compatible with `TValue`. `Refresh` controls selector reevaluation,
|
|
189
|
+
while track reads and segment getters are re-resolved for the next applied
|
|
190
|
+
frame after a watched dependency changes.
|
|
166
191
|
|
|
167
192
|
When multiple tracks write the same member in one frame, apply list order and
|
|
168
193
|
let the last write win.
|
|
@@ -41,8 +41,12 @@ Read the relevant specs in full:
|
|
|
41
41
|
- [P50 loops](https://github.com/ryanbliss/neo-compose-specs/blob/main/new-features/p50-neoscript-for-and-foreach-loops.md)
|
|
42
42
|
- [P51 switch](https://github.com/ryanbliss/neo-compose-specs/blob/main/new-features/p51-neoscript-switch-statements.md)
|
|
43
43
|
- [P52 try/catch](https://github.com/ryanbliss/neo-compose-specs/blob/main/new-features/p52-neoscript-try-catch-blocks.md)
|
|
44
|
+
- [P60 delegate parameters and selector targeting](https://github.com/ryanbliss/neo-compose-specs/blob/main/new-features/p60-closure-parameters-and-selector-targeting.md)
|
|
45
|
+
- [P61 initializer materialization](https://github.com/ryanbliss/neo-compose-specs/blob/main/new-features/complete/p61-initializer-materialization.md)
|
|
46
|
+
- [P64 NeoScript unit testing and push hooks](https://github.com/ryanbliss/neo-compose-specs/blob/main/new-features/p64-neoscript-unit-testing-and-push-hooks.md)
|
|
44
47
|
|
|
45
|
-
P38–P44
|
|
48
|
+
P38–P44, P47–P52, P60–P61, and the initial P64 test/push-hook vertical slice
|
|
49
|
+
are implemented. P45 remains deliberately deferred; do not
|
|
46
50
|
build or teach runtime-child provenance. P46 is a hardening proposal, not an
|
|
47
51
|
authoring capability. P52's document header still says proposed, but try/catch
|
|
48
52
|
shipped in CLI 0.18; implementation and parity tests take precedence over that
|
|
@@ -78,7 +82,7 @@ wrappers.
|
|
|
78
82
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
79
83
|
|
|
80
84
|
```html
|
|
81
|
-
<!-- reviewed-through-cli: 0.
|
|
85
|
+
<!-- reviewed-through-cli: 0.24.1 -->
|
|
82
86
|
```
|
|
83
87
|
|
|
84
88
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -98,8 +98,11 @@ Reference<Dialogue>(id: "capitol-dialogue-id")
|
|
|
98
98
|
- Both forms are legal in a member's declaration default, not only inside a
|
|
99
99
|
value graph. A key written there resolves after every pass has run, so it may
|
|
100
100
|
name a row the same push creates.
|
|
101
|
-
- Keep structural references
|
|
102
|
-
|
|
101
|
+
- Keep genuine structural references ID-based when their collection has no
|
|
102
|
+
stable symbol, path, or key surface. Animation track and frame-override
|
|
103
|
+
targets are selectors, not structural references: encode a stable
|
|
104
|
+
project-owned identity such as `Name` or slug in the selector instead of
|
|
105
|
+
wrapping a row ID in `Reference<T>(id: "...")`.
|
|
103
106
|
|
|
104
107
|
Declaration and file order do not affect resolution within one push. Cyclic
|
|
105
108
|
identity references are legal because they resolve IDs rather than evaluate a
|