@neocompose/cli 0.1.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.
- package/LICENSE +21 -0
- package/README.md +79 -0
- package/dist/neo.mjs +13864 -0
- package/package.json +33 -0
- package/skill/SKILL.md +147 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Copyright (c) Ryan Bliss and contributors. All rights reserved.
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# `neo` — Neo Compose schema-as-code CLI
|
|
2
|
+
|
|
3
|
+
Implements [specs/schema-as-code-cli.md](../specs/schema-as-code-cli.md): a
|
|
4
|
+
git-like C# working copy of a project version's schema, bidirectionally
|
|
5
|
+
synced with Convex, plus NeoScript and content commands.
|
|
6
|
+
|
|
7
|
+
## Run
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm i -g @neocompose/cli # customers: standalone package, `neo` on PATH
|
|
11
|
+
node cli/dist/neo.mjs <command> # repo dev: runs TS directly via tsx
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Packaging (`@neocompose/cli`)
|
|
15
|
+
|
|
16
|
+
The CLI publishes as a standalone npm package from `cli/`:
|
|
17
|
+
|
|
18
|
+
- `cli/package.json` — `bin: neo`, runtime deps are only `convex` and
|
|
19
|
+
`@inquirer/prompts`.
|
|
20
|
+
- `node cli/build.mjs` (also `prepublishOnly`) bundles `src/main.ts` into
|
|
21
|
+
`dist/neo.mjs` with esbuild: all shared monorepo code (`src/models`,
|
|
22
|
+
`src/database/neoscript`, the evaluator, `convex/_generated` references)
|
|
23
|
+
is compiled INTO the bundle, so the published artifact has no source
|
|
24
|
+
dependency on this repo. The build fails if the bundle imports any
|
|
25
|
+
package not declared as a dependency.
|
|
26
|
+
- `cli/dist/` is gitignored; publish with `cd cli && npm publish`.
|
|
27
|
+
|
|
28
|
+
## Interactive UX
|
|
29
|
+
|
|
30
|
+
In a terminal, missing arguments become prompts (`@inquirer/prompts`):
|
|
31
|
+
`neo init` walks project → branch/version → directory; `neo login` picks the
|
|
32
|
+
profile and opens the browser for the device code; `neo branch switch` /
|
|
33
|
+
`neo merge` offer pickers; `neo push` confirms (and offers bump acceptance on
|
|
34
|
+
rejection); `neo release cut` previews the derived floor before asking for
|
|
35
|
+
the bump; pull conflicts offer markers / mine-all / theirs-all. Every prompt
|
|
36
|
+
degrades in CI/pipes (no TTY, `CI`, or `NEO_NO_INTERACTIVE` set): commands
|
|
37
|
+
keep their flag-driven behavior, prompts that would block instead raise an
|
|
38
|
+
error naming the flag to pass, and output is plain (also `NO_COLOR`).
|
|
39
|
+
|
|
40
|
+
## Commands
|
|
41
|
+
|
|
42
|
+
| Command | Purpose |
|
|
43
|
+
| -------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
44
|
+
| `login` | Device-code OAuth (`neo-cli-editor` / `--profile release`); `--token-stdin` / `NEO_COMPOSE_TOKEN` for CI |
|
|
45
|
+
| `init --project <id> [--version <id>]` | Scaffold `neo/` (csproj, attributes, .gitignore) + first pull |
|
|
46
|
+
| `pull [--force]` | Sync from server; field-level three-way merge; conflict markers on overlap |
|
|
47
|
+
| `push [--dry-run] [--accept-bump]` | Atomic CAS transaction; assigns ids to creates; canonical rewrite |
|
|
48
|
+
| `status` / `diff` | Working-copy changes vs base |
|
|
49
|
+
| `dev [--push]` | Convex websocket sync-signal subscription + file watcher |
|
|
50
|
+
| `resolve --mine\|--theirs` | Conflict-marker sugar (editing the file is the real path) |
|
|
51
|
+
| `script check\|eval\|apply` | Compile/evaluate NeoScript with the web's own compiler/evaluator |
|
|
52
|
+
| `records` / `values` / `loc` | Content reads + writes with JSON-array batch stdin |
|
|
53
|
+
|
|
54
|
+
Working-copy layout and the C# subset are documented in
|
|
55
|
+
[`cli/skill/SKILL.md`](skill/SKILL.md) (the agent onboarding surface) and the
|
|
56
|
+
spec. State lives in `neo/.neo/state.json` (gitignored): per-record base
|
|
57
|
+
content hashes — the compare-and-swap tokens — plus conflict bookkeeping.
|
|
58
|
+
|
|
59
|
+
## Architecture notes
|
|
60
|
+
|
|
61
|
+
- **Convex-direct, fully typed**: the CLI calls Convex with `api.*`
|
|
62
|
+
references and inferred types (`cli/src/convex.ts`), authenticated by a
|
|
63
|
+
Convex JWT minted from the scoped device-flow session. Pushes go through
|
|
64
|
+
the session-gated `serverProjectRecordOperations.commitFromSession`
|
|
65
|
+
(same per-change scope gates + CAS as the web's S2S commit). HTTP is used
|
|
66
|
+
only for the auth plane and for content verbs that reuse Next-side write
|
|
67
|
+
services. Record payloads are narrowed with the same `src/models` guards
|
|
68
|
+
the web app uses.
|
|
69
|
+
|
|
70
|
+
- **Round-trip invariant**: `pull` → `push` is always a no-op. Enforced by
|
|
71
|
+
the consumption-model partition (`cli/src/schema/emit.ts`): every record
|
|
72
|
+
field is either expressed in C#, carried in `ExtraJson`, or held as a
|
|
73
|
+
volatile field in state and merged back at reconstruction.
|
|
74
|
+
- The parser (`cli/src/schema/parse.ts`) is a hand-rolled
|
|
75
|
+
recursive-descent parser for the constrained subset with
|
|
76
|
+
file:line:column diagnostics.
|
|
77
|
+
- Server surfaces: `schema/document` (read), `schema/transactions`
|
|
78
|
+
(atomic CAS write), `projectExportData.schemaSignal` (websocket signal).
|
|
79
|
+
- Tests: `npx vitest run cli` (round-trip corpus, parser, merge matrix).
|